# Advent of Code 2022 Day 13 - Discussion

This topic is about Day 13 of the Advent of Code 2022 .

Sorry for delaying this post.

The entry code is:
`370884-a6a71927`

Good luck!

1 Like

Neat challenge, also got into top 1000 today (721/618):

``````main(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 = [[], []],
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.
``````
3 Likes

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.

2 Likes

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.
``````
2 Likes

I copied my enum from my previous year solution since `lists: enumerate` didn’t exist back then 2 Likes