{ lib, utils, ... }: with lib; with builtins; with utils; let disk = map toIntBase10 (stringToCharacters (head (readLines ./input))); 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 "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; 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')); compressed = take totalSize (compress files toMove); # compressed = compress files toMove; checksum = imap0 mul compressed; in { # 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 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! }