diff --git a/2024/06/solution.nix b/2024/06/solution.nix index ea351f0..bb6d12f 100644 --- a/2024/06/solution.nix +++ b/2024/06/solution.nix @@ -132,45 +132,56 @@ startingObsMap = getObsMap chart; - getObsMap = let - findObs = lib.lists.findFirstIndex (b: b == "#") null; - in chart: chart + getObsMap = chart: chart |> lib.imap0 (y: line: line - |> lib.imap0 (x: char: if char != "#" then null else { - right = if y + 1 >= height || x + 1 >= width then null else (chart - |> index (y + 1) - |> lib.sublist (x + 1) width - |> findObs - |> maybeAdd (x + 1) - ); - left = if y < 1 || x <= 0 then null else (chart - |> index (y - 1) - |> lib.sublist 0 (x) - |> lib.reverseList - |> findObs - |> maybeSub (x - 1) - ); - down = if x < 1 then null else (chart - |> lib.sublist (y + 1) (height) - |> map (index (x - 1)) - |> findObs - |> maybeAdd (y + 1) - ); - up = if x + 1 >= width then null else (searchUp (b: b == "#") {x = x + 1; y = y - 1;} chart); - }) + |> lib.imap0 (x: char: if char != "#" then null else makeObs chart (b: b == "#") {inherit x y;}) ) ; - maybe = f: b: if isNull b then null else f b; - maybeAdd = v: builtins.add v |> maybe; - maybeSub = v: builtins.sub v |> maybe; + makeObs = chart: matcher: {x, y}: { + right = if y + 1 >= height || x + 1 >= width then null else + searchRight matcher {x = x + 1; y = y + 1;} chart; - searchUp = matcher: {x, y}: chart: chart - |> lib.sublist 0 (y + 1) - |> map (index (x)) + left = if y < 1 || x <= 0 then null else + searchLeft matcher {x = x - 1; y = y - 1;} chart; + + down = if x <= 0 || y + 1 >= width then null else + searchDown matcher {x = x - 1; y = y + 1;} chart; + + up = if x + 1 >= width then null else + searchUp matcher {x = x + 1; y = y - 1;} chart; + }; + + maybe = f: a: b: if !(builtins.isInt a && builtins.isInt b) then null else f a b; + maybeAdd = maybe builtins.add; + maybeSub = maybe builtins.sub; + column = x: map (index x); + + searchLeft = matcher: {x, y}: chart: chart + |> index y + |> lib.sublist 0 (x + 1) |> lib.reverseList |> lib.lists.findFirstIndex matcher null - |> maybeSub (y) + |> maybeSub x + ; + searchDown = matcher: {x, y}: chart: chart + |> lib.sublist y height + |> column x + |> lib.lists.findFirstIndex matcher null + |> maybeAdd y + ; + searchRight = matcher: {x, y}: chart: chart + |> index y + |> lib.sublist x width + |> lib.lists.findFirstIndex matcher null + |> maybeAdd x + ; + searchUp = matcher: {x, y}: chart: chart + |> lib.sublist 0 (y + 1) + |> column x + |> lib.reverseList + |> lib.lists.findFirstIndex matcher null + |> maybeSub y ; firstOb = { @@ -220,14 +231,46 @@ x = lib.mod i width; y = i / height; }) (height * width) - |> builtins.filter (pos: index2d pos chart == ".") - |> map ({x, y}: replace2d {inherit x y;} "#" chart) + |> builtins.filter (pos: index2d pos startingObsMap |> isNull) + |> map (pos: insert pos startingObsMap) ; - # this is a really slow way to do this, instead just find the adjacent columns and update accordingly - allMaps = allObs |> map getObsMap; + replaceColumn = y: lib.zipListsWith (row: new: + replace y row new + ); - loopyMaps = allMaps + insert = {x, y}@pos: chart: let + newObs = makeObs chart builtins.isAttrs pos; + # nextL = searchRight + in chart + |> replace2d pos newObs + # update obstacles on rows above and below + |> (if y - 1 < 0 then lib.id else nChart: replace (y - 1) ( + nChart |> index (y - 1) + |> lib.imap0 (x: b: if isNull b then null else + makeObs nChart builtins.isAttrs {inherit x; y = y - 1;}) + # |> map (o: if builtins.isAttrs o && o.right > x then + # o // {right = x;} else o) + ) nChart) + |> (if y + 1 >= width then lib.id else nChart: replace (y + 1) ( + nChart |> index (y + 1) + |> lib.imap0 (x: b: if isNull b then null else + makeObs nChart builtins.isAttrs {inherit x; y = y + 1;}) + ) nChart) + |> (if x - 1 < 0 then lib.id else nChart: + replaceColumn (x - 1) (column (x - 1) nChart + |> lib.imap0 (y: b: if isNull b then null else + makeObs nChart builtins.isAttrs {inherit y; x = x - 1;}) + ) nChart) + |> (if x + 1 >= width then lib.id else nChart: + replaceColumn (x + 1) (column (x + 1) nChart + |> lib.imap0 (y: b: if isNull b then null else + makeObs nChart builtins.isAttrs {inherit y; x = x + 1;}) + ) nChart) + + ; + + loopyMaps = allObs |> builtins.filter (m: (getFastpath {obsMap = m;}).looped); part2faster = builtins.length loopyMaps; diff --git a/2024/08/example b/2024/08/example new file mode 100644 index 0000000..78a1e91 --- /dev/null +++ b/2024/08/example @@ -0,0 +1,12 @@ +............ +........0... +.....0...... +.......0.... +....0....... +......A..... +............ +............ +........A... +.........A.. +............ +............ diff --git a/2024/08/input b/2024/08/input new file mode 100644 index 0000000..ad91e12 --- /dev/null +++ b/2024/08/input @@ -0,0 +1,50 @@ +....h.....Q..............Y........................ +...............................Y........C......... +...............m..........x................B...... +........................Y..............qB......... +......g4.........................h..Y.....q...c... +................n.....R........................... +.......................................w........5. +........g...m...........................w5........ +..n...........R.1................W.......q.5...... +.........h...n.................e.................. +...............................R..........B....C.. +.........4................................5.e..... +.......0..4......n.......x..w..................... +.......g.....m........x..b.....W.....B.......w.... +..............m........................3......C... +........q...0.......h....................C.3...... +..................3.....................D......... +...............R..........3.............X......... +..............................W............k2..... +..........7............................2.......... +...............A.............................X...2 +.......................c...x...................... +....................................d............. +.....1......................d..................... +...........1...........................e.......... +.........0.7K.........................2.........W. +...b......0.....A................................. +......................1....ic..................... +......b......................i.................... +..Q.....b..........................A..E........... +...7.........................V.................... +........A.....................v......d............ +........v............c...................8E....... +..............................V........8.....E..N. +......................6........................... +.......I....M....................V................ +...G......................a.......8............... +.........r.9........a...i..................X...... +...............r..i...............e............N.. +.....H...........k....9.....6...............8..... +.v.....................6................V......... +.........v.......a........k..........D............ +Ha..........k.........K........E.......d.......... +...............y.MG..............6....D........... +.........H..G...M......9.K..............N......... +.......G.........................K................ +...............M.........I.......D................ +.................................................. +....r....y................9....................... +....y................................N............ diff --git a/2024/08/sample1 b/2024/08/sample1 new file mode 100644 index 0000000..e9aaca3 --- /dev/null +++ b/2024/08/sample1 @@ -0,0 +1,10 @@ +.......... +...#...... +#......... +....a..... +........a. +.....a.... +..#....... +......#... +.......... +.......... diff --git a/2024/08/solution.nix b/2024/08/solution.nix new file mode 100644 index 0000000..87a0a8a --- /dev/null +++ b/2024/08/solution.nix @@ -0,0 +1,48 @@ +{lib, ...}: let + + addVec = a: b: {x = a.x + b.x; y = a.y + b.y;}; + subVec = a: b: {x = a.x - b.x; y = a.y - b.y;}; + + toCharList = builtins.foldl' + ({y, x, chars}: char: + if char == "." || char == "#" then {inherit y; x = x + 1; inherit chars;} + else if char == "\n" then {y = y + 1; x = 1; inherit chars;} + else {inherit y; x = x + 1; chars = chars ++ [{inherit x y char;}];} + ) + {y = 1; x = 1; chars = [];} # yeah starting at 1,1 what you gonna do about it + ; + + toNodes = {chars, ...}@amap: amap // { + nodes = map (antenna: + builtins.foldl' (acc: antenna2: + if antenna == antenna2 then acc + else if antenna.char != antenna2.char then acc + else let + delta = subVec antenna antenna2; + in acc ++ [(addVec antenna delta)] + ) [] chars + ) chars; + }; + + getUniqueNodes = amap: let + size = amap.x; + in amap.nodes + |> lib.concatLists + |> builtins.filter ({x, y}: x > 0 && y > 0 && x < size && y < size) + |> lib.unique + ; + +in { + inherit addVec subVec toCharList toNodes; + + part1result = s: s + |> lib.trim + |> lib.stringToCharacters + |> toCharList + |> toNodes + |> getUniqueNodes + |> builtins.length + ; + + +} diff --git a/2024/08/solution.test.nix b/2024/08/solution.test.nix new file mode 100644 index 0000000..726d00a --- /dev/null +++ b/2024/08/solution.test.nix @@ -0,0 +1,26 @@ +{describe, it, ...}: +let + pkgs = import {}; + solution = import ./solution.nix pkgs; + exampleInput = pkgs.lib.readFile ./example; + sample1Input = pkgs.lib.readFile ./sample1; +in [ + (describe "part 1" [ + (it "get's the answer with example input" { + actual = solution.part1result exampleInput; + expected = 14; + }) + (it "get's the answer with other sample" { + actual = solution.part1result sample1Input; + expected = 4; + }) + (it "adds vectors" { + actual = solution.addVec {x = 1; y = 2;} {x = 3; y = 4;}; + expected = {x = 4; y = 6;}; + }) + (it "subtracts vectors" { + actual = solution.subVec {x = 4; y = 3;} {x = 1; y = 2;}; + expected = {x = 3; y = 1;}; + }) + ]) +] diff --git a/2024/flake.nix b/2024/flake.nix index a9eea02..e3402c5 100644 --- a/2024/flake.nix +++ b/2024/flake.nix @@ -43,5 +43,17 @@ ]; }; + day08 = let + solution = import ./08/solution.nix pkgs; + example = (pkgs.lib.readFile ./08/example); + input = (pkgs.lib.readFile ./08/input); + in { + solution = solution; + part1result = solution.part1result input; + test = tix.run [ + ./08/solution.test.nix + ]; + }; + }; }