%% to compile: erlc day3A.erl
%% to run: erl -noshell -s day5 solve
%%
-module(day17).

-export ([solve/0, solve/1, solve/2]).
-compile ([export_all]).

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).

solution1({X,Y}) ->
    Xs = find_x(X),
    Ys = find_y(Y),
    {T, X1, Y1} = lists:max([{Key, X1, proplists:get_value(Key,Ys)} || {Key, X1} <- Xs, lists:keysearch(Key, 1, Ys) /= false]),
    y_max(T,Y1,0).
    
solution2({X,Y}) ->
    Xs = find_x(X),
    Ys = find_y(Y),
    length(lists:usort([{X,Y} || {Ty, Y} <- Ys, {T,X} <- lists:filter(fun({T,X}) -> T == Ty end, Xs)])).

read_input() ->
    {{124,174},{-123, -86}}.
%%    {{20,30},{-10, -5}}.

find_x({Xmin, Xmax}) ->
    [ {T, Xstart}  || Xstart <- lists:seq(0,400), T <- lists:seq(1,1000),  x(Xstart, T) >= Xmin, x(Xstart, T) =< Xmax ].

find_y({Ymin, Ymax}) ->
    [ {T, Ystart}  || Ystart <- lists:seq(-400,400), T <- lists:seq(1,1000), y(Ystart, T) >= Ymin, y(Ystart, T) =< Ymax ].

x(Xstart, T) ->
    Last = 
    case (Xstart - T + 1) of
        L when L < 0 -> 0;
        L -> L
    end,
    (Xstart - Last + 1) * (Xstart + Last) div 2.
   
y(Ystart, T) ->
    Last = (Ystart - T + 1),
    (Ystart - Last + 1) * (Ystart + Last) div 2.

y_max(0, _, Ymax) -> Ymax;
y_max(T, Y, Ymax)  ->
    NewY = y(Y, T),
    NewMax = 
    case  NewY of
        M when M > Ymax -> M;
        _ -> Ymax
    end,
    y_max(T-1, Y, NewMax).
    