This repository has been archived by the owner on Nov 22, 2024. It is now read-only.
generated from mazharenko/aoc-agent-template
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathday15.fs
65 lines (55 loc) · 1.9 KB
/
day15.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 impl.day15
open Farkle
open Farkle.Builder
open Farkle.Builder.Regex
let hash s =
s
|> Seq.fold (fun acc c ->
(int c + acc) * 17 % 256
) 0
module Part1 =
let parse (input : string) =
input.Trim().Split(',')
let solve (input : string[]) =
input
|> Seq.sumBy hash
module Part2 =
type Lens = string * int
type Operation = | Add of Lens | Remove of string
let private number = Terminals.int "Number"
let private label =
chars PredefinedSets.AllLetters |> atLeast 1
|> terminal "Label" (T(fun _ chars -> new string(chars)))
let private operation = "Operation" ||= [
!@ label .>> "=" .>>. number => fun l length -> Add(l, length)
!@ label .>> "-" => Remove
]
let parse (input : string) =
let parser = RuntimeFarkle.build operation
input.Split(',')
|> Array.map (RuntimeFarkle.parseUnsafe parser)
let execute map op =
match op with
| Remove label ->
Map.change (hash label) (Option.map (Array.where (fst >> (<>)label))) map
| Add (label, length) ->
Map.change (hash label) (
function
| None -> Some [| label, length |]
| Some box ->
(
Array.map (fun x -> if fst x = label then label, length else x) box,
[| label, length |]
)
||> Array.append
|> Array.distinctBy fst
|> Some
) map
let solve (input : Operation[]) =
let map = Map.empty
input
|> Array.fold execute map
|> Map.toSeq
|> Seq.collect (fun (box, lists) -> lists |> Seq.mapi (fun i x -> box, i+1, snd x) )
|> Seq.map (fun (box, slot, length) -> (box + 1) * slot * length)
|> Seq.sum