-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathday15_part02.fs
65 lines (55 loc) · 2.07 KB
/
day15_part02.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
module day15_part02
open System.Text.RegularExpressions
open AdventOfCode_2023.Modules
type op = {
label: char array
op: char
focalLength: int option
}
type box = {
id: int
content: op list
}
let calculateHash (input: char array) =
let calcHash (acc: int) (input: char) =
(acc + (int input)) * 17 % 256
Array.fold calcHash 0 input
let getOp (input: string) =
let parts = Regex.Match(input, @"([a-zA-Z]+)([-=])(\d+)?")
{
label = parts.Groups.[1].Value.ToCharArray()
op = parts.Groups.[2].Value.[0]
focalLength = if parts.Groups.[3].Value.Length > 0 then Some(int parts.Groups.[3].Value) else None
}
let rec runOp (remainingOps: op list) (boxes: box array)=
match remainingOps with
| currentOp :: tail ->
let hashOfLabel = calculateHash currentOp.label
let box = boxes.[hashOfLabel]
let newContent =
if currentOp.op = '-' then
box.content |> List.filter(fun c -> c.label <> currentOp.label)
else
if box.content |> List.exists(fun c -> c.label = currentOp.label) then
box.content
|> List.map(fun c ->
if c.label = currentOp.label then
{ c with focalLength = currentOp.focalLength }
else
c
)
else
box.content @ [currentOp]
boxes.[hashOfLabel] <- { id = hashOfLabel; content = newContent }
runOp tail boxes
| [] -> boxes
let calculateFocusingPower (box: box) =
box.content |> List.mapi (fun idx op -> (box.id + 1) * (idx + 1) * op.focalLength.Value) |> List.sum
let execute =
let path = "day15/day15_input.txt"
let lines = LocalHelper.GetContentFromFile path
let allops = lines.Split(',') |> Array.map getOp |> Array.toList
let boxes = Array.create 256 {id = 0; content = []}
let result = runOp allops boxes
let focusingPowers = result |> Array.map calculateFocusingPower
focusingPowers |> Array.sum