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
|
let
pkgs = import <nixpkgs> { };
input = builtins.readFile ./input;
mulRe = ''(mul\([[:digit:]]{1,3},[[:digit:]]{1,3}\))'';
mulMatch = mulInput: builtins.split mulRe mulInput;
mulMatches = mulMatch input;
onlyLists = list: builtins.filter (i: builtins.isList i) list;
muls = onlyLists mulMatches;
pairs =
list:
builtins.map (
m:
let
re = ''mul\(([[:digit:]]{1,3}),([[:digit:]]{1,3})\)'';
str = builtins.match re (builtins.elemAt m 0);
in
builtins.map (s: pkgs.lib.toInt s) str
) list;
mulPairs = pairs muls;
sumPairs =
pairs:
builtins.foldl' (
sum: pair:
let
left = builtins.elemAt pair 0;
right = builtins.elemAt pair 1;
in
sum + (left * right)
) 0 pairs;
part1 = sumPairs mulPairs;
cursedInput = builtins.replaceStrings [ "don't" ] [ "Z" ] input;
firstDoRe = ''^([^d]+)Z\(\)'';
firstDoReMatches = builtins.split firstDoRe cursedInput;
doRe = ''do\(\)([^Z]+)Z\(\)'';
doReMatches = builtins.split doRe cursedInput;
doMuls =
matches:
let
subInputs = builtins.map (l: builtins.elemAt l 0) (onlyLists matches);
subMatches = builtins.map (si: mulMatch si) subInputs;
subMuls = builtins.map (sm: onlyLists sm) subMatches;
subPairs = builtins.map (sm: pairs sm) subMuls;
subSums = builtins.map (sp: sumPairs sp) subPairs;
in
builtins.foldl' (sum: ss: sum + ss) 0 subSums;
part2 =
let
sum1 = doMuls firstDoReMatches;
sum2 = doMuls doReMatches;
in
sum1 + sum2;
in
[
part1
part2
]
|