-
Notifications
You must be signed in to change notification settings - Fork 10
/
Day07.fs
35 lines (27 loc) · 1.31 KB
/
Day07.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
module Year2017Day07
open AdventOfCode.FSharp.Common
let getSubTowers (tokens : string array) = if Array.length tokens = 2 then Array.empty else tokens.[3..] |> Array.map (fun c -> c.TrimEnd(','))
let asProgram = splitBy " " (fun tokens -> (tokens.[0], (tokens.[1].Trim('(',')') |> int, getSubTowers tokens)))
let rec findRoot tower currentProgram =
match Map.tryFindKey (fun _ (_, children) -> Array.contains currentProgram children) tower with
| None -> currentProgram
| Some parent -> findRoot tower parent
let rec getWeight tower node =
let weight, children = Map.find node tower
weight + (Array.sumBy (getWeight tower) children)
let getChildrenWeights tower =
Seq.map (fun c -> (getWeight tower c, Map.find c tower |> fst))
>> Seq.groupBy fst
>> Seq.sortByDescending (fun (k, g) -> Seq.length g)
>> Seq.toArray
let getMissingWeight tower =
tower
|> Map.map (fun _ (_, children) -> getChildrenWeights tower children)
|> Map.toSeq
|> Seq.filter (fun (_, v) -> (Array.length v) = 2)
|> Seq.map (fun (_, v) -> (snd v.[1] |> Seq.head |> snd) + (fst v.[0]) - (fst v.[1]))
|> Seq.min
let part1 tower =
let head = Seq.head tower
findRoot tower head.Key
let solver = {parse = parseEachLine asProgram >> Map.ofSeq; part1 = part1; part2 = getMissingWeight}