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:
|
||||
let
|
||||
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
|
||||
any (
|
||||
split:
|
||||
if split < strLen && mod strLen split == 0 then
|
||||
if mod strLen split == 0 then
|
||||
let
|
||||
parts = splitStringByLength str split;
|
||||
in
|
||||
|
|
@ -51,7 +52,7 @@ let
|
|||
let
|
||||
invalidIds = flatten (
|
||||
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
|
||||
);
|
||||
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;
|
||||
max = a: b: if a > b then a else b;
|
||||
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;
|
||||
rangeInclusive =
|
||||
min: max:
|
||||
|
|
@ -16,7 +15,7 @@ rec {
|
|||
len = max - min + 1;
|
||||
in
|
||||
genList (i: min + i) len;
|
||||
sum = input: reduce (sum: v: sum + v) 0 input;
|
||||
sum = input: foldl' (sum: v: sum + v) 0 input;
|
||||
reverseList =
|
||||
list:
|
||||
if builtins.length list == 0 then
|
||||
|
|
@ -25,21 +24,5 @@ rec {
|
|||
# Recursively reverse the tail and append the head to the end
|
||||
(reverseList (builtins.tail list)) ++ [ (builtins.head list) ];
|
||||
splitStringByLength =
|
||||
# @param s: The input string.
|
||||
# @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 [ ];
|
||||
str: len: map (i: substring (i * len) (len) str) (genList (i: i) (stringLength str / len));
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue