2024 day 15 part 2 in nix

This commit is contained in:
tristan 2024-12-15 16:56:29 +00:00
parent c5c6d4becc
commit 394cf9fccb
3 changed files with 81 additions and 5 deletions

9
2024/15/example3.txt Normal file
View file

@ -0,0 +1,9 @@
#######
#...#.#
#.....#
#..OO@#
#..O..#
#.....#
#######
<vv<<^^<<^^

View file

@ -3,7 +3,7 @@
inherit (lib) splitString mod; inherit (lib) splitString mod;
inherit (lib.lists) findFirstIndex imap0; inherit (lib.lists) findFirstIndex imap0;
inherit (lib.strings) stringToCharacters; inherit (lib.strings) stringToCharacters;
inherit (builtins) elemAt concatStringsSep length elem filter foldl' concatLists; inherit (builtins) elemAt concatStringsSep length elem filter foldl' concatLists floor;
index = i: list: elemAt list i; index = i: list: elemAt list i;
index2d = {x, y}: m: m |> index y |> index x; index2d = {x, y}: m: m |> index y |> index x;
@ -11,7 +11,6 @@
init = let init = let
parts = splitString "\n\n" input; parts = splitString "\n\n" input;
chart = elemAt parts 0 |> splitString "\n" |> map stringToCharacters; chart = elemAt parts 0 |> splitString "\n" |> map stringToCharacters;
# ins = elemAt parts 1 |> stringToCharacters |> filter (char: elem char (stringToCharacters "^><v"));
ins = elemAt parts 1 |> splitString "\n" |> map stringToCharacters; ins = elemAt parts 1 |> splitString "\n" |> map stringToCharacters;
width = (elemAt chart 0 |> length) + 1; width = (elemAt chart 0 |> length) + 1;
startIndex = elemAt parts 0 |> stringToCharacters |> findFirstIndex (char: char == "@") null; startIndex = elemAt parts 0 |> stringToCharacters |> findFirstIndex (char: char == "@") null;
@ -24,11 +23,13 @@
} }
; ;
addVec = a: b: {x = a.x + b.x; y = a.y + b.y;}; addVec = a: b: {x = a.x or 0 + b.x or 0; y = a.y or 0 + b.y or 0;};
objects = { objects = {
wall = "#"; wall = "#";
moveable = "O"; moveable = "O";
leftedge = "[";
rightedge = "]";
empty = "."; empty = ".";
}; };
@ -94,4 +95,70 @@
; ;
part1result = getScore result.chart; part1result = getScore result.chart;
init2 = {
chart = init.chart
|> map (map (c: if c == objects.moveable then ["[" "]"]
else if c == "@" then ["@" "."] else [c c]))
|> map concatLists
;
pos = {
inherit (init.pos) y;
x = init.pos.x * 2;
};
};
move2 = dir: {chart, pos, ...}:
let
nextPos = addVec pos dir;
char = chart |> index2d pos;
switch = state: state // {chart = state.chart |> replace2d pos objects.empty |> replace2d nextPos char;};
moved = move2 dir {inherit chart; pos = nextPos;} |> switch;
moved2 = if dir.y == 0 || !moved.moved then moved else if char == objects.leftedge then
move2 dir {inherit (moved) chart; pos = addVec pos {x = 1;};}
else if char == objects.rightedge then
move2 dir {inherit (moved) chart; pos = addVec pos {x = -1;};}
else
moved;
in if char == objects.wall
then {
inherit chart pos;
moved = false;
} else if char == objects.empty
then {
inherit chart pos;
moved = true;
} else if !moved2.moved
then {inherit chart pos; moved = false;}
else {
moved = true;
pos = nextPos;
inherit (moved2) chart;
}
;
applyIns2 = foldl' (c: ins: let
dir = strToDir ins;
in move2 dir c);
applyInsList2 = foldl' (chart: ins:
# evaluate each line of instructions one at a time, to avoid stack overflow.
let res = applyIns2 chart ins; in builtins.deepSeq res
res
);
result2 = applyInsList2 init2 init.ins;
getScore2 = chart: chart
|> imap0 (y: row: row
|> imap0 (x: obj:
if obj == objects.leftedge then x + y * 100 else 0
)
)
|> concatLists
|> foldl' builtins.add 0
;
part2result = getScore2 result2.chart;
} }

View file

@ -31,11 +31,11 @@
value = let value = let
solution = import ./${id}/solution.nix pkgs; solution = import ./${id}/solution.nix pkgs;
example = (pkgs.lib.readFile ./${id}/example.txt); example = (pkgs.lib.readFile ./${id}/example.txt);
example2 = (pkgs.lib.readFile ./${id}/example2.txt); example3 = (pkgs.lib.readFile ./${id}/example3.txt);
input = (pkgs.lib.readFile "${aoc-inputs}/${id}"); input = (pkgs.lib.readFile "${aoc-inputs}/${id}");
in { in {
example = solution example; example = solution example;
example2 = solution example2; example3 = solution example3;
real = solution input; real = solution input;
test = tix.run [ test = tix.run [
./${id}/solution.test.nix ./${id}/solution.test.nix