summary refs log tree commit diff stats
path: root/day12.fsx
blob: 17bcc6b360d106e2d62ec34282050b1abe485c64 (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
61
62
63
64
65
66
open System.IO

type Reg = string
type Lit = int
type Value =
    | LiteralVal of literal: Lit
    | Register of register: Reg

type Instruction =
    | Cpy of copied: Value * register: Reg
    | Inc of register: Reg
    | Dec of register: Reg
    | Jnz of compared: Value * offset: Lit

let parseInstruction (line:string): Instruction =
    let split = line.Split " "
    match split[0] with
    | "inc" -> Inc split[1]
    | "dec" -> Dec split[1]
    | "cpy" ->
        let mutable parsed = 0
        if (System.Int32.TryParse(split[1], &parsed))
        then Cpy (LiteralVal parsed, split[2])
        else Cpy (Register split[1], split[2])
    | "jnz" -> 
        let mutable parsed = 0
        if (System.Int32.TryParse(split[1], &parsed))
        then Jnz (LiteralVal parsed, (int split[2]))
        else Jnz (Register split[1], (int split[2]))
    | _ -> Inc ""

let rec execute index insts registers =
    if index < 0 || index > (Array.length insts) - 1
    then 
        Map.find "a" registers
    else
        match insts[index] with
        | Cpy (value, reg) -> 
            let copied =
                match value with
                | LiteralVal num -> num
                | Register reg -> Map.find reg registers
            let newRegisters = Map.change reg (function | Some x -> Some copied | None -> None) registers
            execute (index + 1) insts newRegisters
        | Inc reg ->
            let newRegisters = Map.change reg (function | Some x -> Some (x + 1) | None -> None) registers
            execute (index + 1) insts newRegisters
        | Dec reg ->
            let newRegisters = Map.change reg (function | Some x -> Some (x - 1) | None -> None) registers
            execute (index + 1) insts newRegisters
        | Jnz (reg, offset) ->
            let compared =
                match reg with
                | LiteralVal num -> num
                | Register reg -> Map.find reg registers
            if compared <> 0
            then 
                execute (index + offset) insts registers
            else
                execute (index + 1) insts registers
    
let lines = File.ReadAllLines "day12.txt" |> Array.map parseInstruction
let regsPart1: Map<string, Lit> = Map.ofList [("a", 0); ("b", 0); ("c", 0); ("d", 0)]
execute 0 lines regsPart1 |> printfn "%d"
let regsPart2: Map<string, Lit> = Map.ofList [("a", 0); ("b", 0); ("c", 1); ("d", 0)]
execute 0 lines regsPart2 |> printfn "%d"