diff --git a/2021/day16/EXAMPLE.txt b/2021/day16/EXAMPLE.txt new file mode 100644 index 0000000..3f0eda1 --- /dev/null +++ b/2021/day16/EXAMPLE.txt @@ -0,0 +1 @@ +D2FE28 diff --git a/2021/day16/EXAMPLE2.txt b/2021/day16/EXAMPLE2.txt new file mode 100644 index 0000000..a7f8f25 --- /dev/null +++ b/2021/day16/EXAMPLE2.txt @@ -0,0 +1 @@ +38006F45291200 diff --git a/2021/day16/EXAMPLE3.txt b/2021/day16/EXAMPLE3.txt new file mode 100644 index 0000000..bcc798c --- /dev/null +++ b/2021/day16/EXAMPLE3.txt @@ -0,0 +1 @@ +EE00D40C823060 diff --git a/2021/day16/EXAMPLE4.txt b/2021/day16/EXAMPLE4.txt new file mode 100644 index 0000000..0d2cbff --- /dev/null +++ b/2021/day16/EXAMPLE4.txt @@ -0,0 +1 @@ +8A004A801A8002F478 diff --git a/2021/day16/EXAMPLE5.txt b/2021/day16/EXAMPLE5.txt new file mode 100644 index 0000000..ed3b78a --- /dev/null +++ b/2021/day16/EXAMPLE5.txt @@ -0,0 +1 @@ +620080001611562C8802118E34 diff --git a/2021/day16/EXAMPLE6.txt b/2021/day16/EXAMPLE6.txt new file mode 100644 index 0000000..827e51b --- /dev/null +++ b/2021/day16/EXAMPLE6.txt @@ -0,0 +1 @@ +C0015000016115A2E0802F182340 diff --git a/2021/day16/EXAMPLE7.txt b/2021/day16/EXAMPLE7.txt new file mode 100644 index 0000000..0a1278e --- /dev/null +++ b/2021/day16/EXAMPLE7.txt @@ -0,0 +1 @@ +A0016C880162017C3686B18A3D4780 diff --git a/2021/day16/INPUT.txt b/2021/day16/INPUT.txt new file mode 100644 index 0000000..a746a7f --- /dev/null +++ b/2021/day16/INPUT.txt @@ -0,0 +1 @@ +005410C99A9802DA00B43887138F72F4F652CC0159FE05E802B3A572DBBE5AA5F56F6B6A4600FCCAACEA9CE0E1002013A55389B064C0269813952F983595234002DA394615002A47E06C0125CF7B74FE00E6FC470D4C0129260B005E73FCDFC3A5B77BF2FB4E0009C27ECEF293824CC76902B3004F8017A999EC22770412BE2A1004E3DCDFA146D00020670B9C0129A8D79BB7E88926BA401BAD004892BBDEF20D253BE70C53CA5399AB648EBBAAF0BD402B95349201938264C7699C5A0592AF8001E3C09972A949AD4AE2CB3230AC37FC919801F2A7A402978002150E60BC6700043A23C618E20008644782F10C80262F005679A679BE733C3F3005BC01496F60865B39AF8A2478A04017DCBEAB32FA0055E6286D31430300AE7C7E79AE55324CA679F9002239992BC689A8D6FE084012AE73BDFE39EBF186738B33BD9FA91B14CB7785EC01CE4DCE1AE2DCFD7D23098A98411973E30052C012978F7DD089689ACD4A7A80CCEFEB9EC56880485951DB00400010D8A30CA1500021B0D625450700227A30A774B2600ACD56F981E580272AA3319ACC04C015C00AFA4616C63D4DFF289319A9DC401008650927B2232F70784AE0124D65A25FD3A34CC61A6449246986E300425AF873A00CD4401C8A90D60E8803D08A0DC673005E692B000DA85B268E4021D4E41C6802E49AB57D1ED1166AD5F47B4433005F401496867C2B3E7112C0050C20043A17C208B240087425871180C01985D07A22980273247801988803B08A2DC191006A2141289640133E80212C3D2C3F377B09900A53E00900021109623425100723DC6884D3B7CFE1D2C6036D180D053002880BC530025C00F700308096110021C00C001E44C00F001955805A62013D0400B400ED500307400949C00F92972B6BC3F47A96D21C5730047003770004323E44F8B80008441C8F51366F38F240 diff --git a/2021/day16/Makefile b/2021/day16/Makefile new file mode 100644 index 0000000..529acac --- /dev/null +++ b/2021/day16/Makefile @@ -0,0 +1,59 @@ +# AOC daily Makefile - GNU make only. +# +# Copyright (C) 2021 Bruno Raoult ("br") +# Licensed under the GNU General Public License v3.0 or later. +# Some rights reserved. See COPYING. +# +# You should have received a copy of the GNU General Public License along with this +# program. If not, see . +# +# SPDX-License-Identifier: GPL-3.0-or-later +# + +INPUT := INPUT.txt +SHELL := /bin/bash + +CC := gcc + +LIB := aoc_$(shell uname -m) +INCDIR := ../include +LIBDIR := ../lib +LDFLAGS := -L$(LIBDIR) +LDLIB := -l$(LIB) + +export LD_LIBRARY_PATH = $(LIBDIR) + +CFLAGS += -std=gnu99 +CFLAGS += -O2 +CFLAGS += -g +#CFLAGS += -pg +CFLAGS += -Wall +CFLAGS += -Wextra +CFLAGS += -march=native +CFLAGS += -Wmissing-declarations +CFLAGS += -Wno-unused-result + +CFLAGS += -DDEBUG_DEBUG # activate general debug (debug.c) +CFLAGS += -DDEBUG_POOL # memory pools management + +TIME := \time -f "\ttime: %E real, %U user, %S sys\n\tcontext-switch:\t%c+%w, page-faults: %F+%R\n" +export PATH := .:$(PATH) + +.PHONY: clean all compile ex1 ex2 + +all: ex1 ex2 + +compile: aoc-c + +ex1: aoc-c + @$(TIME) aoc-c -p 1 < $(INPUT) + +ex2: aoc-c + @$(TIME) aoc-c -p 2 < $(INPUT) + +clean: + @rm -f aoc-c core* gmon.out + +.c: + @echo compiling $< + @$(CC) $(CFLAGS) $(LDFLAGS) -I $(INCDIR) $< $(LDLIB) -o $@ diff --git a/2021/day16/README.txt b/2021/day16/README.txt new file mode 100644 index 0000000..fe66e07 --- /dev/null +++ b/2021/day16/README.txt @@ -0,0 +1,93 @@ +--- Day 16: Packet Decoder --- + +As you leave the cave and reach open waters, you receive a transmission from the Elves back on the ship. + +The transmission was sent using the Buoyancy Interchange Transmission System (BITS), a method of packing numeric expressions into a binary sequence. Your submarine's computer has saved the transmission in hexadecimal (your puzzle input). + +The first step of decoding the message is to convert the hexadecimal representation into binary. Each character of hexadecimal corresponds to four bits of binary data: + +0 = 0000 +1 = 0001 +2 = 0010 +3 = 0011 +4 = 0100 +5 = 0101 +6 = 0110 +7 = 0111 +8 = 1000 +9 = 1001 +A = 1010 +B = 1011 +C = 1100 +D = 1101 +E = 1110 +F = 1111 + +The BITS transmission contains a single packet at its outermost layer which itself contains many other packets. The hexadecimal representation of this packet might encode a few extra 0 bits at the end; these are not part of the transmission and should be ignored. + +Every packet begins with a standard header: the first three bits encode the packet version, and the next three bits encode the packet type ID. These two values are numbers; all numbers encoded in any packet are represented as binary with the most significant bit first. For example, a version encoded as the binary sequence 100 represents the number 4. + +Packets with type ID 4 represent a literal value. Literal value packets encode a single binary number. To do this, the binary number is padded with leading zeroes until its length is a multiple of four bits, and then it is broken into groups of four bits. Each group is prefixed by a 1 bit except the last group, which is prefixed by a 0 bit. These groups of five bits immediately follow the packet header. For example, the hexadecimal string D2FE28 becomes: + +110100101111111000101000 +VVVTTTAAAAABBBBBCCCCC + +Below each bit is a label indicating its purpose: + + The three bits labeled V (110) are the packet version, 6. + The three bits labeled T (100) are the packet type ID, 4, which means the packet is a literal value. + The five bits labeled A (10111) start with a 1 (not the last group, keep reading) and contain the first four bits of the number, 0111. + The five bits labeled B (11110) start with a 1 (not the last group, keep reading) and contain four more bits of the number, 1110. + The five bits labeled C (00101) start with a 0 (last group, end of packet) and contain the last four bits of the number, 0101. + The three unlabeled 0 bits at the end are extra due to the hexadecimal representation and should be ignored. + +So, this packet represents a literal value with binary representation 011111100101, which is 2021 in decimal. + +Every other type of packet (any packet with a type ID other than 4) represent an operator that performs some calculation on one or more sub-packets contained within. Right now, the specific operations aren't important; focus on parsing the hierarchy of sub-packets. + +An operator packet contains one or more packets. To indicate which subsequent binary data represents its sub-packets, an operator packet can use one of two modes indicated by the bit immediately after the packet header; this is called the length type ID: + + If the length type ID is 0, then the next 15 bits are a number that represents the total length in bits of the sub-packets contained by this packet. + If the length type ID is 1, then the next 11 bits are a number that represents the number of sub-packets immediately contained by this packet. + +Finally, after the length type ID bit and the 15-bit or 11-bit field, the sub-packets appear. + +For example, here is an operator packet (hexadecimal string 38006F45291200) with length type ID 0 that contains two sub-packets: + +00111000000000000110111101000101001010010001001000000000 +VVVTTTILLLLLLLLLLLLLLLAAAAAAAAAAABBBBBBBBBBBBBBBB + + The three bits labeled V (001) are the packet version, 1. + The three bits labeled T (110) are the packet type ID, 6, which means the packet is an operator. + The bit labeled I (0) is the length type ID, which indicates that the length is a 15-bit number representing the number of bits in the sub-packets. + The 15 bits labeled L (000000000011011) contain the length of the sub-packets in bits, 27. + The 11 bits labeled A contain the first sub-packet, a literal value representing the number 10. + The 16 bits labeled B contain the second sub-packet, a literal value representing the number 20. + +After reading 11 and 16 bits of sub-packet data, the total length indicated in L (27) is reached, and so parsing of this packet stops. + +As another example, here is an operator packet (hexadecimal string EE00D40C823060) with length type ID 1 that contains three sub-packets: + +11101110000000001101010000001100100000100011000001100000 +VVVTTTILLLLLLLLLLLAAAAAAAAAAABBBBBBBBBBBCCCCCCCCCCC + + The three bits labeled V (111) are the packet version, 7. + The three bits labeled T (011) are the packet type ID, 3, which means the packet is an operator. + The bit labeled I (1) is the length type ID, which indicates that the length is a 11-bit number representing the number of sub-packets. + The 11 bits labeled L (00000000011) contain the number of sub-packets, 3. + The 11 bits labeled A contain the first sub-packet, a literal value representing the number 1. + The 11 bits labeled B contain the second sub-packet, a literal value representing the number 2. + The 11 bits labeled C contain the third sub-packet, a literal value representing the number 3. + +After reading 3 complete sub-packets, the number of sub-packets indicated in L (3) is reached, and so parsing of this packet stops. + +For now, parse the hierarchy of the packets throughout the transmission and add up all of the version numbers. + +Here are a few more examples of hexadecimal-encoded transmissions: + + 8A004A801A8002F478 represents an operator packet (version 4) which contains an operator packet (version 1) which contains an operator packet (version 5) which contains a literal value (version 6); this packet has a version sum of 16. + 620080001611562C8802118E34 represents an operator packet (version 3) which contains two sub-packets; each sub-packet is an operator packet that contains two literal values. This packet has a version sum of 12. + C0015000016115A2E0802F182340 has the same structure as the previous example, but the outermost packet uses a different length type ID. This packet has a version sum of 23. + A0016C880162017C3686B18A3D4780 is an operator packet that contains an operator packet that contains an operator packet that contains five literal values; it has a version sum of 31. + +Decode the structure of your hexadecimal-encoded BITS transmission; what do you get if you add up the version numbers in all packets?