-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy path14.fsx
73 lines (63 loc) · 1.88 KB
/
14.fsx
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
72
73
let input =
"inputs/14.txt"
|> System.IO.File.ReadAllLines
|> Array.map (fun s -> s.ToCharArray())
let tilt col =
let mutable l = []
let mutable i = []
for c in col do
if c = 'O' then
l <- c :: l
else if c = '.' then
i <- c :: i
else
l <- c :: i @ l
i <- []
l <- i @ l
l |> List.rev |> Array.ofList
let load =
Array.map (fun row -> row |> Array.sumBy (fun c -> if c = 'O' then 1 else 0))
>> Array.mapi (fun i c -> (input[0].Length - i) * c)
>> Array.sum
input
|> Array.transpose
|> Array.map tilt
|> Array.transpose
|> Array.map (fun row -> row |> Array.sumBy (fun c -> if c = 'O' then 1 else 0))
|> Array.mapi (fun i c -> (input[0].Length - i) * c)
|> Array.sum
|> printfn "part1: %d"
let cycle a =
a
|> Array.transpose // facing north
|> Array.map tilt
|> Array.transpose // facing west (reset)
|> Array.map tilt
|> Array.transpose
|> Array.map Array.rev // facing south
|> Array.map tilt
|> Array.map Array.rev
|> Array.transpose // facing west (reset)
|> Array.map Array.rev // facing east
|> Array.map tilt
|> Array.map Array.rev // facing west (reset)
let findLoop target input =
let d = System.Collections.Generic.Dictionary<string, int * int>()
let mutable last = input
Seq.initInfinite id
|> Seq.pick (fun i ->
last <- cycle last
let key = last |> Array.collect id |> Array.map string |> String.concat ""
if d.ContainsKey key then
// found loop. it starts at `offset` and repeats every `nth`.
let offset = fst (d[key])
let nth = i - fst (d[key])
// the value at the target iteration is
// offset + the modulo of the repeating loop
// minus 1 because of 0 indexing
let pos = offset + (target - offset) % nth - 1
d.Values |> Seq.item pos |> snd |> Some
else
d[key] <- i, (load last)
None)
findLoop 1_000_000_000 input |> printfn "part2: %d"