changeset 27:457820e3609e

Day 15 part 2 - quite fast implementation! :))
author Lewin Bormann <lbo@spheniscida.de>
date Sat, 17 Dec 2022 13:47:46 +0100
parents 7db9666c6c77
children 72bbee9f4d9e
files 15/15.jl
diffstat 1 files changed, 34 insertions(+), 11 deletions(-) [+]
line wrap: on
line diff
--- a/15/15.jl	Sat Dec 17 13:11:15 2022 +0100
+++ b/15/15.jl	Sat Dec 17 13:47:46 2022 +0100
@@ -34,12 +34,16 @@
     v
 end
 
-function point_is_within_closest(p::Point, b::Beacon; ignorebeacon=false)::Bool
-    distance(p, b.sensor) <= b.dist && (ignorebeacon || p != b.beacon)
+function point_is_within_closest(p::Point, b::Beacon)::Bool
+    distance(p, b.sensor) <= b.dist && p != b.beacon
+end
+
+function point_is_beacon(p::Point, bs::Vector{Beacon})::Bool
+    any(b -> b.beacon == p, bs)
 end
 
 function point_is_covered(p::Point, bs::Vector{Beacon}; ignorebeacon=false)::Bool
-    any(b -> point_is_within_closest(p, b; ignorebeacon=ignorebeacon), bs)
+    any(b -> point_is_within_closest(p, b), bs)
 end
 
 function n_covered_points(bs::Vector{Beacon}, y::Int)::Int
@@ -50,24 +54,43 @@
     count
 end
 
-function find_distress_beacon(bs::Vector{Beacon}, minc=0, maxc=20)::Vector{Point}
-    reachable = Set{Point}();
+function find_distress_beacon(bs::Vector{Beacon}, minc=0, maxc=20)::Set{Point}
+    # Check borders of sensor's coverage area
+    v = Set{Point}();
+    isvalid(p) = p.x >= minc && p.x <= maxc && p.y >= minc && p.y <= maxc;
     for b in bs
         @show b
         for x = b.sensor.x-b.dist:b.sensor.x+b.dist
-            for y = b.sensor.y-abs(b.dist-abs(x-b.sensor.x)):b.sensor.y+abs(b.dist-abs(x-b.sensor.x))
-                push!(reachable, Point(x,y));
+            for dir = [-1, 1]
+                y = dir*b.sensor.y + abs(b.dist - abs(b.sensor.x-x));
+                p = Point(x+sign(x-b.sensor.x), y);
+                if isvalid(p) && !point_is_covered(p, bs) && !point_is_beacon(p, bs)
+                    push!(v, p);
+                    continue;
+                end
+                if x == b.sensor.x
+                    p = Point(x, y+dir);
+                    if isvalid(p) && !point_is_covered(p, bs) && !point_is_beacon(p, bs)
+                        push!(v, p);
+                        continue;
+                    end
+                end
             end
         end
     end
-    possible = [Point(x, y) for x = minc:maxc for y = minc:maxc if !in(Point(x,y), reachable)];
-    possible
+    v
+end
+
+function tuning_frequency(p::Point)::Int
+    p.x*4000000+p.y
 end
 
 bs = parse_lines("15/input.txt");
 println(n_covered_points(bs, 2000000));
-#println(find_distress_beacon(bs, 0, 4000000));
+db = find_distress_beacon(bs, 0, 4000000);
+@show (db, map(tuning_frequency, collect(db)))
 
 bs = parse_lines("15/test_input.txt");
 println(n_covered_points(bs, 10));
-println(find_distress_beacon(bs));
+db = find_distress_beacon(bs);
+@show (db, map(tuning_frequency, collect(db)))