-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathday23_part02.fs
67 lines (58 loc) · 2.53 KB
/
day23_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
66
67
module day23_part02
open AdventOfCode_Utilities
open AdventOfCode_2020.Modules
let findDestinationCup cupsToSearch currentCupValue =
let indexedCups = cupsToSearch |> List.indexed
match indexedCups |> List.filter (fun (_, c) -> c < currentCupValue) with
| [] -> indexedCups |> List.maxBy snd
| smallerValueCups -> smallerValueCups |> List.maxBy snd
let applyMove cups =
let currentCup = cups |> List.head
let cupsToMove = cups |> List.tail |> List.take 3
let remainingCups = cups |> List.skip 4
let destinationIndex, _ = findDestinationCup remainingCups currentCup
remainingCups.[..destinationIndex] @ cupsToMove @ remainingCups.[(destinationIndex+1)..] @ [currentCup]
let applyXMoves numberMoves cups =
List.init numberMoves id
|> List.fold (fun previousState _ -> applyMove previousState) cups
let findNextInsertionPoint cup removedCups =
let rec decreaseBy1 previousValue =
let target = (positiveModulo (previousValue - 2) 1000000) + 1
if removedCups |> List.contains target then
decreaseBy1 target
else
target
decreaseBy1 cup
let applyMoveToMap currentCup cups =
let firstCup = cups |> Map.find currentCup
let secondCup = cups |> Map.find firstCup
let thirdCup = cups |> Map.find secondCup
let endOfRemovedCups = cups |> Map.find thirdCup
let insertionPoint = findNextInsertionPoint currentCup [firstCup; secondCup; thirdCup]
(
endOfRemovedCups,
cups
|> Map.add currentCup endOfRemovedCups // close the gap
|> Map.add insertionPoint firstCup // start of new position
|> Map.add thirdCup (cups |> Map.find insertionPoint) // end of new position
)
let applyXMovesToMap numberMoves startCup cups =
List.init numberMoves id
|> List.fold (fun (nextCup, previousCups) _ -> applyMoveToMap nextCup previousCups) (startCup, cups)
|> snd
let multiplyLabels numbers =
let allCups =
(numbers |> List.pairwise)
@ [(List.last numbers, 10)]
@ (List.init 1000000 (fun i -> (i, i+1)) |> List.skip 10)
@ [(1000000, List.head numbers)]
|> Map.ofList
|> applyXMovesToMap 10000000 (List.head numbers)
let firstStarCup = allCups |> Map.find 1
let secondStarCup = allCups |> Map.find firstStarCup
(int64 firstStarCup) * (int64 secondStarCup)
let execute =
let path = "day23/day23_input.txt"
let content = LocalHelper.GetContentFromFile path
let numbers = content.ToCharArray() |> Array.map (string >> int) |> List.ofArray
multiplyLabels numbers