Last active
December 7, 2024 19:08
-
-
Save joeytrapp/eb48413a58ca43827b4735748d9b76bb to your computer and use it in GitHub Desktop.
Advent of Code Day 6 Part 1 and Part 2
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-module(aoc). | |
-export([main/1]). | |
main([Path]) -> | |
{ok, Content} = file:read_file(Path), | |
{Grid, [Guard]} = parse(Content), | |
Complete = rounds(Grid, Guard), | |
Tests = sets:del_element(element(2, Guard), Complete), | |
io:format("Visited: ~p~n", [sets:size(Complete)]), | |
Loops = sets:fold(fun(Pos,Acc) -> | |
case contains_loop(obstruct(Grid,Pos), Guard) of | |
true -> Acc + 1; | |
false -> Acc | |
end | |
end, 0, Tests), | |
io:format("Loops: ~p~n", [Loops]), | |
erlang:halt(0). | |
parse(Bin) when is_binary(Bin) -> | |
Lines = binary:split(Bin, <<"\n">>, [global, trim_all]), | |
lists:foldl(fun({Y, Line}, {A0, G0}) -> | |
{Row, G1} = collect(Line, Y, 0, [], array:new(string:length(Line))), | |
{array:set(Y-1, Row, A0), lists:append(G0, G1)} | |
end, {array:new(length(Lines)), []}, lists:enumerate(Lines)). | |
collect(<<>>, _, _, G, A) -> {A, G}; | |
collect(<<C:1/binary, T/binary>>, Y, X, G0, A0) -> | |
{Symbol, G1} = case C of | |
<<".">> -> {empty, []}; | |
<<"#">> -> {obstruction, []}; | |
<<"^">> -> {empty, [{up, {X,Y}}]}; | |
<<">">> -> {empty, [{right, {X,Y}}]}; | |
<<"v">> -> {empty, [{down, {X,Y}}]}; | |
<<"<">> -> {empty, [{left, {X,Y}}]} | |
end, | |
collect(T, Y, X+1, lists:append(G0, G1), array:set(X, Symbol, A0)). | |
lookup(G0, {X,Y}) -> | |
try | |
array:get(X, array:get(Y, G0)) | |
catch | |
error:_Reason -> undefined | |
end. | |
obstruct(G0, {X,Y}) -> | |
R0 = array:get(Y, G0), | |
R1 = array:set(X, obstruction, R0), | |
array:set(Y, R1, G0). | |
move_up({X,Y}) -> {X,Y-1}. | |
move_right({X,Y}) -> {X+1,Y}. | |
move_down({X,Y}) -> {X,Y+1}. | |
move_left({X,Y}) -> {X-1,Y}. | |
move_fn(up) -> fun move_up/1; | |
move_fn(right) -> fun move_right/1; | |
move_fn(down) -> fun move_down/1; | |
move_fn(left) -> fun move_left/1. | |
turn(up) -> right; | |
turn(right) -> down; | |
turn(down) -> left; | |
turn(left) -> up. | |
rounds(Grid, Guard) -> rounds(Grid, Guard, sets:new()). | |
rounds(_, undefined, Seen) -> Seen; | |
rounds(Grid, {Dir,P0}, Seen) -> | |
Fn = move_fn(Dir), | |
P1 = Fn(P0), | |
case lookup(Grid, P1) of | |
obstruction -> rounds(Grid, {turn(Dir), P0}, Seen); | |
undefined -> rounds(Grid, undefined, sets:add_element(P0, Seen)); | |
_ -> rounds(Grid, {Dir, P1}, sets:add_element(P0, Seen)) | |
end. | |
contains_loop(Grid, Guard) -> contains_loop(Grid, Guard, sets:new()). | |
contains_loop(_, undefined, _) -> false; | |
contains_loop(Grid, {Dir,P0}, Seen) -> | |
Fn = move_fn(Dir), | |
P1 = Fn(P0), | |
case lookup(Grid, P1) of | |
undefined -> contains_loop(Grid, undefined, Seen); | |
obstruction -> contains_loop(Grid, {turn(Dir), P0}, Seen); | |
_ -> | |
case sets:is_element({Dir,P0}, Seen) of | |
true -> true; | |
false -> contains_loop(Grid, {Dir, P1}, sets:add_element({Dir,P0}, Seen)) | |
end | |
end. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment