-
Notifications
You must be signed in to change notification settings - Fork 10
/
Day13.fs
71 lines (56 loc) · 2.18 KB
/
Day13.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
module Year2015Day13
open AdventOfCode.FSharp.Common
open GraphFS.Graph
type Action = { Person : string; IsGain : bool; Units : int; NextTo : string }
let asAction line =
let toks = splitBy " " id line
{ Person = toks.[0]; IsGain = toks.[2] = "gain"; Units = int toks.[3]; NextTo = toks.[10].Trim('.')}
let parse = parseEachLine asAction
let solvePart1 input =
let G =
input
|> Seq.map (fun a -> (a.Person, a.NextTo), if a.IsGain then a.Units else -a.Units)
|> Graph.fromEdgesWithData
let people = Graph.verts G |> Set.ofSeq
let rec findBestOrder first recent remaining =
if Set.isEmpty remaining then
let h1 = Graph.getEdgeData (recent, first) G
let h2 = Graph.getEdgeData (first, recent) G
h1 + h2
else
remaining
|> Seq.map (fun p ->
let h1 = Graph.getEdgeData (recent, p) G
let h2 = Graph.getEdgeData (p, recent) G
let h3 = findBestOrder first p (Set.remove p remaining)
h1 + h2 + h3)
|> Seq.max
people
|> Seq.map (fun p -> findBestOrder p p (Set.remove p people))
|> Seq.max
let solvePart2 input =
let G =
input
|> Seq.map (fun a -> (a.Person, a.NextTo), if a.IsGain then a.Units else -a.Units)
|> Graph.fromEdgesWithData
let people = Graph.verts G |> Set.ofSeq
let edgesToAdd =
people
|> Seq.map (fun p -> [(p, "ME"), 0; ("ME", p), 0])
|> Seq.collect id
let G = Graph.addEdgesWithData edgesToAdd G
let rec findBestOrder first recent remaining =
if Set.isEmpty remaining then
let h1 = Graph.getEdgeData (recent, first) G
let h2 = Graph.getEdgeData (first, recent) G
h1 + h2
else
remaining
|> Seq.map (fun p ->
let h1 = Graph.getEdgeData (recent, p) G
let h2 = Graph.getEdgeData (p, recent) G
let h3 = findBestOrder first p (Set.remove p remaining)
h1 + h2 + h3)
|> Seq.max
findBestOrder "ME" "ME" people
let solver = { parse = parse; part1 = solvePart1; part2 = solvePart2 }