60 lines
1.5 KiB
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;
|
|
}
|