changeset 24:e7ce9cd36033

Day 14 part 2
author Lewin Bormann <lbo@spheniscida.de>
date Fri, 16 Dec 2022 19:20:59 +0100
parents 3c02202f3b8e
children c5879c425b94
files 14/14.jl
diffstat 1 files changed, 67 insertions(+), 3 deletions(-) [+]
line wrap: on
line diff
--- a/14/14.jl	Fri Dec 16 18:29:37 2022 +0100
+++ b/14/14.jl	Fri Dec 16 19:20:59 2022 +0100
@@ -51,6 +51,69 @@
 const ROCK = 1;
 const SAND = 2;
 
+function run_matrix_2(v::Vector{Vector{Tuple{Int,Int}}})
+    SAND_POINT = (500,0)
+    minx = min(SAND_POINT[1], minimum(minimum(t[1] for t in vv) for vv in v));
+    maxx = max(SAND_POINT[1], maximum(maximum(t[1] for t in vv) for vv in v));
+    miny = min(SAND_POINT[2], minimum(minimum(t[2] for t in vv) for vv in v));
+    maxy = max(SAND_POINT[2], maximum(maximum(t[2] for t in vv) for vv in v));
+
+    maxx += div((maxy-miny)+1, 1);
+    minx -= div((maxy-miny)+1, 1);
+
+    m = zeros(Int8, maxx-minx+1, maxy-miny+1+2);
+    m[begin:end, end] .= ROCK;
+
+    for line in v
+        last = line[1];
+        for p in @view line[2:end]
+            a, b = CartesianIndex(last .- (minx-1, miny-1)), CartesianIndex(p .- (minx-1, miny-1));
+            @assert abs(last[1]-p[1]) == 0 || abs(last[2]-p[2]) == 0
+            if a > b
+                a, b = b, a;
+            end
+            m[a:b] .= ROCK;
+            last = p;
+        end
+    end
+
+
+    show_cave(m);
+
+    # part 2
+    println(" === PART 2 === ");
+    pos0 = SAND_POINT .- (minx-1, miny-1);
+    down, left, right = (0,1), (-1,1), (1,1);
+    X, Y = size(m);
+    isvalid(pos) = 0 < pos[1] && pos[1] <= X && 0 < pos[2] && pos[2] <= Y
+
+    count = 0;
+    pos = pos0;
+    while true
+        if m[CartesianIndex(pos .+ down)] == EMPTY
+            pos = pos .+ down;
+            continue;
+        elseif m[CartesianIndex(pos .+ left)] == EMPTY
+            pos = pos .+ left;
+            continue
+        elseif m[CartesianIndex(pos .+ right)] == EMPTY
+            pos = pos .+ right;
+            continue;
+        else
+            count += 1;
+            if pos == pos0
+                break;
+            end
+            m[CartesianIndex(pos)] = SAND;
+            println(" ==== $count ==== ");
+            pos = pos0;
+            continue;
+        end
+    end
+    show_cave(m);
+    @show count;
+end
+
 function run_matrix(v::Vector{Vector{Tuple{Int,Int}}})
     # Not very efficient...
     SAND_POINT = (500,0)
@@ -74,6 +137,7 @@
         end
     end
 
+    M0 = copy(m);
     down, left, right = (0,1), (-1,1), (1,1);
     X, Y = size(m);
     isvalid(pos) = 0 < pos[1] && pos[1] <= X && 0 < pos[2] && pos[2] <= Y
@@ -107,7 +171,6 @@
     end
     show_cave(m);
     @show count;
-
 end
 
 function show_cave(m::Matrix{Int8})
@@ -116,7 +179,8 @@
     end
 end
 
-open("14/input.txt"; read=true) do fh
+open("14/test_input.txt"; read=true) do fh
     ac = (parse_all_coords(fh));
-    m = run_matrix(ac);
+    run_matrix(ac);
+    run_matrix_2(ac);
 end