From c5c6d4becc81d6a01d8fdc9b827650242301397f Mon Sep 17 00:00:00 2001 From: tristan Date: Sun, 15 Dec 2024 15:11:41 +0000 Subject: [PATCH] 2024 day 15 part 1 in nix --- 2024/15/example.txt | 21 ++++++++++ 2024/15/example2.txt | 10 +++++ 2024/15/solution.nix | 97 ++++++++++++++++++++++++++++++++++++++++++++ 2024/flake.lock | 4 +- 2024/flake.nix | 4 +- 5 files changed, 133 insertions(+), 3 deletions(-) create mode 100644 2024/15/example.txt create mode 100644 2024/15/example2.txt create mode 100644 2024/15/solution.nix diff --git a/2024/15/example.txt b/2024/15/example.txt new file mode 100644 index 0000000..84cf1fb --- /dev/null +++ b/2024/15/example.txt @@ -0,0 +1,21 @@ +########## +#..O..O.O# +#......O.# +#.OO..O.O# +#..O@..O.# +#O#..O...# +#O..O..O.# +#.OO.O.OO# +#....O...# +########## + +^v>^vv^v>v<>v^v<<><>>v^v^>^<<<><^ +vvv<<^>^v^^><<>>><>^<<><^vv^^<>vvv<>><^^v>^>vv<>v<<<^<^^>>>^<>vv>v^v^<>><>>>><^^>vv>v<^^^>>v^v^<^^>v^^>v^<^v>v<>>v^v^v^^<^^vv< +<>^^^^>>>v^<>vvv^>^^^vv^^>v<^^^^v<>^>vvvv><>>v^<<^^^^^ +^><^><>>><>^^<<^^v>>><^^>v>>>^v><>^v><<<>vvvv>^<><<>^>< +^>><>^v<><^vvv<^^<><^v<<<><<<^^<^>>^<<<^>>^v^>>^v>vv>^<<^v<>><<><<>v<^vv<<<>^^v^>^^>>><<^v>>v^v><^^>>^<>vv^ +<><^^>^^^<>^vv<<^><<><<><<<^^<<<^<<>><<><^^^>^^<>^>v<> +^^>vv<^v^v^<>^^^>>>^^vvv^>vvv<>>>^<^>>>>>^<<^v>^vvv<>^<>< +v^^>>><<^^<>>^v^v^<<>^<^v^v><^<<<><<^vv>>v>v^<<^ diff --git a/2024/15/example2.txt b/2024/15/example2.txt new file mode 100644 index 0000000..8163605 --- /dev/null +++ b/2024/15/example2.txt @@ -0,0 +1,10 @@ +######## +#..O.O.# +##@.O..# +#...O..# +#.#.O..# +#...O..# +#......# +######## + +<^^>>>vv>v<< diff --git a/2024/15/solution.nix b/2024/15/solution.nix new file mode 100644 index 0000000..74502e3 --- /dev/null +++ b/2024/15/solution.nix @@ -0,0 +1,97 @@ +{lib, ...}: input: rec { + inherit lib; + inherit (lib) splitString mod; + inherit (lib.lists) findFirstIndex imap0; + inherit (lib.strings) stringToCharacters; + inherit (builtins) elemAt concatStringsSep length elem filter foldl' concatLists; + + index = i: list: elemAt list i; + index2d = {x, y}: m: m |> index y |> index x; + + init = let + parts = splitString "\n\n" input; + chart = elemAt parts 0 |> splitString "\n" |> map stringToCharacters; + # ins = elemAt parts 1 |> stringToCharacters |> filter (char: elem char (stringToCharacters "^> splitString "\n" |> map stringToCharacters; + width = (elemAt chart 0 |> length) + 1; + startIndex = elemAt parts 0 |> stringToCharacters |> findFirstIndex (char: char == "@") null; + in { + inherit chart ins; + pos = { + x = mod startIndex width; + y = startIndex / width; + }; + } + ; + + addVec = a: b: {x = a.x + b.x; y = a.y + b.y;}; + + objects = { + wall = "#"; + moveable = "O"; + empty = "."; + }; + + replace2d = {x, y}: updated: chart: let + newRow = chart |> index y |> replace x updated; + in + replace y newRow chart; + + replace = i: updated: list: + let before = lib.sublist 0 i list; + after = lib.sublist (i + 1) (builtins.length list - i) list; + in + if i < 0 || i > builtins.length list then list else + before ++ [updated] ++ after; + + strToDir = strDir: { + x = if strDir == "<" then -1 else if strDir == ">" then 1 else 0; + y = if strDir == "^" then -1 else if strDir == "v" then 1 else 0; + }; + + move = {chart, pos, ...}: dir: let + nextPos = addVec pos dir; + atPos = chart |> index2d pos; + moved = move {inherit chart; pos = nextPos;} dir; + in if atPos == objects.wall + then { + inherit chart pos; + moved = false; + } else if atPos == objects.empty + then { + inherit chart pos; + moved = true; + } else if !moved.moved + then {inherit chart pos; moved = false;} + else { + moved = true; + pos = nextPos; + chart = moved.chart |> replace2d pos objects.empty |> replace2d nextPos atPos; + }; + + chartToStr = chart: chart |> (map (concatStringsSep "")) |> concatStringsSep "\n"; + + applyIns = foldl' (c: ins: let + dir = strToDir ins; + in move c dir); + + applyInsList = foldl' (chart: ins: + # evaluate each line of instructions one at a time, to avoid stack overflow. + let res = applyIns chart ins; in builtins.deepSeq res + (res) + ); + + result = applyInsList init init.ins; + + getScore = chart: chart + |> imap0 (y: row: row + |> imap0 (x: obj: + if obj == objects.moveable then x + y * 100 else 0 + ) + ) + |> concatLists + |> foldl' builtins.add 0 + ; + + part1result = getScore result.chart; +} diff --git a/2024/flake.lock b/2024/flake.lock index b6026cd..dd3f27c 100644 --- a/2024/flake.lock +++ b/2024/flake.lock @@ -3,8 +3,8 @@ "aoc-inputs": { "flake": false, "locked": { - "lastModified": 1734173652, - "narHash": "sha256-jXnmQLoXNcaqYY/uupC8f8JQ27zdwSVBmxAnIxlennk=", + "lastModified": 1734266579, + "narHash": "sha256-fhPoaCWITp2KZtdxm+D9e6GiWf+c3/RGJeiq03/ynfY=", "path": "/tmp/aoc-inputs", "type": "path" }, diff --git a/2024/flake.nix b/2024/flake.nix index 3014a85..7362cbd 100644 --- a/2024/flake.nix +++ b/2024/flake.nix @@ -25,15 +25,17 @@ inherit (pkgs) lib; - in (lib.range 1 14 + in (lib.range 1 15 |> map (i: let id = lib.fixedWidthNumber 2 i; in { name = "day-${id}"; value = let solution = import ./${id}/solution.nix pkgs; example = (pkgs.lib.readFile ./${id}/example.txt); + example2 = (pkgs.lib.readFile ./${id}/example2.txt); input = (pkgs.lib.readFile "${aoc-inputs}/${id}"); in { example = solution example; + example2 = solution example2; real = solution input; test = tix.run [ ./${id}/solution.test.nix