diff --git a/day16/Project.toml b/day16/Project.toml new file mode 100644 index 0000000..7c93416 --- /dev/null +++ b/day16/Project.toml @@ -0,0 +1,4 @@ +name = "day16" +uuid = "f387bcc2-ba0a-4663-aa22-1bcc9c8680c1" +authors = ["HeNine "] +version = "0.1.0" diff --git a/day16/data/case00.txt b/day16/data/case00.txt new file mode 100644 index 0000000..d4de4d5 --- /dev/null +++ b/day16/data/case00.txt @@ -0,0 +1 @@ +8A004A801A8002F478 \ No newline at end of file diff --git a/day16/data/case01.txt b/day16/data/case01.txt new file mode 100644 index 0000000..bbb3a63 --- /dev/null +++ b/day16/data/case01.txt @@ -0,0 +1 @@ +620080001611562C8802118E34 \ No newline at end of file diff --git a/day16/data/case02.txt b/day16/data/case02.txt new file mode 100644 index 0000000..1276895 --- /dev/null +++ b/day16/data/case02.txt @@ -0,0 +1 @@ +C0015000016115A2E0802F182340 \ No newline at end of file diff --git a/day16/data/case03.txt b/day16/data/case03.txt new file mode 100644 index 0000000..95d155f --- /dev/null +++ b/day16/data/case03.txt @@ -0,0 +1 @@ +A0016C880162017C3686B18A3D4780 \ No newline at end of file diff --git a/day16/data/case04.txt b/day16/data/case04.txt new file mode 100644 index 0000000..ac6d7b8 --- /dev/null +++ b/day16/data/case04.txt @@ -0,0 +1 @@ +60552F100693298A9EF0039D24B129BA56D67282E600A4B5857002439CE580E5E5AEF67803600D2E294B2FCE8AC489BAEF37FEACB31A678548034EA0086253B183F4F6BDDE864B13CBCFBC4C10066508E3F4B4B9965300470026E92DC2960691F7F3AB32CBE834C01A9B7A933E9D241003A520DF316647002E57C1331DFCE16A249802DA009CAD2117993CD2A253B33C8BA00277180390F60E45D30062354598AA4008641A8710FCC01492FB75004850EE5210ACEF68DE2A327B12500327D848028ED0046661A209986896041802DA0098002131621842300043E3C4168B12BCB6835C00B6033F480C493003C40080029F1400B70039808AC30024C009500208064C601674804E870025003AA400BED8024900066272D7A7F56A8FB0044B272B7C0E6F2392E3460094FAA5002512957B98717004A4779DAECC7E9188AB008B93B7B86CB5E47B2B48D7CAD3328FB76B40465243C8018F49CA561C979C182723D769642200412756271FC80460A00CC0401D8211A2270803D10A1645B947B3004A4BA55801494BC330A5BB6E28CCE60BE6012CB2A4A854A13CD34880572523898C7EDE1A9FA7EED53F1F38CD418080461B00440010A845152360803F0FA38C7798413005E4FB102D004E6492649CC017F004A448A44826AB9BFAB5E0AA8053306B0CE4D324BB2149ADDA2904028600021909E0AC7F0004221FC36826200FC3C8EB10940109DED1960CCE9A1008C731CB4FD0B8BD004872BC8C3A432BC8C3A4240231CF1C78028200F41485F100001098EB1F234900505224328612AF33A97367EA00CC4585F315073004E4C2B003530004363847889E200C45985F140C010A005565FD3F06C249F9E3BC8280804B234CA3C962E1F1C64ADED77D10C3002669A0C0109FB47D9EC58BC01391873141197DCBCEA401E2CE80D0052331E95F373798F4AF9B998802D3B64C9AB6617080 \ No newline at end of file diff --git a/day16/data/case05.txt b/day16/data/case05.txt new file mode 100644 index 0000000..42b305e --- /dev/null +++ b/day16/data/case05.txt @@ -0,0 +1 @@ +C200B40A82 \ No newline at end of file diff --git a/day16/data/case06.txt b/day16/data/case06.txt new file mode 100644 index 0000000..726b25a --- /dev/null +++ b/day16/data/case06.txt @@ -0,0 +1 @@ +04005AC33890 \ No newline at end of file diff --git a/day16/data/case07.txt b/day16/data/case07.txt new file mode 100644 index 0000000..6638168 --- /dev/null +++ b/day16/data/case07.txt @@ -0,0 +1 @@ +880086C3E88112 \ No newline at end of file diff --git a/day16/data/case08.txt b/day16/data/case08.txt new file mode 100644 index 0000000..87ec237 --- /dev/null +++ b/day16/data/case08.txt @@ -0,0 +1 @@ +CE00C43D881120 \ No newline at end of file diff --git a/day16/data/case09.txt b/day16/data/case09.txt new file mode 100644 index 0000000..c87dfc5 --- /dev/null +++ b/day16/data/case09.txt @@ -0,0 +1 @@ +D8005AC2A8F0 \ No newline at end of file diff --git a/day16/data/case10.txt b/day16/data/case10.txt new file mode 100644 index 0000000..5ecb3f8 --- /dev/null +++ b/day16/data/case10.txt @@ -0,0 +1 @@ +F600BC2D8F \ No newline at end of file diff --git a/day16/data/case11.txt b/day16/data/case11.txt new file mode 100644 index 0000000..ce082eb --- /dev/null +++ b/day16/data/case11.txt @@ -0,0 +1 @@ +9C005AC2F8F0 \ No newline at end of file diff --git a/day16/data/case12.txt b/day16/data/case12.txt new file mode 100644 index 0000000..995ba6e --- /dev/null +++ b/day16/data/case12.txt @@ -0,0 +1 @@ +9C0141080250320F1802104A08 \ No newline at end of file diff --git a/day16/src/day16.jl b/day16/src/day16.jl new file mode 100644 index 0000000..d3d0320 --- /dev/null +++ b/day16/src/day16.jl @@ -0,0 +1,181 @@ +include("../../AoC2021.jl") + +## + +hexmap = Dict( + '0' => BitVector([0, 0, 0, 0]), + '1' => BitVector([0, 0, 0, 1]), + '2' => BitVector([0, 0, 1, 0]), + '3' => BitVector([0, 0, 1, 1]), + '4' => BitVector([0, 1, 0, 0]), + '5' => BitVector([0, 1, 0, 1]), + '6' => BitVector([0, 1, 1, 0]), + '7' => BitVector([0, 1, 1, 1]), + '8' => BitVector([1, 0, 0, 0]), + '9' => BitVector([1, 0, 0, 1]), + 'A' => BitVector([1, 0, 1, 0]), + 'B' => BitVector([1, 0, 1, 1]), + 'C' => BitVector([1, 1, 0, 0]), + 'D' => BitVector([1, 1, 0, 1]), + 'E' => BitVector([1, 1, 1, 0]), + 'F' => BitVector([1, 1, 1, 1]) +) + +function parsehex(string::String) + (collect(string) .|> + x -> hexmap[x]) |> + (x -> vcat(x...)) +end + +## + +abstract type Packet end + +struct LiteralValue <: Packet + version::Int + value::Int +end + +function LiteralValue(data::BitVector) + version = splice!(data, 1:3)' * 2 .^ collect(2:-1:0) + splice!(data, 1:3) + + value = 0 + + section = splice!(data, 1:5) + while true + value <<= 4 + value += section[2:end]' * 2 .^ collect(3:-1:0) + + if section[1] == 0 + break + else + section = splice!(data, 1:5) + end + end + + (LiteralValue(version, value), data) +end + +struct Operator <: Packet + version::Int + type::Int + subpackets::Vector{Packet} +end + +function Operator(data::BitVector) + version = splice!(data, 1:3)' * 2 .^ collect(2:-1:0) + + type = splice!(data, 1:3)' * 2 .^ collect(2:-1:0) + + subtype = splice!(data, 1) + + if subtype == 0 + subpacketdatalength = splice!(data, 1:15)' * 2 .^ collect(14:-1:0) + subpacketdata = splice!(data, 1:subpacketdatalength) + + subpackets = [] + while length(subpacketdata) != 0 + (subpacket, subpacketdata) = parsepackets(subpacketdata) + push!(subpackets, subpacket) + end + else + subpacketcount = splice!(data, 1:11)' * 2 .^ collect(10:-1:0) + + subpackets = [] + for p ∈ 1:subpacketcount + (subpacket, data) = parsepackets(data) + + push!(subpackets, subpacket) + end + end + + (Operator(version, type, subpackets), data) +end + +evaluate(literal::LiteralValue) = literal.value + +function evaluate(operator::Operator) + if operator.type == 0 + sum(evaluate.(operator.subpackets)) + elseif operator.type == 1 + prod(evaluate.(operator.subpackets)) + elseif operator.type == 2 + minimum(evaluate.(operator.subpackets)) + elseif operator.type == 3 + maximum(evaluate.(operator.subpackets)) + elseif operator.type == 5 + evaluate(operator.subpackets[1]) > evaluate(operator.subpackets[2]) + elseif operator.type == 6 + evaluate(operator.subpackets[1]) < evaluate(operator.subpackets[2]) + elseif operator.type == 7 + evaluate(operator.subpackets[1]) == evaluate(operator.subpackets[2]) + end +end + +## + +function parsepackets(data::BitVector) + type = data[4:6]' * 2 .^ collect(2:-1:0) + + if type == 4 + LiteralValue(data) + else + Operator(data) + end +end + +sumversions(literal::LiteralValue) = literal.version + +sumversions(operator::Operator) = operator.version + sum(sumversions.(operator.subpackets)) + +## + +function task0(file) + data = parsehex(readline(file)) + + (packet, _) = parsepackets(data) + + sumversions(packet) +end + +## + +verify(16, 1, 0, 16) +verify(16, 1, 1, 12) +verify(16, 1, 2, 23) +verify(16, 1, 3, 31) +verify(16, 1, 4, 877) + +## + +parsehex("D2FE28") |> +LiteralValue + +parsehex("38006F45291200") |> +Operator + +parsehex("EE00D40C823060") |> +Operator + +## + +function task1(file) + data = parsehex(readline(file)) + + (packet, _) = parsepackets(data) + + evaluate(packet) +end + +## + +verify(16, 2, 5, 3) +verify(16, 2, 6, 54) +verify(16, 2, 7, 7) +verify(16, 2, 8, 9) +verify(16, 2, 9, 1) +verify(16, 2, 10, 0) +verify(16, 2, 11, 0) +verify(16, 2, 12, 1) +verify(16, 2, 4, 194435634456) \ No newline at end of file