You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

44 lines
1.6 KiB

-module(day13).
-export([solve/1]).
-compile(export_all).
solve(Input) ->
PacketPairs = binary:split(Input, <<"\n\n">>, [global, trim_all]),
Part1 = part1(PacketPairs),
{Part1, none}.
part1(PacketPairs) -> part1(PacketPairs, {1, 0}).
part1([], {_Index, Score}) -> Score;
part1([PacketPair|Rest], {Index, Score}) ->
[LeftStr, RightStr] = binary:split(PacketPair, <<$\n>>, [trim_all]),
Left = parse_packet(LeftStr),
Right = parse_packet(RightStr),
NewScore = case compare(Left, Right) of
true -> Score + Index;
false -> Score
end,
part1(Rest, {Index+1, NewScore}).
compare([], []) -> undecided;
compare([], [_|_Rest]) -> true;
compare([_|_Rest], []) -> false;
compare([Left | LeftRest], [Right | RightRest]) when is_list(Left) and is_list(Right) ->
case compare(Left, Right) of
undecided -> compare(LeftRest, RightRest);
Result -> Result
end;
compare([Left | _] = Lefts, [Right | RightRest]) when is_list(Left) and is_integer(Right) ->
compare(Lefts, [[Right] | RightRest]);
compare([Left | LeftRest], [Right | _] = Rights) when is_integer(Left) and is_list(Right) ->
compare([[Left] | LeftRest], Rights);
compare([Value | Left], [Value | Right]) when is_integer(Value) -> compare(Left, Right);
compare([Left|_], [Right|_]) when is_integer(Left) and is_integer(Right) -> Left < Right;
compare(Left, Right) when is_integer(Left) and is_integer(Right) -> Left < Right.
parse_packet(Packet) ->
{ok, Tokens, _EndLine} = erl_scan:string(unicode:characters_to_list([Packet,$.])),
{ok, Parsed} = erl_parse:parse_term(Tokens),
Parsed.