-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathday08_part01.fs
108 lines (97 loc) · 4.07 KB
/
day08_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
module day08_part01
open AdventOfCode_2017.Modules
type Comparison =
| Greater
| Lesser
| Equal
| NotEqual
| EqualOrGreater
| EquealOrLesser
type SelectorType = {
Element: string;
Operation: Comparison
ToCompare: int
}
type Op =
| Inc
| Dec
type Instruction = {
Target: string;
Value: int;
Operation: Op;
Selector: SelectorType;
}
let parseLines (lines: string array) : (Instruction list*(string*int) list) =
let mutable registries = Set.empty<(string*int)>
let parseLine (l: string) =
let parts = l.Split(" ")
let target = parts[0]
let opValue = (int)parts[2]
let sel = parts[4]
let comp = parts[5]
let toComp = (int)parts[6]
let op = if parts[1] = "inc" then Inc else Dec
let selector =
match comp with
| ">" -> { Element = sel; Operation = Greater; ToCompare = toComp }
| "<" -> { Element = sel; Operation = Lesser; ToCompare = toComp }
| "==" -> { Element = sel; Operation = Equal; ToCompare = toComp }
| "!=" -> { Element = sel; Operation = NotEqual; ToCompare = toComp }
| ">=" -> { Element = sel; Operation = EqualOrGreater; ToCompare = toComp }
| "<=" -> { Element = sel; Operation = EquealOrLesser; ToCompare = toComp }
| _ -> failwith "operation not found"
registries <- registries.Add((target, 0)).Add(sel, 0)
{ Target = target; Value = opValue; Operation = op; Selector = selector }
(List.ofArray (lines |> Array.map parseLine), registries |> Set.toList)
let executeOp op v1 v2 =
match op with
| Inc -> v1 + v2
| Dec -> v1 - v2
let rec runInstructions (instructions: Instruction list) (registry: (string*int) list) =
match instructions with
| [] -> registry
| instruction :: rest ->
let comparer = registry |> List.find(fun (r, v) -> r = instruction.Selector.Element)
let tmpresult = registry |> List.find (fun (r, v) -> r = instruction.Target)
let newResult =
(fst tmpresult,
match instruction.Selector.Operation with
| Greater ->
if (snd comparer) > instruction.Selector.ToCompare then
executeOp instruction.Operation (snd tmpresult) instruction.Value
else
snd tmpresult
| Lesser ->
if (snd comparer) < instruction.Selector.ToCompare then
executeOp instruction.Operation (snd tmpresult) instruction.Value
else
snd tmpresult
| Equal ->
if (snd comparer) = instruction.Selector.ToCompare then
executeOp instruction.Operation (snd tmpresult) instruction.Value
else
snd tmpresult
| NotEqual ->
if (snd comparer) <> instruction.Selector.ToCompare then
executeOp instruction.Operation (snd tmpresult) instruction.Value
else
snd tmpresult
| EqualOrGreater ->
if (snd comparer) >= instruction.Selector.ToCompare then
executeOp instruction.Operation (snd tmpresult) instruction.Value
else
snd tmpresult
| EquealOrLesser ->
if (snd comparer) <= instruction.Selector.ToCompare then
executeOp instruction.Operation (snd tmpresult) instruction.Value
else
snd tmpresult
)
runInstructions rest (newResult :: List.except ([tmpresult]) registry)
let execute() =
//let path = "day08/test_input_01.txt"
let path = "day08/day08_input.txt"
let lines = LocalHelper.GetLinesFromFile path
let (instructions, initialvalues) = parseLines lines
let result = runInstructions instructions initialvalues
result |> List.sortByDescending snd |> List.map snd |> List.head