three broken solutions to 2024 day 9 part 1

This commit is contained in:
tristan 2024-12-09 14:32:12 +00:00
parent e1c3006456
commit 82a96a263e
7 changed files with 282 additions and 0 deletions

122
2024/09/bad.solution.nix Normal file
View file

@ -0,0 +1,122 @@
{lib, ...}: input: let
inherit (builtins) length foldl' filter tail head genList elemAt;
inherit (lib) stringToCharacters toInt mod last reverseList min;
data = input
|> lib.trim
|> stringToCharacters
|> map toInt;
disk = data
|> foldl' (acc: size:
let
index = length acc;
id = index / 2;
prev = last acc;
in
acc ++ [{
inherit size;
id = if index == 0 || mod index 2 == 0 then id else null;
start = if length acc == 0 then 0 else prev.start + prev.size;
}]
) []
;
# works, but max-call-depth exceeded on real input... ugh
defragRec = {free, files}: if free == [] then files else
let
file = last files;
space = head free;
size = min (space.size) (file.size);
in
if file.start + file.size < space.start then files else
defragRec {
files = (if size == 0 then [] else [{
inherit (file) id;
inherit (space) start;
inherit size;
}])
++ (lib.sublist 0 (length files - 1) files)
++ (if file.size == size then [] else [{
inherit (file) id start;
size = file.size - size;
}]);
free = (if size == 0 then [] else [{
start = space.start + size;
size = space.size - size;
}])
++ tail free;
}
;
defrag = free: file:
free |> foldl' (acc: space: let
amt = min acc.rem space.size;
in if (isNull space.id || space.id == file.id) -> acc.rem == 0
then acc // {free = acc.free ++ [space];}
else {
file = acc.file ++ [{
inherit (file) id;
inherit (space) start;
size = amt;
}];
free = acc.free ++ (if space.size - amt == 0 then [] else [{
id = space.id;
start = space.start + amt;
size = space.size - amt;
}]);
rem = acc.rem - amt;
})
{free = []; file = []; rem = file.size;}
|> (result: { inherit (result) free file; })
;
defragged = let
files = disk
|> filter ({id, ...}: !isNull id)
|> reverseList
;
in files |> foldl' (acc: file: let
res = builtins.trace "defraging with file ${toString file.id}" (defrag acc.free file);
in
{
inherit (res) free;
files = acc.files ++ res.file;
})
{free = disk; files = [];}
;
checksum = disk: disk.files
|> foldl' (acc: {id, size, start}: acc + (id * size * (start + ((size - 1) / 2.0)))) 0
;
fullDisk = disk |> map (sect: genList (i: sect.id) sect.size) |> lib.concatLists;
defragFullDisk = d: let
notEmptyDisk = d |> filter (s: !isNull s);
in d |> foldl' ({i, j, acc}: id: let
idFromEnd = elemAt notEmptyDisk i;
in {
acc = acc ++ [(if j >= length notEmptyDisk then null else if isNull id then idFromEnd else id)];
i = if isNull id then i + 1 else i;
j = j + 1;
}
) {i = 0; acc = []; j = 0;};
checksumFullDisk = d: d |> filter (s: !isNull s)
|> foldl'
({i, total}: id: {i = i + 1; total = total + i * id;})
{i = 0; total = 0;};
in {
inherit data disk defrag defragged checksum fullDisk;
part1result = defragged |> checksum;
# defraggedFullDisk = defragFullDisk fullDisk;
# part1result = (defragFullDisk fullDisk).acc |> checksumFullDisk;
}

View file

