day 9 part 1
This commit is contained in:
parent
7b91042fd3
commit
cecf48f950
3 changed files with 62 additions and 66 deletions
|
@ -4,76 +4,57 @@ with builtins;
|
|||
with utils;
|
||||
let
|
||||
disk = map toIntBase10 (stringToCharacters (head (readLines ./input)));
|
||||
files = genList (id: {
|
||||
size = elemAt disk (id * 2);
|
||||
freeAfter = elemAt disk (id * 2 + 1);
|
||||
inherit id;
|
||||
} ) ((length disk) / 2);
|
||||
files = genList (id:
|
||||
let baseIndex = id * 2;
|
||||
in {
|
||||
size = elemAt disk baseIndex;
|
||||
freeAfter = if (baseIndex + 1) < (length disk) then
|
||||
elemAt disk (baseIndex + 1)
|
||||
else
|
||||
0;
|
||||
inherit id;
|
||||
}) ((length disk) / 2 + 1);
|
||||
|
||||
totalSize = listSumWith (getAttr "size") files;
|
||||
totalFree = listSumWith (getAttr "size") files;
|
||||
|
||||
diskExpanded = concatLists (map (f: (genList (const f.id) f.size) ++ (genList (const null) f.freeAfter)) files);
|
||||
diskSemiExpanded = concatLists (map (f: (genList (const f.id) f.size) ++ (genList (const null) f.freeAfter)) files);
|
||||
|
||||
# totalFree = listSumWith (getAttr "freeAfter") files;
|
||||
|
||||
diskExpanded = concatLists (map
|
||||
(f: (genList (const f.id) f.size) ++ (genList (const null) f.freeAfter))
|
||||
files);
|
||||
# diskSemiExpanded = concatLists (map (f: [ (genList (const f.id) f.size) f.freeAfter ]) files);
|
||||
|
||||
toMove = reverseList (filter (invert isNull) (drop totalSize diskExpanded));
|
||||
base = take totalSize diskExpanded;
|
||||
# base = take totalSize diskExpanded;
|
||||
|
||||
# compress = base: toMove: let firstNullIndex = lists.findFirstIndex isNull null base; in
|
||||
# if (toMove == []) || (isNull firstNullIndex) then
|
||||
# base
|
||||
# else (take firstNullIndex base) ++ [ (head toMove) ] ++ (compress (drop (firstNullIndex + 1) base) (tail toMove) );
|
||||
compress = files': toMove':
|
||||
let f = head files';
|
||||
in if toMove' == [ ] then
|
||||
(genList (const f.id) f.size)
|
||||
else
|
||||
(genList (const f.id) f.size) ++ (take f.freeAfter toMove')
|
||||
++ (compress (tail files') (drop f.freeAfter toMove'));
|
||||
|
||||
build_link_chunk = f: { content = genList (const f.id) f.size; inherit (f) freeAfter; };
|
||||
|
||||
compress = uncompressed_chunks: toMove': let
|
||||
h = head uncompressed_chunks;
|
||||
moveAmount = min (length toMove') h.freeAfter;
|
||||
in if toMove' == [] then h.content else h.content ++ (take moveAmount toMove') ++ (compress (tail uncompressed_chunks) (drop moveAmount toMove'));
|
||||
|
||||
# foldl' (current: c:
|
||||
# if isNull c then
|
||||
# {
|
||||
# next = current.next + 1;
|
||||
# content = current.content ++ [ (elemAt toMove current.next) ];
|
||||
# } else {
|
||||
# inherit (current) next;
|
||||
# content = current.content ++ [ c ];
|
||||
# }
|
||||
# ) { next = 0; content = []; } base;
|
||||
|
||||
chunks = map build_link_chunk files;
|
||||
# compressed = take totalSize (compress chunks toMove); # taking totalSize because compress overshoots. Compress overshoots because the last file contents are partially duplicated.
|
||||
compressed = compress chunks toMove; # taking totalSize because compress overshoots. Compress overshoots because the last file contents are partially duplicated.
|
||||
|
||||
# expandToMove = foldl' () [] (genList)
|
||||
compressed = take totalSize (compress files toMove);
|
||||
# compressed = compress files toMove;
|
||||
|
||||
checksum = imap0 mul compressed;
|
||||
|
||||
|
||||
|
||||
|
||||
# compressed = genList (i: let current = in) (length diskExpanded)
|
||||
# chunks = map build_link_chunk files;
|
||||
# compressed = compress chunks;
|
||||
|
||||
in {
|
||||
part1 = listSum checksum;
|
||||
test1 = elemAt compressed 10000;
|
||||
test2 = elemAt compressed 20000;
|
||||
test3 = elemAt compressed 30000;
|
||||
test4 = elemAt compressed 40000;
|
||||
test5 = elemAt compressed 49000;
|
||||
# part1 = listSum checksum;
|
||||
# inherit files;
|
||||
# test = listSumLog (sublist 0 50000 checksum);
|
||||
part1 = listSumLog checksum;
|
||||
# inherit chunks;
|
||||
# inherit compressed;
|
||||
lenCompressed = length compressed;
|
||||
compressedHead = head compressed;
|
||||
inherit totalSize;
|
||||
moveLen = length toMove;
|
||||
nullsInBase = count isNull base;
|
||||
# lenCompressed = length compressed;
|
||||
# compressedHead = head compressed;
|
||||
# inherit totalSize totalFree;
|
||||
# inherit diskExpanded;
|
||||
# moveLen = length toMove;
|
||||
# nullsInBase = count isNull base;
|
||||
# inherit disk;
|
||||
# sumTest = listSumLog [1 2 3 4 5];
|
||||
|
||||
|
||||
diskSize = listSum disk; # TOO DAMN LARGE FOR LINEAR RECURSION!
|
||||
fileCount = length files; # TOO DAMN LARGE FOR LINEAR RECURSION!
|
||||
}
|
||||
|
|
1
day9/example
Normal file
1
day9/example
Normal file
|
@ -0,0 +1 @@
|
|||
2333133121414131402
|
32
utils.nix
32
utils.nix
|
@ -13,13 +13,15 @@ with builtins; rec {
|
|||
listSumLog = l:
|
||||
if length l == 1 then
|
||||
head l
|
||||
else if l == [] then
|
||||
else if l == [ ] then
|
||||
0
|
||||
else
|
||||
(listSumLog (take ((length l) / 2) l)) + (listSumLog (drop ((length l) / 2) l));
|
||||
(listSumLog (take ((length l) / 2) l))
|
||||
+ (listSumLog (drop ((length l) / 2) l));
|
||||
|
||||
chunk = size: l:
|
||||
if length l < size then l else (take size l) ++ (chunk size (drop size l));
|
||||
|
||||
chunk = size: l: if length l < size then l else (take size l) ++ (chunk size (drop size l));
|
||||
|
||||
deleteAt = l: i: (take i l) ++ (drop (i + 1) l);
|
||||
eq = x: y: x == y;
|
||||
greaterThan = x: y: x > y;
|
||||
|
@ -54,12 +56,24 @@ with builtins; rec {
|
|||
else
|
||||
[ pos ] ++ (raycastUntil pred direction (vecSum pos direction));
|
||||
|
||||
getMatrixIndices = m: let
|
||||
makeLayers = m: if isList m then [ (listRange m) ] ++ (makeLayers (head m)) else [];
|
||||
layers = makeLayers m;
|
||||
in mapCartesianProduct (args@{...}: attrValues args) (listToAttrs (map (k: nameValuePair (toString k) (elemAt layers k)) (listRange layers)));
|
||||
getMatrixIndices = m:
|
||||
let
|
||||
makeLayers = m:
|
||||
if isList m then [ (listRange m) ] ++ (makeLayers (head m)) else [ ];
|
||||
layers = makeLayers m;
|
||||
in mapCartesianProduct (args@{ ... }: attrValues args) (listToAttrs
|
||||
(map (k: nameValuePair (toString k) (elemAt layers k))
|
||||
(listRange layers)));
|
||||
|
||||
gcd = a: b: if a == 0 then b else if b == 0 then a else if a < b then gcd b a else gcd b (mod a b);
|
||||
gcd = a: b:
|
||||
if a == 0 then
|
||||
b
|
||||
else if b == 0 then
|
||||
a
|
||||
else if a < b then
|
||||
gcd b a
|
||||
else
|
||||
gcd b (mod a b);
|
||||
listGcd = l: foldl' gcd (head l) (tail l);
|
||||
|
||||
shortenVec = vec: scalarVecDiv (listGcd (map abs vec)) vec;
|
||||
|
|
Loading…
Reference in a new issue