three broken solutions to 2024 day 9 part 1
This commit is contained in:
parent
e1c3006456
commit
82a96a263e
122
2024/09/bad.solution.nix
Normal file
122
2024/09/bad.solution.nix
Normal 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;
|
||||||
|
|
||||||
|
}
|
130
2024/09/bad.solution.test.nix
Normal file
130
2024/09/bad.solution.test.nix
Normal 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
1
2024/09/example.txt
Normal file
|
@ -0,0 +1 @@
|
||||||
|
2333133121414131402
|
1
2024/09/input.txt
Normal file
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
5
2024/09/solution.nix
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
{lib, ...}: input: let
|
||||||
|
|
||||||
|
in {
|
||||||
|
|
||||||
|
}
|
12
2024/09/solution.test.nix
Normal file
12
2024/09/solution.test.nix
Normal 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" [
|
||||||
|
])
|
||||||
|
]
|
|
@ -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
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue