-
Notifications
You must be signed in to change notification settings - Fork 10
/
Day14.fs
71 lines (56 loc) · 2.34 KB
/
Day14.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 Year2015Day14
open AdventOfCode.FSharp.Common
type Reindeer = { Name : string; Speed : int; Seconds : int; Rest : int }
let parseReindeer r =
let toks = splitBy " " id r
{ Name = toks.[0]; Speed = int toks.[3]; Seconds = int toks.[6]; Rest = int toks.[13] }
let parse = parseEachLine parseReindeer
let solvePart1 input =
let reindeer = input |> Seq.map (fun r -> r.Name, r ) |> Map.ofSeq
let initStates = reindeer |> Map.map (fun r d -> (0, true, d.Seconds))
let step states =
states
|> Map.map (fun r (dist, isGoing, t) ->
let reinData = reindeer.[r]
let newDist =
if isGoing then dist + reinData.Speed
else dist
let newIsGoing = if t = 1 then not isGoing else isGoing
let newT = if t = 1 then (if newIsGoing then reinData.Seconds else reinData.Rest) else t - 1
(newDist, newIsGoing, newT))
let rec simulateN n state =
if n = 0 then state
else step state |> simulateN (n - 1)
simulateN 2503 initStates
|> Map.toSeq
|> Seq.map (fun (_, (d, _, _)) -> d)
|> Seq.max
let solvePart2 input =
let reindeer = input |> Seq.map (fun r -> r.Name, r ) |> Map.ofSeq
let initStates = reindeer |> Map.map (fun r d -> (0, true, d.Seconds, 0))
let step states =
let newStates =
states
|> Map.map (fun r (dist, isGoing, t, score) ->
let reinData = reindeer.[r]
let newDist =
if isGoing then dist + reinData.Speed
else dist
let newIsGoing = if t = 1 then not isGoing else isGoing
let newT = if t = 1 then (if newIsGoing then reinData.Seconds else reinData.Rest) else t - 1
(newDist, newIsGoing, newT, score))
let bestDist =
newStates
|> Map.toSeq
|> Seq.map (fun (_, (d, _, _, _)) -> d)
|> Seq.max
newStates
|> Map.map (fun r (a, b, c, d) -> (a, b, c, if a = bestDist then d + 1 else d))
let rec simulateN n state =
if n = 0 then state
else step state |> simulateN (n - 1)
simulateN 2503 initStates
|> Map.toSeq
|> Seq.map (fun (_, (d, _, _, s)) -> s)
|> Seq.max
let solver = { parse = parse; part1 = solvePart1; part2 = solvePart2 }