-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathDay6.re
98 lines (84 loc) · 2.43 KB
/
Day6.re
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
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
open Tablecloth;
module Orbit = {
let make = value =>
switch (value |> String.split(~on=")")) {
| [a, b] => (a, b)
| _ => ("", "")
};
};
module PartOne = {
module WalkTree = {
let rec make = (key, map) =>
switch (map |> StrDict.get(~key)) {
| Some(deps) =>
deps |> List.foldl(~init=0, ~f=(c, acc) => {acc + make(c, map) + 1})
| None => 0
};
};
let make = input => {
let out =
input
|> List.foldl(
~init=StrDict.empty,
~f=(curr, acc) => {
let (key, target) = Orbit.make(curr);
switch (acc |> StrDict.get(~key)) {
| Some(v) => acc |> StrDict.insert(~key, ~value=[target, ...v])
| None => acc |> StrDict.insert(~key, ~value=[target])
};
},
);
out
|> StrDict.toList
|> List.foldl(~init=0, ~f=((id, _), acc) => {
acc + WalkTree.make(id, out)
});
};
};
module PartTwo = {
module FindPath = {
let rec make = (planet: string, orbits, ~previous=[], ()) => {
switch (orbits |> StrDict.get(~key=planet)) {
| Some(orbit) =>
make(orbit, orbits, ~previous=[planet, ...previous], ())
| None => previous
};
};
};
module FindDistance = {
let rec make = (paths, ~steps=0, ~index=0, ()) => {
let (you, santa) = paths;
switch (steps) {
| x when x !== 0 => steps
| _ =>
switch (you |> List.getAt(~index), santa |> List.getAt(~index)) {
| (Some(x), Some(y)) when x === y =>
make(paths, ~steps, ~index=index + 1, ())
| _ =>
// -2 because we want them to orbit the same planet
// Somehow I need to add 1 to index because this part "lags behind"
// Response in here is the last matching values
let index = index + 1;
let steps =
List.length(santa) - index + (List.length(you) - index) - 2;
make(paths, ~steps, ~index, ());
}
};
};
};
let make = input => {
let map = StrDict.empty;
let orbits =
input
|> List.foldl(
~init=map,
~f=(orbit, acc) => {
let (value, key) = Orbit.make(orbit);
acc |> StrDict.insert(~key, ~value);
},
);
let pathToYou = FindPath.make("YOU", orbits, ());
let pathToSanta = FindPath.make("SAN", orbits, ());
FindDistance.make((pathToYou, pathToSanta), ());
};
};