Browse Source

Day 15-2

trunk
Shanti Chellaram 3 years ago
parent
commit
3277893cfa
  1. 33
      day15.erl

33
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}].
Loading…
Cancel
Save