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"
|