summary refs log tree commit diff stats
path: root/day8.fsx
blob: 5a4f423c3626428ee96d9a428cfddabfc24e91cc (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
open System.IO
open System.Text.RegularExpressions
open System.Collections.Generic

let (|InstRegex|_|) input =
    let m = Regex.Match(input, "(\w+) (dec|inc) (-?\d+) if (\w+) (>|<|>=|<=|==|!=) (-?\d+)")
    if m.Success then
        let op = if m.Groups[2].Value = "dec" then (-) else (+)
        let comparator: int->int->bool = 
            match m.Groups[5].Value with
            | ">" -> (>)
            | "<" -> (<)
            | ">=" -> (>=)
            | "<=" -> (<=)
            | "==" -> (=)
            | "!=" -> (<>)
            | _ -> (fun x y -> false)
        Some((m.Groups[1].Value, op, int m.Groups[3].Value, m.Groups[4].Value, comparator, int m.Groups[6].Value))
    else None

type Instruction =
    struct
        val opReg: string
        val opFun: int -> int -> int
        val opVal: int
        val compReg: string
        val compFun: int -> int -> bool
        val compVal: int
        new(inst: string) =
            match inst with
            | InstRegex (target, operator, value, compared, comparator, compValue) ->
                {
                    opReg = target;
                    opFun = operator;
                    opVal = value;
                    compReg = compared;
                    compFun = comparator;
                    compVal = compValue
                }
            | _ -> {opReg = ""; opFun = (+); opVal = 0; compReg = ""; compFun = (>); compVal = 0}
    end

let registers = new Dictionary<string, int>()
let mutable maxValue = 0
let executeInstruction (inst: Instruction) =
    let mutable regVal = 0
    registers.TryGetValue(inst.compReg, &regVal) |> ignore
    if inst.compFun regVal inst.compVal then
        registers.TryGetValue(inst.opReg, &regVal) |> ignore
        registers[inst.opReg] <- inst.opFun regVal inst.opVal
        if registers[inst.opReg] > maxValue then
            maxValue <- registers[inst.opReg]
        else ()
    else ()

File.ReadAllLines "day8.txt" |> Array.map (fun x -> new Instruction(x)) |> Array.iter executeInstruction
// part 1
registers.Values |> Seq.max |> printfn "%A"
// part 2
printfn "%d" maxValue