/
Day25_Part1_Part2.fsx
74 lines (64 loc) · 1.87 KB
/
Day25_Part1_Part2.fsx
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
67
68
69
70
71
72
73
74
#time
open System
open System.Collections.Generic
open System.IO
let inputs = File.ReadAllLines (__SOURCE_DIRECTORY__ + "/Day25Input.txt")
type Operant =
| Value of int
| Reg of string
type Instruction =
| Cpy of n: Operant * dest: Operant
| Inc of string
| Dec of string
| Jnz of n: Operant * offset: Operant
| Out of n: Operant
let (|Operant|) x =
match Int32.TryParse x with
| true, n -> Value n
| _ -> Reg x
let instructions =
inputs
|> Array.map (fun l -> l.Split())
|> Array.map (function
| [| "cpy"; Operant n; Operant dest |] -> Cpy (n, dest)
| [| "inc"; reg |] -> Inc reg
| [| "dec"; reg |] -> Dec reg
| [| "jnz"; Operant n; Operant offset |] -> Jnz (n, offset)
| [| "out"; Operant n |] -> Out n)
let execute initValues (instructions : Instruction[]) =
let registers = new Dictionary<string, int>()
initValues |> Seq.iter (fun (key, value) -> registers.[key] <- value)
let fetch = function
| Value n -> n
| Reg reg ->
match registers.TryGetValue reg with
| true, n -> n
| _ -> 0
seq {
let mutable idx = 0
while idx < instructions.Length do
match instructions.[idx] with
| Cpy (n, Reg dest) ->
registers.[dest] <- fetch n
idx <- idx + 1
| Inc reg ->
registers.[reg] <- registers.[reg] + 1
idx <- idx + 1
| Dec reg ->
registers.[reg] <- registers.[reg] - 1
idx <- idx + 1
| Jnz (n, offset) when fetch n <> 0 ->
idx <- idx + fetch offset
| Out n ->
yield fetch n
idx <- idx + 1
| _ ->
idx <- idx + 1
}
let part1 =
Seq.initInfinite id
|> Seq.find (fun n ->
execute [ "a", n ] instructions
|> Seq.take 1000
|> Seq.chunkBySize 2
|> Seq.forall (fun [| a; b |] -> a = 0 && b = 1))