solve 2021 day 16
This commit is contained in:
parent
9b8558c65f
commit
f478284da5
2 changed files with 103 additions and 1 deletions
|
@ -16,7 +16,7 @@
|
|||
| :-: | :-: | :-: | :-: | :-: | :-: | :-: |
|
||||
| | | | [1] | [2] | [3] | [4] |
|
||||
| [5] | [6] | [7] | [8] | [9] | [10] | [11]|
|
||||
| [12]| [13]| [14]| [15] | 16 | 17 | 18 |
|
||||
| [12]| [13]| [14]| [15] | [16] | 17 | 18 |
|
||||
| 19 | 20 | 21 | 22 | 23 | 24 | 25 |
|
||||
|
||||
<!-- links -->
|
||||
|
@ -36,3 +36,4 @@
|
|||
[13]: ./lib/2021/13.ex
|
||||
[14]: ./lib/2021/14.ex
|
||||
[15]: ./lib/2021/15.ex
|
||||
[16]: ./lib/2021/16.ex
|
||||
|
|
101
2021/lib/2021/16.ex
Normal file
101
2021/lib/2021/16.ex
Normal file
|
@ -0,0 +1,101 @@
|
|||
import AOC
|
||||
|
||||
aoc 2021, 16 do
|
||||
def to_binary_digits(?0), do: [0, 0, 0, 0]
|
||||
def to_binary_digits(?1), do: [0, 0, 0, 1]
|
||||
def to_binary_digits(?2), do: [0, 0, 1, 0]
|
||||
def to_binary_digits(?3), do: [0, 0, 1, 1]
|
||||
def to_binary_digits(n) when n in ?4..?7, do: [0 | Integer.digits(n - ?0, 2)]
|
||||
def to_binary_digits(n) when n in ?8..?9, do: Integer.digits(n - ?0, 2)
|
||||
def to_binary_digits(n) when n in ?A..?F, do: Integer.digits(n - ?A + 10, 2)
|
||||
|
||||
def input_bitstring(input_string \\ input_string()) do
|
||||
input_string
|
||||
|> String.trim()
|
||||
|> String.to_charlist()
|
||||
|> Enum.flat_map(&to_binary_digits/1)
|
||||
|> Enum.into(<<>>, &<<&1::1>>)
|
||||
end
|
||||
|
||||
def decode_packets(bits) do
|
||||
case decode_packet(bits) do
|
||||
{:ok, packet, rest} -> [packet | decode_packets(rest)]
|
||||
_ -> []
|
||||
end
|
||||
end
|
||||
|
||||
def decode_packets(bits, 0) do
|
||||
{[], bits}
|
||||
end
|
||||
|
||||
def decode_packets(bits, n) do
|
||||
{:ok, packet, rest} = decode_packet(bits)
|
||||
{packets, rest} = decode_packets(rest, n - 1)
|
||||
{[packet | packets], rest}
|
||||
end
|
||||
|
||||
def decode_packet(<<version::3, 4::3, rest::bits>>) do
|
||||
{value, rest} = decode_value(rest)
|
||||
|
||||
{:ok, [version, 4, Integer.undigits(value, 16)], rest}
|
||||
end
|
||||
|
||||
def decode_packet(<<version::3, id::3, 0::1, subpacket_length::15, rest::bits>>) do
|
||||
<<subpackets::size(subpacket_length), rest::bits>> = rest
|
||||
|
||||
{:ok, [version, id, decode_packets(<<subpackets::size(subpacket_length)>>)], rest}
|
||||
end
|
||||
|
||||
def decode_packet(<<version::3, id::3, 1::1, number_of_subpackets::11, rest::bits>>) do
|
||||
{packets, rest} = decode_packets(<<rest::bits>>, number_of_subpackets)
|
||||
|
||||
{:ok, [version, id, packets], rest}
|
||||
end
|
||||
|
||||
def decode_packet(_), do: :error
|
||||
|
||||
def decode_value(<<0::1, chunk::4, rest::bits>>), do: {[chunk], rest}
|
||||
|
||||
def decode_value(<<1::1, chunk::4, rest::bits>>) do
|
||||
{bits, rest} = decode_value(rest)
|
||||
{[chunk | bits], rest}
|
||||
end
|
||||
|
||||
def versions([version, _, subpackets]) when is_list(subpackets) do
|
||||
[version | Enum.map(subpackets, &versions/1)]
|
||||
end
|
||||
def versions([version, _, _]), do: [version]
|
||||
|
||||
|
||||
def eval([_, 4, v]), do: v
|
||||
def eval([_, op, args]) do
|
||||
case {op, Enum.map(args, &eval/1)} do
|
||||
{0 = _sum, args} -> Enum.sum(args)
|
||||
{1 = _prod, args} -> Enum.product(args)
|
||||
{2 = _min, args} -> Enum.min(args)
|
||||
{3 = _max, args} -> Enum.max(args)
|
||||
{5 = _gt, [a, b]} -> if a > b, do: 1, else: 0
|
||||
{6 = _lt, [a, b]} -> if a < b, do: 1, else: 0
|
||||
{7 = _eq, [a, b]} -> if a == b, do: 1, else: 0
|
||||
end
|
||||
end
|
||||
|
||||
def p1 do
|
||||
{:ok, packet, _rest} =
|
||||
input_bitstring()
|
||||
|> decode_packet()
|
||||
|
||||
versions(packet)
|
||||
|> List.flatten()
|
||||
|> Enum.sum()
|
||||
end
|
||||
|
||||
def p2 do
|
||||
{:ok, packet, _rest} =
|
||||
input_bitstring()
|
||||
|> decode_packet()
|
||||
|
||||
|
||||
eval(packet)
|
||||
end
|
||||
end
|
Loading…
Reference in a new issue