This topic is about Day 13 of the Advent of Code 2022 .
Sorry for delaying this post.
Link to our leaderboard:
https://adventofcode.com/2022/leaderboard/private/view/370884
The entry code is:
370884-a6a71927
Good luck!
This topic is about Day 13 of the Advent of Code 2022 .
Sorry for delaying this post.
Link to our leaderboard:
https://adventofcode.com/2022/leaderboard/private/view/370884
The entry code is:
370884-a6a71927
Good luck!
Neat challenge, also got into top 1000 today (721/618):
main(File) ->
{ok, RawData} = file:read_file(File),
Data = [ [ parse_term(T) || T <- binary:split(X, <<"\n">>) ]
|| X <- binary:split(RawData, <<"\n\n">>, [global, trim]) ],
io:format("part 1: ~p~n", [solve1(Data)]),
io:format("part 2: ~p~n", [solve2(Data)]).
parse_term(Binary) ->
{ok, Tokens, _} = erl_scan:string(binary_to_list(<<Binary/binary, ".">>)),
{ok, Term} = erl_parse:parse_term(Tokens),
Term.
enum(List) ->
lists:zip(lists:seq(1, length(List)), List).
solve1(Data) ->
lists:sum([ N || {N, [A, B]} <- enum(Data), compare(A, B) ]).
solve2(Data) ->
Dividers = [[[2]], [[6]]],
Result = enum(lists:sort(fun compare/2, Dividers ++ [ Y || X <- Data, Y <- X ])),
[F1, F2] = [ N || {N, V} <- Result, lists:member(V, Dividers) ],
F1 * F2.
compare([], [_|_]) -> true;
compare([_|_], []) -> false;
compare([], []) -> ok;
compare([A|_ ], [B|_ ]) when is_integer(A), is_integer(B), A > B -> false;
compare([A|_ ], [B|_ ]) when is_integer(A), is_integer(B), A < B -> true;
compare([A|Ax], [B|Bx]) when is_integer(A), is_integer(B), A =:= B -> compare(Ax, Bx);
compare(A, B) when is_integer(A), is_list(B) -> compare([A], B);
compare(A, B) when is_list(A), is_integer(B) -> compare(A, [B]);
compare([A|Ax], [B|Bx]) when is_list(A); is_list(B) ->
case compare(A, B) of
ok -> compare(Ax, Bx);
Other -> Other
end.
I did it the same way. Though in Elixir. But it took me awhile to understand the sorting mechanism here. Started questioning my reading skills.
I confess to stealing your term parsing code.
Not often I can offer an improvement, but in this case you can use lists:enumerate/1
in place of your enum/1
function. My belated part 1 solution was otherwise pretty similar. My compare/2
implementation was:
compare(L, L) ->
continue;
compare(L, R) when is_integer(L) andalso is_integer(R) -> L < R;
compare([HL | TL], [HR | TR]) ->
case compare(HL, HR) of
continue -> compare(TL, TR);
Result -> Result
end;
compare(L, R) when is_list(L) andalso is_integer(R) -> compare(L, [R]);
compare(L, R) when is_integer(L) andalso is_list(R) -> compare([L], R);
compare(L, []) when is_list(L) -> false;
compare([], R) when is_list(R) -> true.
I copied my enum from my previous year solution since lists: enumerate
didn’t exist back then