aoc/2024/02/solution.nix
2024-12-10 09:04:17 +00:00

77 lines
1.6 KiB
Nix

{lib, ...}: rawContent: rec {
content = lib.strings.removeSuffix "\n" rawContent;
toLines = lib.strings.splitString "\n";
toLevels = map ( line: line
|> lib.strings.splitString " "
|> map lib.strings.toInt
)
;
isSafe = builtins.foldl'
({prev ? null, inc ? null, safe}: next:
if !safe then {inherit safe;} else
if prev == null then {prev = next; inherit safe;} else
let
diff = next - prev;
safeDiff = abs diff > 0 && abs diff <= 3;
isInc = next > prev;
in {
prev = next;
safe = safeDiff && ( isInc == inc || isNull inc );
inc = isInc;
}
)
{safe = true;};
abs = n: if n > 0 then n else -n;
countSafety = lib.lists.count (level: level.safe);
getPart1Result = input: input
|> toLines
|> toLevels
|> map isSafe
|> countSafety
;
part1result = getPart1Result content;
excluding = l: i: let
len = builtins.length l;
before = lib.sublist 0 (i) l;
after = lib.sublist (i + 1) (len - 1) l;
in before ++ after
;
dampLevels = l: let
len = builtins.length l;
range = lib.range 0 (len - 1);
toTest = map (excluding l) range
;
in toTest;
anySafety = builtins.any (level: level.safe);
dampSafety = level: level
|> dampLevels
|> map isSafe
|> anySafety
;
isSafeWithDamp = level:
( isSafe level ).safe || ( dampSafety level )
;
countSafeWithDamp = levels: levels
|> map isSafeWithDamp
|> lib.count (a: a == true)
;
part2result = content
|> toLines
|> toLevels
|> countSafeWithDamp
;
}