From eefce852c2ee5f84fc7ce6d0104577a185f68875 Mon Sep 17 00:00:00 2001 From: Tristan Date: Thu, 19 Dec 2024 00:25:35 +0000 Subject: [PATCH] 2024 day 18 part 2 with binary search --- 2024/18/solution.nix | 47 ++++++++++++++++++++++++++++++++------------ 1 file changed, 34 insertions(+), 13 deletions(-) diff --git a/2024/18/solution.nix b/2024/18/solution.nix index 4aa02eb..b3ae70d 100644 --- a/2024/18/solution.nix +++ b/2024/18/solution.nix @@ -28,7 +28,7 @@ inherit size bytes input; walls = init input; part1result = p1Dijkstra.toGoal.steps; - p1Dijkstra = searchAfterBytes 12; + p1Dijkstra = searchAfterBytes bytes; searchAfterBytes = bytes: let walls = lib.sublist 0 bytes (init input); @@ -41,19 +41,40 @@ height = size; }; - findFirst = bytes: prevPath: let - dijkstra = lib.traceSeq "retracing after ${toString bytes} with ${key wall}" (searchAfterBytes bytes); - wall = elemAt walls (bytes - 1); - wallCollides = elem (key wall) (map ({pos,...}: pos) prevPath); - in if !wallCollides - then findFirst (bytes + 1) prevPath - else - if dijkstra.isImpossible - then key wall - else - findFirst (bytes + 1) dijkstra.path; + findFirst = { + index ? bytes, + max ? length walls - 1 + }: let + calcAt = i: rec { + index = i; + wall = elemAt walls (i - 1); + dijkstra = lib.traceSeq "retracing after ${toString index} with ${key wall}" (searchAfterBytes i); + possible = !dijkstra.isImpossible; + }; - part2result = findFirst bytes p1Dijkstra.path; + thisByte = calcAt index; + maxByte = calcAt max; + midByte = calcAt (index + (max - index) / 2); + + isEnd = index == maxByte.index; + + rightHalf = lib.traceSeq + "going right to ${toString (midByte.index + 1)}-${toString max}" + (findFirst {index = midByte.index + 1; inherit max;}); + + leftHalf = lib.traceSeq + "going left to ${toString index}-${toString (midByte.index - 1)}" + (findFirst {index = index + 1; max = midByte.index;}); + in + if isEnd then key thisByte.wall else + if !thisByte.possible then "oof" else + if midByte.possible then + rightHalf + else + leftHalf + ; + + part2result = findFirst {}; };