my splitStringByLen function was extremely slow, and lists/iterating lists is slow in general so cahnge to splitByLen make old version 60% faster, and a version without the intermediate loop it is 4s
This commit is contained in:
parent
e9f2b69924
commit
802a8dde26
3 changed files with 67 additions and 23 deletions
|
|
@ -30,11 +30,12 @@ let
|
||||||
str:
|
str:
|
||||||
let
|
let
|
||||||
strLen = stringLength str;
|
strLen = stringLength str;
|
||||||
splits = reverseList (genList (i: i + 1) strLen);
|
maxSplit = strLen / 2; # Only check up to half length since it must repeat at least twice
|
||||||
|
splits = genList (i: i + 1) maxSplit;
|
||||||
in
|
in
|
||||||
any (
|
any (
|
||||||
split:
|
split:
|
||||||
if split < strLen && mod strLen split == 0 then
|
if mod strLen split == 0 then
|
||||||
let
|
let
|
||||||
parts = splitStringByLength str split;
|
parts = splitStringByLength str split;
|
||||||
in
|
in
|
||||||
|
|
@ -51,7 +52,7 @@ let
|
||||||
let
|
let
|
||||||
invalidIds = flatten (
|
invalidIds = flatten (
|
||||||
map (
|
map (
|
||||||
range: (reduce (invalidIds: id: invalidIds ++ (if badIdFunc id then [ id ] else [ ])) [ ] range)
|
range: (foldl' (invalidIds: id: invalidIds ++ (if badIdFunc id then [ id ] else [ ])) [ ] range)
|
||||||
) fullRanges
|
) fullRanges
|
||||||
);
|
);
|
||||||
invalidIdNums = map (v: toIntBase10 v) invalidIds;
|
invalidIdNums = map (v: toIntBase10 v) invalidIds;
|
||||||
|
|
|
||||||
60
2025/day_2_perf.nix
Normal file
60
2025/day_2_perf.nix
Normal file
|
|
@ -0,0 +1,60 @@
|
||||||
|
# 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;
|
||||||
|
}
|
||||||
|
|
@ -5,7 +5,6 @@ rec {
|
||||||
min = a: b: if a < b then a else b;
|
min = a: b: if a < b then a else b;
|
||||||
max = a: b: if a > b then a else b;
|
max = a: b: if a > b then a else b;
|
||||||
split = delim: input: filter (s: isString s && s != "") (builtins.split delim input);
|
split = delim: input: filter (s: isString s && s != "") (builtins.split delim input);
|
||||||
reduce = foldl'; # foldl' (acc: elem: acc + elem) 0 [1 2 3]
|
|
||||||
flatten = input: concatMap (x: if isList x then x else [ x ]) input;
|
flatten = input: concatMap (x: if isList x then x else [ x ]) input;
|
||||||
rangeInclusive =
|
rangeInclusive =
|
||||||
min: max:
|
min: max:
|
||||||
|
|
@ -16,30 +15,14 @@ rec {
|
||||||
len = max - min + 1;
|
len = max - min + 1;
|
||||||
in
|
in
|
||||||
genList (i: min + i) len;
|
genList (i: min + i) len;
|
||||||
sum = input: reduce (sum: v: sum + v) 0 input;
|
sum = input: foldl' (sum: v: sum + v) 0 input;
|
||||||
reverseList =
|
reverseList =
|
||||||
list:
|
list:
|
||||||
if builtins.length list == 0 then
|
if builtins.length list == 0 then
|
||||||
[ ]
|
[ ]
|
||||||
else
|
else
|
||||||
# Recursively reverse the tail and append the head to the end
|
# Recursively reverse the tail and append the head to the end
|
||||||
(reverseList(builtins.tail list)) ++ [ (builtins.head list) ];
|
(reverseList (builtins.tail list)) ++ [ (builtins.head list) ];
|
||||||
splitStringByLength =
|
splitStringByLength =
|
||||||
# @param s: The input string.
|
str: len: map (i: substring (i * len) (len) str) (genList (i: i) (stringLength str / len));
|
||||||
# @param len: The desired length of each part.
|
|
||||||
s: len:
|
|
||||||
let
|
|
||||||
# Recursive helper function
|
|
||||||
splitRec =
|
|
||||||
currentString: acc:
|
|
||||||
if stringLength currentString <= 0 then
|
|
||||||
reverseList acc
|
|
||||||
else
|
|
||||||
let
|
|
||||||
chunk = substring 0 len currentString;
|
|
||||||
remaining = substring len (stringLength currentString - len) currentString;
|
|
||||||
in
|
|
||||||
splitRec remaining ([ chunk ] ++ acc);
|
|
||||||
in
|
|
||||||
splitRec s [ ];
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue