commit
This commit is contained in:
179
day16/day16.erl
Normal file
179
day16/day16.erl
Normal file
@@ -0,0 +1,179 @@
|
||||
%% to compile: erlc day3A.erl
|
||||
%% to run: erl -noshell -s day5 solve
|
||||
%%
|
||||
-module(day16).
|
||||
|
||||
-compile(export_all).
|
||||
|
||||
-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'),
|
||||
{ok, Line} = file:read_line(IO),
|
||||
file:close(IO),
|
||||
hexstr_to_bin(string:strip(Line, 'both', $\n)).
|
||||
|
||||
hexstr_to_bin(S) ->
|
||||
hexstr_to_bin(S, []).
|
||||
hexstr_to_bin([], Acc) ->
|
||||
list_to_binary(lists:reverse(Acc));
|
||||
hexstr_to_bin([X,Y|T], Acc) ->
|
||||
{ok, [V], []} = io_lib:fread("~16u", [X,Y]),
|
||||
hexstr_to_bin(T, [V | Acc]);
|
||||
hexstr_to_bin([X|T], Acc) ->
|
||||
{ok, [V], []} = io_lib:fread("~16u", lists:flatten([X,"0"])),
|
||||
hexstr_to_bin(T, [V | Acc]).
|
||||
|
||||
bin_to_hexstr(Bin) ->
|
||||
lists:flatten([io_lib:format("~2.16.0B", [X]) ||
|
||||
X <- binary_to_list(Bin)]).
|
||||
|
||||
solution1(Input) ->
|
||||
D = unpack(Input, [], not is_zero_bitstring(Input)),
|
||||
io:format("Pkt: ~p~n", [D]),
|
||||
count_versions(D, 0).
|
||||
|
||||
solution2(Input) ->
|
||||
D = unpack(Input, [], not is_zero_bitstring(Input)),
|
||||
io:format("Pkt: ~p~n", [D]),
|
||||
calc(D).
|
||||
|
||||
calc({_,literal, V}) ->
|
||||
V;
|
||||
calc({_,Op, V}) ->
|
||||
?MODULE:Op(V);
|
||||
calc([{_,Op, V}]) ->
|
||||
?MODULE:Op(V).
|
||||
|
||||
sum(Args) ->
|
||||
io:format("sum: ~p~n", [Args]),
|
||||
lists:foldl(fun(X, Acc) -> calc(X) + Acc end, 0, Args).
|
||||
|
||||
product(Args) ->
|
||||
io:format("product: ~p~n", [Args]),
|
||||
lists:foldl(fun(X, Acc) -> calc(X) * Acc end, 1, Args).
|
||||
|
||||
min(Args) ->
|
||||
io:format("min: ~p~n", [Args]),
|
||||
lists:min([calc(X) || X <- Args]).
|
||||
|
||||
max(Args) ->
|
||||
io:format("max: ~p~n", [Args]),
|
||||
lists:max([calc(X) || X <- Args]).
|
||||
|
||||
lt([A,B] = Args) ->
|
||||
io:format("lt: ~p~n", [Args]),
|
||||
case calc(A) < calc(B) of
|
||||
'true' -> 1;
|
||||
'false' -> 0
|
||||
end.
|
||||
|
||||
gt([A,B] = Args) ->
|
||||
io:format("gt: ~p~n", [Args]),
|
||||
case calc(A) > calc(B) of
|
||||
'true' -> 1;
|
||||
'false' -> 0
|
||||
end.
|
||||
|
||||
eq([A,B] = Args) ->
|
||||
io:format("eq: ~p~n", [Args]),
|
||||
case calc(A) == calc(B) of
|
||||
'true' -> 1;
|
||||
'false' -> 0
|
||||
end.
|
||||
|
||||
count_versions([{Ver, Type, Rest}|T], Acc) ->
|
||||
count_versions(T, count_versions(Rest, Acc) + Ver);
|
||||
count_versions(_, Acc) ->
|
||||
Acc.
|
||||
|
||||
is_zero_bitstring(BitString) ->
|
||||
Size = erlang:bit_size(BitString),
|
||||
<<0:Size>> =:= BitString.
|
||||
|
||||
unpack(Data, [], 'false') ->
|
||||
Data;
|
||||
unpack(Input, Acc, 'false') ->
|
||||
Acc;
|
||||
|
||||
unpack(Input, Acc, 'true') ->
|
||||
{{Ver, Type, Data}, Rest} = unpack(Input),
|
||||
io:format("unpacking data: ~p~n", [Data]),
|
||||
lists:reverse(unpack(Rest, Acc ++ [{Ver, Type, unpack(Data, [], is_bitstring(Data) andalso not is_zero_bitstring(Data))}], not is_zero_bitstring(Rest))).
|
||||
|
||||
%% Literal
|
||||
unpack(<<V:3, 4:3, Rest/bitstring>>) ->
|
||||
io:format("V:~p, T:literal~n", [V]),
|
||||
unpack_literal(V, Rest);
|
||||
|
||||
%% Operator length type id 0
|
||||
unpack(<<V:3, T:3, 0:1, Rest/bitstring>>) ->
|
||||
io:format("V:~p, T:operator I:0~n", [V]),
|
||||
unpack_operator_0(V, T, Rest);
|
||||
|
||||
%% Operator length type id 1
|
||||
unpack(<<V:3, T:3, 1:1, Rest/bitstring>>) ->
|
||||
io:format("V:~p, T:operator I:1~n", [V]),
|
||||
unpack_operator_1(V, T, Rest).
|
||||
|
||||
unpack_literal(V, Pkt) ->
|
||||
unpack_literal(V, Pkt, <<>>, 0).
|
||||
|
||||
unpack_literal(V, <<1:1, Value:4, Rest/bitstring>>, Acc, Count) ->
|
||||
unpack_literal(V, Rest, <<Acc/bitstring, Value:4>>, Count + 1);
|
||||
unpack_literal(V, <<0:1, Value:4, Rest/bitstring>>, Acc, Count) ->
|
||||
L = <<Acc/bitstring, Value:4>>,
|
||||
Size = (Count + 1) * 4,
|
||||
io:format("unpack_literal value: ~p size:~p rest:~p~n", [Value, Size, Rest]),
|
||||
<<X:(Size)>> = L,
|
||||
{{V, literal, X}, Rest}.
|
||||
|
||||
unpack_operator_0(V, T, <<Length:15, Rest0/bitstring>>) ->
|
||||
io:format("operator0 length:~p~n", [Length]),
|
||||
<<Pkt:(Length)/bitstring, Rest/bitstring>> = Rest0,
|
||||
{Rest1, Decoded} = unpack_len(Length, Rest0, []),
|
||||
{{V, operator_type(T), Decoded}, Rest1}.
|
||||
|
||||
unpack_operator_1(V, T, <<Num:11, Rest/bitstring>>) ->
|
||||
{Rest1, Decoded} = unpack_count(Num, Rest, []),
|
||||
io:format("operator1 num of packets:~p Decoded:~p, Rest:~p~n", [Num,Decoded,Rest1]),
|
||||
{{V, operator_type(T), Decoded}, Rest1}.
|
||||
|
||||
unpack_len(0, Pkt, Acc) ->
|
||||
{Pkt, Acc};
|
||||
unpack_len(Length, Pkt, Acc) ->
|
||||
{L, R} = unpack(Pkt),
|
||||
io:format("unpack_len: length:before ~p after: ~p~n", [Length, Length - bit_size(Pkt) + bit_size(R)]),
|
||||
unpack_len(Length - bit_size(Pkt) + bit_size(R), R, Acc ++ [L]).
|
||||
|
||||
unpack_count(0, Pkt, Acc) ->
|
||||
{Pkt, Acc};
|
||||
unpack_count(Num, Pkt, Acc) ->
|
||||
{L, R} = unpack(Pkt),
|
||||
unpack_count(Num - 1, R, Acc ++ [L]).
|
||||
|
||||
operator_type(0) -> 'sum';
|
||||
operator_type(1) -> 'product';
|
||||
operator_type(2) -> 'min';
|
||||
operator_type(3) -> 'max';
|
||||
operator_type(5) -> 'gt';
|
||||
operator_type(6) -> 'lt';
|
||||
operator_type(7) -> 'eq'.
|
||||
1
day16/input.txt
Normal file
1
day16/input.txt
Normal file
@@ -0,0 +1 @@
|
||||
420D50000B318100415919B24E72D6509AE67F87195A3CCC518CC01197D538C3E00BC9A349A09802D258CC16FC016100660DC4283200087C6485F1C8C015A00A5A5FB19C363F2FD8CE1B1B99DE81D00C9D3002100B58002AB5400D50038008DA2020A9C00F300248065A4016B4C00810028003D9600CA4C0084007B8400A0002AA6F68440274080331D20C4300004323CC32830200D42A85D1BE4F1C1440072E4630F2CCD624206008CC5B3E3AB00580010E8710862F0803D06E10C65000946442A631EC2EC30926A600D2A583653BE2D98BFE3820975787C600A680252AC9354FFE8CD23BE1E180253548D057002429794BD4759794BD4709AEDAFF0530043003511006E24C4685A00087C428811EE7FD8BBC1805D28C73C93262526CB36AC600DCB9649334A23900AA9257963FEF17D8028200DC608A71B80010A8D50C23E9802B37AA40EA801CD96EDA25B39593BB002A33F72D9AD959802525BCD6D36CC00D580010A86D1761F080311AE32C73500224E3BCD6D0AE5600024F92F654E5F6132B49979802129DC6593401591389CA62A4840101C9064A34499E4A1B180276008CDEFA0D37BE834F6F11B13900923E008CF6611BC65BCB2CB46B3A779D4C998A848DED30F0014288010A8451062B980311C21BC7C20042A2846782A400834916CFA5B8013374F6A33973C532F071000B565F47F15A526273BB129B6D9985680680111C728FD339BDBD8F03980230A6C0119774999A09001093E34600A60052B2B1D7EF60C958EBF7B074D7AF4928CD6BA5A40208E002F935E855AE68EE56F3ED271E6B44460084AB55002572F3289B78600A6647D1E5F6871BE5E598099006512207600BCDCBCFD23CE463678100467680D27BAE920804119DBFA96E05F00431269D255DDA528D83A577285B91BCCB4802AB95A5C9B001299793FCD24C5D600BC652523D82D3FCB56EF737F045008E0FCDC7DAE40B64F7F799F3981F2490
|
||||
Reference in New Issue
Block a user