-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.fs
71 lines (58 loc) · 2.03 KB
/
main.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
open System;
open System.Numerics;
let rec parseNodeMap (networkLines: string[]) (nodeMap: Map<string, (string * string)>) : Map<string, (string * string)> =
if networkLines.Length = 0 then
nodeMap
else
let currentLine = networkLines.[0]
let keyAndRest = currentLine.Split('=')
let key = keyAndRest.[0].Trim()
let leftAndRight = keyAndRest.[1].Split(',')
let left = leftAndRight.[0].Trim().[1..];
let rightPart = leftAndRight.[1].Trim();
let right = rightPart.[0..(rightPart.Length - 2)];
let newMap = nodeMap.Add(key, (left, right))
let nodeMap = parseNodeMap networkLines.[1..] newMap
nodeMap
let rec followNetwork (currentKey: string) (directions: string) (nodeMap: Map<string, (string * string)>) (count: int): int =
if currentKey.EndsWith("Z") then
count
else
let direction = directions.[count % directions.Length]
let nextKey =
if direction = 'L' then
fst nodeMap.[currentKey]
else
snd nodeMap.[currentKey]
followNetwork nextKey directions nodeMap (count + 1)
let lcm a b =
let gcd = BigInteger.GreatestCommonDivisor(a, b)
(BigInteger.Abs(a * b)) / gcd
// SCM of a list of numbers
let rec scm numbers: BigInteger =
match numbers with
| [] -> 1
| [x] -> x
| x :: xs -> lcm x (scm xs)
let solve (directions: string) (nodeMap: Map<string, (string * string)>) =
let totalSteps = followNetwork "AAA" directions nodeMap 0
printfn "%i" totalSteps
let solve2 (directions: string) (nodeMap: Map<string, (string * string)>) =
let startKeys =
nodeMap
|> Map.keys
|> Seq.filter (fun key -> key.EndsWith("A"))
|> Seq.toArray
let totals =
startKeys
|> Array.map (fun key -> BigInteger(followNetwork key directions nodeMap 0))
let lcmValue = scm (Seq.toList totals)
printfn "%A" lcmValue
[<EntryPoint>]
let main argv =
let lines = System.IO.File.ReadAllLines("input")
let directions = lines.[0]
let nodeMap = parseNodeMap lines.[2..] Map[]
solve directions nodeMap
solve2 directions nodeMap
0