%% to compile: erlc day8.erl %% to run: erl -noshell -s day5 solve %% -module(day8). -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, lists:reverse([Line|Input])) end. read_line(IO) -> case file:read_line(IO) of 'eof' -> 'eof'; {ok, Line} -> parse_line(Line) end. parse_line(Line) -> [string:tokens(X, " \n") || X <- string:split(Line, "|")]. solution1(Input) -> lists:foldl(fun([_,X], Acc) -> count_unique(X, Acc) end, 0, Input). solution2([]) -> 0; solution2([[I|[O]]|T]) -> [One] = find_length(2,I), [Seven] = find_length(3,I), [Four] = find_length(4,I), [Eight] = find_length(7,I), Three = find_three(find_length(5, I), One), Nine = find_nine(find_length(6, I), Four), [Five, Two] = find_five_and_two(find_length(5, I), Three, Four), [Six, Zero] = find_six_and_zero(find_length(6, I), Nine, One), Key = [{lists:sort(One), 1},{lists:sort(Two), 2},{lists:sort(Three), 3},{lists:sort(Four), 4},{lists:sort(Five), 5},{lists:sort(Six), 6},{lists:sort(Seven), 7},{lists:sort(Eight), 8},{lists:sort(Nine), 9}, {lists:sort(Zero), 0}], [{_, A},{_,B},{_,C},{_,D}] = [lists:keyfind(lists:sort(X), 1, Key) || X <- O], (A * 1000 + B * 100 + C * 10 + D) + solution2(T). count_unique([], V) -> V; count_unique([H|T], V) -> count_unique(T, V + count(length(H))). count(2) -> 1; count(4) -> 1; count(3) -> 1; count(7) -> 1; count(_) -> 0. find_length(_Len, []) -> []; find_length(Len, [H|T]) when length(H) == Len -> [H|find_length(Len, T)]; find_length(Len, [_H|T]) -> find_length(Len, T). find_three([H|T], One) -> case length(minus(H, One)) of 3 -> H; _ -> find_three(T, One) end. find_nine([H|T], Four) -> case length(minus(H, Four)) of 2 -> H; _ -> find_nine(T, Four) end. find_five_and_two(Fives, Three, Four) -> N = lists:delete(Three, Fives), find_five_and_two(N, Four). find_five_and_two([H,T], Four) -> case length(minus(H, Four)) of 3 -> [T, H]; 2 -> [H, T] end. find_six_and_zero(Sixes, Nine, One) -> N = lists:delete(Nine, Sixes), find_six_and_zero(N, One). find_six_and_zero([H,T], One) -> case length(minus(H, One)) of 4 -> [T, H]; 5 -> [H, T] end. minus(X, Y) -> lists:foldl(fun(T, Acc) -> lists:delete(T, Acc) end, X, Y). plus(X, Y) -> lists:usort(X ++ Y).