-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathTwo.re
89 lines (71 loc) · 2.16 KB
/
Two.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
module CharMap = Map.Make(Char);
type boxId = string;
type boxIdCombo = (boxId, boxId);
let inputLines = () =>
Node.Fs.readFileAsUtf8Sync("resources/two.txt")
|> Js.String.split("\n")
|> Array.to_list;
let stringAsCollection = (s: string): array(char) =>
Array.init(String.length(s), String.get(s));
let characterHistogram = (chars: array(char)) =>
Array.fold_left(
(map, aChar) =>
switch (CharMap.find(aChar, map)) {
| item => CharMap.add(aChar, item + 1, map)
| exception Not_found => CharMap.add(aChar, 1, map)
},
CharMap.empty,
chars,
);
let hasValue = (value: 'a, map: CharMap.t('a)): bool =>
CharMap.exists((_, binding) => binding == value, map);
let boxIdHistogram = (boxId: boxId) =>
boxId |> stringAsCollection |> characterHistogram;
let checksum = (boxIds: list(boxId)): int => {
let histograms = List.map(boxIdHistogram, boxIds);
let numberOfTwos =
List.fold_left(
(total, histogram) => hasValue(2, histogram) ? total + 1 : total,
0,
histograms,
);
let numberOfThrees =
List.fold_left(
(total, histogram) => hasValue(3, histogram) ? total + 1 : total,
0,
histograms,
);
numberOfThrees * numberOfTwos;
};
let positionalEqualities = (combo: boxIdCombo) => {
let (boxIdA, boxIdB) = combo;
Array.mapi(
(index, char) => boxIdB.[index] == char,
stringAsCollection(boxIdA),
);
};
let offByOne = (combo: boxIdCombo) =>
1
== Array.fold_left(
(inequalities, isEqual) => isEqual ? inequalities : inequalities + 1,
0,
positionalEqualities(combo),
);
let allCombinationsOfTwo = (boxIds: list(boxId)): list(boxIdCombo) =>
List.map(
boxId => List.map(otherBoxId => (boxId, otherBoxId), boxIds),
boxIds,
)
|> List.flatten;
let commonLetters = (combo: boxIdCombo) => {
let (boxIdA, boxIdB) = combo;
stringAsCollection(boxIdA)
|> Array.mapi((index, char) =>
boxIdB.[index] == char ? String.make(1, char) : ""
)
|> Array.to_list
|> String.concat("");
};
let firstSolution = () => inputLines() |> checksum;
let secondSolution = () =>
inputLines() |> allCombinationsOfTwo |> List.find(offByOne) |> commonLetters;