Mercurial > lbo > hg > aoc22
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)))