From 3277893cfabf151510aee08b5b6b488e92efea11 Mon Sep 17 00:00:00 2001 From: Shanti Chellaram Date: Mon, 19 Dec 2022 17:34:38 +0900 Subject: [PATCH] Day 15-2 --- day15.erl | 33 ++++++++++++++++++++++++++++++--- 1 file changed, 30 insertions(+), 3 deletions(-) diff --git a/day15.erl b/day15.erl index a48c2cd..3be0dfb 100644 --- a/day15.erl +++ b/day15.erl @@ -3,12 +3,29 @@ -export([solve/1]). solve(Input) -> - {part1(Input), none}. + {part1(Input), part2(Input)}. part1(Input) -> Sensors = parse_sensors(Input), Ranges = get_row(Sensors, 2000000), - sum_ranges(Ranges). + BeaconlessRanges = remove_beacons(Sensors, 2000000, Ranges), + sum_ranges(BeaconlessRanges). + +part2(Input) -> + Sensors = parse_sensors(Input), + {Sensors, [Answer]} = for(0, 4000000, fun check_row_for_gaps/2, {Sensors, []}), + Answer. + +check_row_for_gaps(Row, {Sensors, Acc}) -> + case rset_remove_after(4000001, rset_remove_before(-1, get_row(Sensors, Row))) of + [{_X, _Y}] -> {Sensors, Acc}; + [{0, NMinusOne}, {NPlusOne, 4000000}] when NMinusOne + 2 == NPlusOne -> {Sensors, [tuning_frequency(NMinusOne+1, Row)|Acc]} + end. + +tuning_frequency(X, Y) -> X * 4000000 + Y. + +for(End, End, Fun, Acc) -> Fun(End, Acc); +for(Start, End, Fun, Acc) -> for(Start+1, End, Fun, Fun(Start, Acc)). parse_sensors(Input) -> lists:map(fun parse_sensor/1, binary:split(Input, <<$\n>>, [global, trim_all])). @@ -17,7 +34,7 @@ parse_sensor(Line) -> {{SensorX, SensorY}, {BeaconX, BeaconY}}. get_row(Sensors, Row) -> - remove_beacons(Sensors, Row, get_row(Sensors, Row, rset_new())). + get_row(Sensors, Row, rset_new()). remove_beacons([], _Row, Set) -> Set; remove_beacons([{_, {BeaconX, Row}}|Rest], Row, Set) -> remove_beacons(Rest, Row, rset_remove1(BeaconX, Set)); @@ -60,3 +77,13 @@ rset_remove1(Point, [{Point, Point} | Rest]) -> Rest; rset_remove1(Point, [{Point, End} | Rest]) -> [{Point+1, End} | Rest]; rset_remove1(Point, [{Start, Point} | Rest]) -> [{Start, Point-1} | Rest]; rset_remove1(Point, [{Start, End} | Rest]) -> [{Start, Point-1}, {Point+1, End} | Rest]. + +rset_remove_before(_Point, []) -> []; +rset_remove_before(Point, [{_, End}|Rest]) when Point >= End -> rset_remove_before(Point, Rest); +rset_remove_before(Point, [{Start, _}|_] = List) when Point < Start -> List; +rset_remove_before(Point, [{_, End}|Rest]) -> [{Point+1, End}|Rest]. + +rset_remove_after(_Point, []) -> []; +rset_remove_after(Point, [{Start, _}|_]) when Point =< Start -> []; +rset_remove_after(Point, [{_, End}=Node | Rest]) when Point > End -> [Node|rset_remove_after(Point, Rest)]; +rset_remove_after(Point, [{Start, _End}|_]) -> [{Start, Point-1}].