%% to compile: erlc day3A.erl %% to run: erl -noshell -s day5 solve %% -module(day5). -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' -> lists:map(fun([{X1,Y1},{X2,Y2}]) -> case X1 > X2 orelse (X1 == X2 andalso Y1 > Y2) of 'true' -> [{X2,Y2},{X1,Y1}]; 'false' -> [{X1,Y1},{X2,Y2}] end end, 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) -> Points = string:tokens(Line, " ,->\n"), [X1, Y1, X2, Y2] = [list_to_integer(X) || X <- Points], [{X1, Y1},{X2,Y2}]. solution1(Input) -> HV = get_hor_vert(Input), Points = lists:sort( lists:flatten( [[{X,Y} || X <- lists:seq(X1, X2, case X1 =< X2 of 'true' -> 1; _ -> -1 end), Y <- lists:seq(Y1, Y2, case Y1 =< Y2 of 'true' -> 1; _ -> -1 end)] || [{X1,Y1},{X2,Y2}] <- HV] ) ), Count = count_duplicates(Points), Count. solution2(Input) -> Points = get_all_points(Input), Count = count_duplicates(lists:sort(Points)), Count. get_hor_vert(Input) -> lists:filter(fun([{X1, Y1},{X2,Y2}]) -> X1 == X2 orelse Y1 == Y2 end, Input). get_all_points(Input) -> get_all_points(Input, []). get_all_points([], Acc) -> Acc; get_all_points([[{X1,Y1},{X2,Y2}]|Rest], Acc) when X1 == X2 -> get_all_points(Rest, Acc ++ [{X1, Y} || Y <- lists:seq(Y1,Y2)]); get_all_points([[{X1,Y1},{X2,Y2}]|Rest], Acc) when Y1 == Y2 -> get_all_points(Rest, Acc ++ [{X, Y1} || X <- lists:seq(X1,X2)]); get_all_points([[{X1,Y1},{X2,Y2}]|Rest], Acc) when Y1 < Y2 -> get_all_points(Rest, Acc ++ [{X, Y1-X1+X} || X <- lists:seq(X1,X2)]); get_all_points([[{X1,Y1},{X2,Y2}]|Rest], Acc) when Y1 > Y2 -> get_all_points(Rest, Acc ++ [{X, (-1 * X) + X1 + Y1 } || X <- lists:seq(X1,X2)]). count_duplicates(Points) -> count_duplicates(Points, []). count_duplicates([], Count) -> lists:foldl(fun({X, _P}, Acc) -> case X > 1 of 'true' -> Acc + 1; _ -> Acc end end, 0, Count); count_duplicates([H|T], Count) -> case T /= [] andalso hd(T) == H of 'true' -> count_duplicate(H, T, Count, 1); _Else -> count_duplicates(T, Count ++ [{1, H}]) end. count_duplicate(H, [H|T], Count, X) -> count_duplicate(H, T, Count, X + 1); count_duplicate(H, List, Count, X) -> count_duplicates(List, Count ++ [{X, H}]).