advent_of_code/2025/day_2_perf.nix

60 lines
1.5 KiB
Nix

# nix eval -f ./day_2_perf.nix part2
# nix eval -f ./day_2_perf.nix part2 --arg input 'builtins.readFile ./puzzle_cache/day_2_1'
{
input ? (builtins.readFile ./puzzle_cache/day_2_0),
}:
with builtins;
with import ./utils.nix;
let
# part 2 any repeat num
isStrPatternRepeated =
str:
let
strLen = stringLength str;
maxSplit = strLen / 2; # Only check up to half length since it must repeat at least twice
splits = genList (i: i + 1) maxSplit;
checkSplit =
split:
if mod strLen split == 0 then
let
count = strLen / split;
firstElem = substring 0 split str;
checkElem =
index:
if index >= count then
true
else if substring (index * split) split str == firstElem then
checkElem (index + 1)
else
false;
allPartsEqual = checkElem 1;
in
allPartsEqual
else
false;
in
any checkSplit splits;
ranges = map (range: map (v: toIntBase10 v) (split "-" range)) (split "," input);
sumBadIdsInRange =
range:
let
from = elemAt range 0;
to = elemAt range 1;
ids = genList (i: from + i) (to - from + 1);
processId =
acc: id:
let
strId = toString id;
in
if isStrPatternRepeated strId then acc + id else acc;
in
(foldl' processId 0 ids);
sumAllBadIds = sum (map sumBadIdsInRange ranges);
in
{
part2 = sumAllBadIds;
}