re-organise repo
This commit is contained in:
100
2021/day12/day12.erl
Normal file
100
2021/day12/day12.erl
Normal file
@@ -0,0 +1,100 @@
|
||||
%% to compile: erlc day3A.erl
|
||||
%% to run: erl -noshell -s day5 solve
|
||||
%%
|
||||
-module(day12).
|
||||
|
||||
-export ([solve/0, solve/1, solve/2]).
|
||||
-export ([read_input/0]).
|
||||
|
||||
solve() ->
|
||||
solve(['1']),
|
||||
solve(['2']),
|
||||
init:stop().
|
||||
|
||||
solve(A) ->
|
||||
solve(A, read_input()).
|
||||
|
||||
solve(['1'], D) ->
|
||||
io:format("The solution to ~p puzzle1 is: ~p~n", [?MODULE, solve(1, D)]);
|
||||
solve(1, D) ->
|
||||
solution1(D);
|
||||
solve(['2'], D) ->
|
||||
io:format("The solution to ~p puzzle2 is: ~p~n", [?MODULE, solve(2, D)]);
|
||||
solve(2, D) ->
|
||||
solution2(D).
|
||||
|
||||
read_input() ->
|
||||
{ok, IO} = file:open("input.txt", 'read'),
|
||||
Data = read_input(IO),
|
||||
file:close(IO),
|
||||
Data.
|
||||
|
||||
read_input(IO) ->
|
||||
read_input(IO, []).
|
||||
|
||||
read_input(IO, Input) ->
|
||||
case read_line(IO) of
|
||||
'eof' -> Input;
|
||||
Line -> read_input(IO, Input ++ [Line])
|
||||
end.
|
||||
|
||||
read_line(IO) ->
|
||||
case file:read_line(IO) of
|
||||
'eof' -> 'eof';
|
||||
{ok, Line} -> parse_line(Line)
|
||||
end.
|
||||
|
||||
parse_line(Line) ->
|
||||
[Cave1, Cave2] = string:tokens(Line, "-\n"),
|
||||
{Cave1, Cave2}.
|
||||
|
||||
solution1(Caves) ->
|
||||
CaveMap = insert(Caves),
|
||||
count_paths("start", #{}, 'some', CaveMap).
|
||||
|
||||
solution2(Caves) ->
|
||||
CaveMap = insert(Caves),
|
||||
count_paths("start", #{}, 'none', CaveMap).
|
||||
|
||||
|
||||
insert(Caves) -> insert(Caves, maps:new()).
|
||||
|
||||
insert([], CaveMap) -> CaveMap;
|
||||
insert([{Cave1, Cave2}|Rest], CaveMap) ->
|
||||
NewMap =
|
||||
case maps:is_key(Cave1, CaveMap) of
|
||||
'false' -> maps:put(Cave1, [Cave2], CaveMap);
|
||||
'true' -> maps:put(Cave1, [Cave2|maps:get(Cave1, CaveMap)], CaveMap)
|
||||
end,
|
||||
NewMap2 =
|
||||
case maps:is_key(Cave2, NewMap) of
|
||||
'false' -> maps:put(Cave2, [Cave1], NewMap);
|
||||
'true' -> maps:put(Cave2, [Cave1|maps:get(Cave2, CaveMap)], NewMap)
|
||||
end,
|
||||
insert(Rest, NewMap2).
|
||||
|
||||
visit_vertex(Name, Visited, VisitedTwice, Graph) ->
|
||||
NewVisited =
|
||||
case hd(Name) >= $a of
|
||||
true -> Visited#{Name => true};
|
||||
false -> Visited
|
||||
end,
|
||||
#{Name := Neighbours} = Graph,
|
||||
lists:sum([count_paths(N, NewVisited, VisitedTwice, Graph) || N <- Neighbours]).
|
||||
|
||||
count_paths("end", _, _, _) ->
|
||||
% We have found an entire path through the graph.
|
||||
1;
|
||||
count_paths("start", Visited, _, _) when map_size(Visited) > 0 ->
|
||||
% We cannot visit the start cave more than once.
|
||||
0;
|
||||
count_paths(Name, Visited, VisitedTwice, Graph) when hd(Name) >= $a andalso is_map_key(Name, Visited) ->
|
||||
% We can visit only one small cave twice.
|
||||
case VisitedTwice of
|
||||
'none' -> visit_vertex(Name, Visited, Name, Graph);
|
||||
_ -> 0
|
||||
end;
|
||||
count_paths(Name, Visited, VisitedTwice, Graph) ->
|
||||
% Small caves can only be visited once, but large caves may be visited any
|
||||
% number of times.
|
||||
visit_vertex(Name, Visited, VisitedTwice, Graph).
|
||||
Reference in New Issue
Block a user