day 16 part 1 (with tons of debug printf)

This commit is contained in:
2021-12-20 20:36:23 +01:00
parent 90303eb8b5
commit 50963c233b
2 changed files with 226 additions and 0 deletions

View File

@@ -91,3 +91,35 @@ Here are a few more examples of hexadecimal-encoded transmissions:
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. 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? Decode the structure of your hexadecimal-encoded BITS transmission; what do you get if you add up the version numbers in all packets?
Your puzzle answer was 923.
The first half of this puzzle is complete! It provides one gold star: *
--- Part Two ---
Now that you have the structure of your transmission decoded, you can calculate the value of the expression it represents.
Literal values (type ID 4) represent a single number as described above. The remaining type IDs are more interesting:
Packets with type ID 0 are sum packets - their value is the sum of the values of their sub-packets. If they only have a single sub-packet, their value is the value of the sub-packet.
Packets with type ID 1 are product packets - their value is the result of multiplying together the values of their sub-packets. If they only have a single sub-packet, their value is the value of the sub-packet.
Packets with type ID 2 are minimum packets - their value is the minimum of the values of their sub-packets.
Packets with type ID 3 are maximum packets - their value is the maximum of the values of their sub-packets.
Packets with type ID 5 are greater than packets - their value is 1 if the value of the first sub-packet is greater than the value of the second sub-packet; otherwise, their value is 0. These packets always have exactly two sub-packets.
Packets with type ID 6 are less than packets - their value is 1 if the value of the first sub-packet is less than the value of the second sub-packet; otherwise, their value is 0. These packets always have exactly two sub-packets.
Packets with type ID 7 are equal to packets - their value is 1 if the value of the first sub-packet is equal to the value of the second sub-packet; otherwise, their value is 0. These packets always have exactly two sub-packets.
Using these rules, you can now work out the value of the outermost packet in your BITS transmission.
For example:
C200B40A82 finds the sum of 1 and 2, resulting in the value 3.
04005AC33890 finds the product of 6 and 9, resulting in the value 54.
880086C3E88112 finds the minimum of 7, 8, and 9, resulting in the value 7.
CE00C43D881120 finds the maximum of 7, 8, and 9, resulting in the value 9.
D8005AC2A8F0 produces 1, because 5 is less than 15.
F600BC2D8F produces 0, because 5 is not greater than 15.
9C005AC2F8F0 produces 0, because 5 is not equal to 15.
9C0141080250320F1802104A08 produces 1, because 1 + 3 = 2 * 2.
What do you get if you evaluate the expression represented by your hexadecimal-encoded BITS transmission?

194
2021/day16/aoc-c.c Normal file
View File

@@ -0,0 +1,194 @@
/* aoc-c.c: Advent of Code 2021, day 16 parts 1 & 2
*
* 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 <https://www.gnu.org/licenses/gpl-3.0-standalone.html>.
*
* SPDX-License-Identifier: GPL-3.0-or-later <https://spdx.org/licenses/GPL-3.0-or-later.html>
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <malloc.h>
#include <ctype.h>
#include <stdint.h>
#include "debug.h"
#include "pool.h"
#include "bits.h"
#include "list.h"
#define MAX_SUBPACKETS 1024
#define TYPE_VAL 4
struct packet {
u8 version;
u8 type;
u64 value;
};
static u64 totversions;
static u64 bitval(char *p, int length)
{
u64 val = 0;
for (; length; length--, p++) {
u8 b = *p -'0';
val += b << (length - 1);
//printf("%c -> %d, %lu\n", *p, b, val);
}
//printf("%lu\n", val);
return val;
}
static u64 decode_value(char *bits, char **end)
{
u64 val = 0;
for (u64 tmp = 16; tmp & 16; bits += 5) {
tmp = bitval(bits, 5);
val = val << 4 | (tmp & 15);
//printf("bits =%5s tmp=%lu xor=%lu val=%lu\n", bits, tmp, tmp & 15, val);
}
*end = bits;
return val;
}
int weight[] = {
['B'] = 0, ['C'] = 1, ['F'] = 2,
['H'] = 3, ['K'] = 4, ['N'] = 5, ['O'] = 6,
['P'] = 7, ['S'] = 8, ['V'] = 9
};
static struct packet decode(char *start, char **end)
{
struct packet packet;
char *cur;
s64 count;
//printf("decode(%.4s...)\n", start);
packet.version = bitval(start, 3);
totversions += packet.version;
packet.type = bitval(start + 3, 3);
log_f(3, "[%.6s...] version=%d type=%d\n", start, packet.version, packet.type);
cur = start + 6;
switch (packet.type) {
case TYPE_VAL:
packet.value = decode_value(cur, end);
printf("val = %lu len=%lu\n", packet.value, *end - cur);
break;
default:
switch (*cur++) {
case '0':
count = bitval(cur, 15);
cur += 15;
*end = cur;
printf("nbits = %lu\n", count);
while ((*end - cur) < count) {
decode(*end, end);
printf(" end - cur = %lu\n", *end - cur);
}
break;
case '1':
count = bitval(cur, 11);
cur += 11;
*end = cur;
printf("npackets = %ld\n", count);
while (count--) {
decode(*end, end);
printf(" count = %ld\n", count);
}
}
}
//log_f(3, "bin=[%s] version=%d type=%d\n", bits, version, type);
//log_f(3, "[%s] version=%d type=%d\n", start, packet.version, packet.type);
return packet;
}
/* read BITS data
*/
static char *read_input()
{
size_t alloc = 0;
char *buf, *bits = NULL, *p, *q, decode[2] = { 0 };
ssize_t buflen, bits_len;
if ((buflen = getline(&buf, &alloc, stdin)) > 0) {
buf[--buflen] = 0;
bits_len = buflen * 4 + 1;
if (!(bits = malloc(bits_len)))
goto free;
for (p = buf, q = bits; *p; ++p, q += 4) {
decode[0] = *p;
int val = strtol(decode, NULL, 16);
sprintf(q, "%c%c%c%c", val & 8? '1': '0', val & 4? '1': '0',
val & 2? '1': '0', val & 1? '1': '0');
}
}
free:
free(buf);
return bits;
}
/*
static u32 doit()
{
return 1;
}
static u32 part1()
{
return doit();
}
static u32 part2()
{
return doit();
}
*/
static int usage(char *prg)
{
fprintf(stderr, "Usage: %s [-d debug_level] [-p part]\n", prg);
return 1;
}
int main(int ac, char **av)
{
int opt, part = 1;
char *buf, *end=NULL;
while ((opt = getopt(ac, av, "d:p:")) != -1) {
switch (opt) {
case 'd':
debug_level_set(atoi(optarg));
break;
case 'p': /* 1 or 2 */
part = atoi(optarg);
if (part < 1 || part > 2)
return usage(*av);
break;
default:
return usage(*av);
}
}
if (optind < ac)
return usage(*av);
buf = read_input();
decode(buf, &end);
printf("END: end=%lu sum_versions=%lu\n", end - buf, totversions);
//printf("%s : res=%u\n", *av, part == 1? part1(): part2());
exit (0);
}