view 15/15.jl @ 25:c5879c425b94

day 15 part 1
author Lewin Bormann <lbo@spheniscida.de>
date Sat, 17 Dec 2022 12:33:38 +0100
parents
children 7db9666c6c77
line wrap: on
line source


using ParserCombinator

const Line = E"Sensor at x=" + PInt64() + E", y=" + PInt64() + E": closest beacon is at x=" + PInt64() + E", y=" + PInt64() + Eos();

struct Point
    x::Int
    y::Int
end

function distance(p::Point, q::Point)::Int
    abs(p.x-q.x) + abs(p.y-q.y)
end

struct Beacon
    sensor::Point
    beacon::Point
    dist::Int
end

function parse_line(s::String)::Beacon
    es = parse_one(s, Line);
    p, q = Point(es[1]::Int, es[2]::Int), Point(es[3]::Int, es[4]::Int)
    Beacon(p, q, distance(p, q))
end

function parse_lines(f::String)::Vector{Beacon}
    v = Vector{Beacon}();
    open(f; read=true) do fh
        for l in eachline(fh)
            push!(v, parse_line(l));
        end
    end
    v
end

function point_is_within_closest(p::Point, b::Beacon)::Bool
    distance(p, b.sensor) <= b.dist && p != b.beacon
end

function point_is_covered(p::Point, bs::Vector{Beacon})::Bool
    any(b -> point_is_within_closest(p, b), bs)
end

function n_covered_points(bs::Vector{Beacon}, y::Int)::Int
    minx = minimum(min(b.sensor.x, b.beacon.x)-b.dist for b in bs);
    maxx = maximum(max(b.sensor.x, b.beacon.x)+b.dist for b in bs);

    count = sum(point_is_covered(Point(x, y), bs) for x = minx:maxx);
    count
end

println(" === PART 1 === ");
bs = parse_lines("15/input.txt");
println(n_covered_points(bs, 2000000));

bs = parse_lines("15/test_input.txt");
println(n_covered_points(bs, 10));