@ -0,0 +1,130 @@
{describe, it, ...}:
let
pkgs = import <nixpkgs> {};
lib = pkgs.lib;
solution = import ./solution.nix pkgs;
sample1 = "2333133121414131402";
/*
0099811188827773336446555566
*/
sample1defraged = [
{ id = 0; size = 2; start = 0; }
{ id = 9; size = 2; start = 2; }
{ id = 8; size = 1; start = 4; }
{ id = 1; size = 3; start = 5; }
{ id = 8; size = 3; start = 8; }
{ id = 2; size = 1; start = 11; }
{ id = 7; size = 3; start = 12; }
{ id = 3; size = 3; start = 15; }
{ id = 6; size = 1; start = 18; }
{ id = 4; size = 2; start = 19; }
{ id = 6; size = 1; start = 21; }
{ id = 5; size = 4; start = 22; }
{ id = 6; size = 1; start = 26; }
{ id = 6; size = 1; start = 27; }
];
sample2 = "12345";
sample2disk = [
{id = 0; size = 1; start = 0;}
{id = null; size = 2; start = 1;}
{id = 1; size = 3; start = 3;}
{id = null; size = 4; start = 6;}
{id = 2; size = 5; start = 10;}
];
in [
(describe "part 1" [
(it "gets list of disk chunks" {
actual = (solution sample2).disk;
expected = sample2disk;
})
(it "gets list of disk chunks with bigger sample" {
actual = (solution sample1).disk;
expected = [
{ id = 0; size = 2; start = 0; }
{ id = null; size = 3; start = 2; }
{ id = 1; size = 3; start = 5; }
{ id = null; size = 3; start = 8; }
{ id = 2; size = 1; start = 11; }
{ id = null; size = 3; start = 12; }
{ id = 3; size = 3; start = 15; }
{ id = null; size = 1; start = 18; }
{ id = 4; size = 2; start = 19; }
{ id = null; size = 1; start = 21; }
{ id = 5; size = 4; start = 22; }
{ id = null; size = 1; start = 26; }
{ id = 6; size = 4; start = 27; }
{ id = null; size = 1; start = 31; }
{ id = 7; size = 3; start = 32; }
{ id = null; size = 1; start = 35; }
{ id = 8; size = 4; start = 36; }
{ id = null; size = 0; start = 40; }
{ id = 9; size = 2; start = 40; }
];
})
(it "defrags files" {
actual = (solution sample1).defragged.files
|> builtins.filter ({size,...}: size > 0)
|> lib.sort (a: b: a.start < b.start);
expected = sample1defraged;
})
# (it "defrags a file" {
# actual = (solution sample1).defrag
# [
# {id = null; size = 1; start = 10;}
# {id = null; size = 5; start = 15;}
# {id = null; size = 10; start = 50;}
# {id = 1; size = 100; start = 100;}
# ]
# {id = 1; size = 100; start = 100;};
# expected = {
# file = [
# { id = 1; size = 1; start = 10; }
# { id = 1; size = 5; start = 15; }
# { id = 1; size = 10; start = 50;}
# { id = 1; size = 100 - 10 - 5 - 1; start = 100;}
# ];
# free = [
# {id = null; start = 100 + 100 - 10 - 5 - 1; size = 1 + 5 + 10;}
# ];
# };
# })
#
# (it "doesn't defrag a file to the left of free space" {
# actual = (solution sample1).defrag
# [
# {id = 1; size = 100; start = 0;}
# {id = null; size = 1; start = 101;}
# ]
# {id = 1; size = 100; start = 0;};
# expected = {
# file = [
# { id = 1; size = 100; start = 0;}
# ];
# free = [
# { id = null; size = 1; start = 101;}
# ];
# };
# })
#
(it "gets checksum" {
actual = (solution sample1).checksum {files = sample1defraged;};
expected = 1928;
})
(it "gets the correct result" {
actual = (solution sample1).part1result;
expected = 1928;
})
(it "makes the disk" {
actual = (solution sample1).fullDisk;
expected = 5;
})
])
]

1
2024/09/example.txt Normal file
View file

@ -0,0 +1 @@
2333133121414131402

1
2024/09/input.txt Normal file

File diff suppressed because one or more lines are too long

5
2024/09/solution.nix Normal file
View file

@ -0,0 +1,5 @@
{lib, ...}: input: let
in {
}

12
2024/09/solution.test.nix Normal file
View file

@ -0,0 +1,12 @@
{describe, it, ...}:
let
pkgs = import <nixpkgs> {};
lib = pkgs.lib;
solution = import ./solution.nix pkgs;
sample1 = "2333133121414131402";
sample2 = "12345";
in [
(describe "part 1" [
])
]

View file

@ -43,5 +43,16 @@
]; ];
}; };
day09 = let
solution = import ./09/bad.solution.nix pkgs;
example = (pkgs.lib.readFile ./09/example.txt);
in {
example = solution example;
real.part1result = "My solution doesn't work on the real input :(";
test = tix.run [
./09/solution.test.nix
];
};
}; };
} }