From 13e154a0c294b309fd57ac9b512c61f72522e5a2 Mon Sep 17 00:00:00 2001 From: Adam Millerchip Date: Wed, 30 Nov 2022 19:16:45 +0900 Subject: [PATCH] 2021 day 16 part 2 --- 2021/day16.exs | 39 ++++++++++++++++++++++++++++----------- 1 file changed, 28 insertions(+), 11 deletions(-) diff --git a/2021/day16.exs b/2021/day16.exs index b0b974c..f457d32 100644 --- a/2021/day16.exs +++ b/2021/day16.exs @@ -4,21 +4,17 @@ defmodule Day16 do version_sum end - def part2(_input) do - :ok - end - @literal_type 4 @literal_part 1 @literal_end 0 @total_length_type 0 @sub_packets_length_type 1 - def decode_packet(<>, count, version_sum) do + defp decode_packet(<>, count, version_sum) do decode_literal(rest, <<>>, count + 6, version_sum + version) end - def decode_packet(<>, count, version_sum) do + defp decode_packet(<>, count, version_sum) do {sub_packets, rest, count, version_sum} = case rest do <<@total_length_type::1, length::15, rest::bits>> -> @@ -45,21 +41,21 @@ defmodule Day16 do {{:operator, operator_type, sub_packets}, rest, count, version_sum} end - def decode_literal(<<@literal_part::1, group::bits-4, rest::bits>>, acc, count, version_sum) do + defp decode_literal(<<@literal_part::1, group::bits-4, rest::bits>>, acc, count, version_sum) do decode_literal(rest, <>, count + 5, version_sum) end - def decode_literal(<<@literal_end::1, group::bits-4, rest::bits>>, acc, count, version_sum) do + defp decode_literal(<<@literal_end::1, group::bits-4, rest::bits>>, acc, count, version_sum) do literal_binary = <> <> = literal_binary {{:literal, literal}, rest, count + 5, version_sum} end - def decode_sub_packets_by(_method, 0, decoded_packets, bits, count, version_sum) do + defp decode_sub_packets_by(_method, 0, decoded_packets, bits, count, version_sum) do {Enum.reverse(decoded_packets), bits, count, version_sum} end - def decode_sub_packets_by(method, remaining, decoded_packets, bits, count, version_sum) do + defp decode_sub_packets_by(method, remaining, decoded_packets, bits, count, version_sum) do {decoded_packet, rest, packet_size, version_sum} = decode_packet(bits, 0, version_sum) remaining = @@ -78,6 +74,27 @@ defmodule Day16 do ) end + def part2(input) do + {packet, _rest, _count, _version_sum} = decode_packet(input, 0, 0) + evaluate(packet) + end + + defp evaluate({:literal, literal}), do: literal + + defp evaluate({:operator, op, args}) do + args + |> Enum.map(&evaluate/1) + |> calculate(op) + end + + defp calculate(args, 0), do: Enum.sum(args) + defp calculate(args, 1), do: Enum.reduce(args, &Kernel.*/2) + defp calculate(args, 2), do: Enum.min(args) + defp calculate(args, 3), do: Enum.max(args) + defp calculate([a, b], 5), do: if(a > b, do: 1, else: 0) + defp calculate([a, b], 6), do: if(a < b, do: 1, else: 0) + defp calculate([a, b], 7), do: if(a == b, do: 1, else: 0) + def input do with [input_filename] <- System.argv(), {:ok, input} <- File.read(input_filename) do @@ -120,4 +137,4 @@ defmodule Day16 do end end -# Day16.run() +Day16.run()