|
1 | 1 | { inputPath, lib ? import <nixpkgs/lib> }:
|
2 |
| - let inherit (builtins) length readFile; |
3 |
| - inherit (lib.lists) all count filter head tail zipListsWith; |
| 2 | + let inherit (builtins) head tail length readFile; |
| 3 | + inherit (lib.lists) all any count filter range zipListsWith; |
4 | 4 | inherit (lib.strings) splitString toInt stringLength;
|
| 5 | + inherit (lib.trivial) flip; |
5 | 6 | in
|
6 | 7 | let abs = x: if x >= 0 then x else -x;
|
7 | 8 | compose = f: g: x: f (g x);
|
| 9 | + dropNth = n: xs: if n == 0 then tail xs else [(head xs)] ++ dropNth (n - 1) (tail xs); |
| 10 | + removeOne = r: map (flip dropNth r) (range 0 (length r - 1)); |
8 | 11 | input = readFile inputPath;
|
9 | 12 | isNonEmpty = s: stringLength s > 0;
|
10 | 13 | lines = filter isNonEmpty (splitString "\n" input);
|
11 | 14 | reports = map (compose (map toInt) (splitString " ")) lines;
|
12 |
| - isSafe = r: let diffs = zipListsWith (x: y: x - y) r (tail r); |
| 15 | + isSafe1 = r: let diffs = zipListsWith (x: y: x - y) r (tail r); |
13 | 16 | in (all (x: x > 0) diffs || all (x: x < 0) diffs)
|
14 | 17 | && all (x: x >= 1 && x <= 3) (map abs diffs);
|
15 |
| - part1 = count isSafe reports; |
16 |
| - in "Part 1: " + toString part1 |
| 18 | + isSafe2 = compose (any isSafe1) removeOne; |
| 19 | + part1 = count isSafe1 reports; |
| 20 | + part2 = count isSafe2 reports; |
| 21 | + in "Part 1: " + toString part1 + ", Part 2: " + toString part2 |
0 commit comments