Last active
December 27, 2020 12:25
-
-
Save Karamell/f065f30bf2dbf7ab3dcd97eae91857b3 to your computer and use it in GitHub Desktop.
Advent of Code 2020 day 23
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #time "on" | |
| module Cup = | |
| let build (inp:string) count = | |
| let input = inp |> Seq.map (string >> int) |> Seq.toList | |
| let first = input |> List.head | |
| let arr0 = | |
| let a0 = Array.init(input.Length + 1) (fun _ -> 0) | |
| input |> List.pairwise |> List.iter(fun (a, b) -> a0.[a] <- b) | |
| a0 | |
| let last0 = input |> List.last | |
| let arr = | |
| if count = 9 then | |
| arr0.[last0] <- first | |
| arr0 | |
| else | |
| let arr1 = Array.init (count - 9) (fun i -> 11 + i) | |
| arr0.[last0] <- 10 | |
| arr1.[count - 10] <- first | |
| Array.append arr0 arr1 | |
| first, arr | |
| let rec toSeq n arr = | |
| seq { | |
| yield n | |
| yield! toSeq (Array.item n arr) arr | |
| } | |
| let moves input ccount mcount = | |
| let first, arr = Cup.build input ccount | |
| let inline getDestination c c1 c2 c3 = | |
| let inline minus n = if n = 1 then ccount else n - 1 | |
| let d = minus c | |
| let d' = if c1 = d || c2 = d || c3 = d then minus d else d | |
| let d'' = if c1 = d' || c2 = d' || c3 = d' then minus d' else d' | |
| if c1 = d'' || c2 = d'' || c3 = d'' then minus d'' else d'' | |
| let rec move m c = | |
| let m' = m + 1 | |
| // -- pick -- | |
| let c1 = arr.[c] | |
| let c2 = arr.[c1] | |
| let c3 = arr.[c2] | |
| let c4 = arr.[c3] | |
| arr.[c] <- c4 | |
| // ---------- | |
| let destination = getDestination c c1 c2 c3 | |
| // -- insert -- | |
| let dnext = arr.[destination] | |
| arr.[destination] <- c1 | |
| arr.[c3] <- dnext | |
| // ---------- | |
| if mcount = m then | |
| arr | |
| else | |
| move m' arr.[c] | |
| move 1 first | |
| let input = "653427918" | |
| let c1 = moves input 9 100 | |
| c1 | |
| |> Cup.toSeq 1 |> Seq.tail |> Seq.takeWhile ((<>) 1) |> Seq.map string | |
| |> fun c -> System.String.Join("", c) | |
| |> printfn "part 1: %s" | |
| let c2 = moves input 1_000_000 10_000_000 | |
| let [aft1; aft2] = c2 |> Cup.toSeq 1 |> Seq.tail |> Seq.take 2 |> Seq.toList | |
| (int64 aft1) * (int64 aft2) |> printfn "part 2: %d" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment