-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathday23_part01.fs
110 lines (101 loc) · 3.92 KB
/
day23_part01.fs
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
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
module day23_part01
open AdventOfCode_2016.Modules
type operation =
| Copy of value: int * registry: string
| CopyReg of fromreg: string * toreg: string
| Inc of registry: string
| Dec of registry: string
| Jump of value: int * steps: int
| JumpReg of checker: string * steps: int
| JumpIReg of checker: int * steps: string
| JumpRegReg of checker: string * steps: string
| Toggle of registry: string
| None
let parseContent (lines: string array) =
let buildop (line: string) =
let parts = line.Split(" ")
match parts[0] with
| "cpy" ->
match System.Int32.TryParse parts[1] with
| true, v ->
Copy(v, parts[2])
| false, _ ->
CopyReg(parts[1], parts[2])
| "inc" -> Inc(parts[1])
| "dec" -> Dec(parts[1])
| "jnz" ->
match System.Int32.TryParse parts[1] with
| true, v ->
match System.Int32.TryParse parts[2] with
| true, v' ->
Jump(v, v')
| false, _ ->
JumpIReg(v, parts[2])
| false, _ ->
JumpReg(parts[1], (int)parts[2])
| "tgl" -> Toggle(parts[1])
| _ -> failwith "op error!"
lines |> Array.map buildop
let rec runOp (ops: operation array) (p': int) (values: Map<string, int>)=
let performOp (op: operation) (values: Map<string, int>) pointer=
match op with
| Copy(value, registry) ->
(pointer + 1, Map.add registry value values)
| CopyReg(fromreg, toreg) ->
(pointer + 1, Map.add toreg values[fromreg] values)
| Inc(registry) ->
(pointer + 1, Map.add registry (values[registry] + 1) values)
| Dec(registry) ->
(pointer + 1, Map.add registry (values[registry] - 1) values)
| Jump(checker, steps) ->
if checker <> 0 then
(pointer + steps, values)
else
(pointer + 1, values)
| JumpIReg(checker, steps) ->
if checker <> 0 then
(pointer + values[steps], values)
else
(pointer + 1, values)
| JumpReg(checker, steps) ->
if values[checker] <> 0 then
(pointer + steps, values)
else
(pointer + 1, values)
| JumpRegReg(checker, steps) ->
if values[checker] <> 0 then
(pointer + values[steps], values)
else
(pointer + 1, values)
| Toggle(registry) ->
let index = values[registry] + pointer
if index < ops.Length then
let opToSwitch = ops[index]
let newop =
match opToSwitch with
| Copy(v, r) -> JumpIReg(v, r) // two arguments
| CopyReg(r1, r2) -> JumpRegReg(r1, r2) // two arguments
| Inc(r) -> Dec(r) // One argument
| Dec(r) -> Inc(r) // One Argument
| Jump(v, s) -> None // Two argument
| JumpReg(c, s) -> None // Two argument
| JumpIReg(c, s) -> Copy(c, s) // Two argument
| JumpRegReg(r1, r2) -> CopyReg(r1, r2) // Two argument
| Toggle(r) -> Inc(r) // One Argument
| None -> None
ops[index] <- newop
(pointer + 1, values)
| None ->
(pointer + 1, values)
match ops.Length <= p' with
| true -> values
| false ->
let (newpointer, newvalues) = performOp ops[p'] values p'
runOp ops newpointer newvalues
let execute =
let path = "day23/day23_input.txt"
let content = LocalHelper.GetLinesFromFile path
let operations = parseContent content
let registries = Map[("a", 7); ("b", 0); ("c", 0); ("d", 0)]
let result = runOp operations 0 registries
result["a"]