aoc-2019-c

git clone https://git.sinitax.com/sinitax/aoc-2019-c
Log | Files | Refs | README | sfeed.txt

commit a1f776c9c5390b8409e7f44cb2a33d728d1200f3
parent 9c4f72ce260acc6398632cd9e396a54b0e494151
Author: Louis Burda <quent.burda@gmail.com>
Date:   Tue,  4 Apr 2023 12:24:38 -0400

Add day 23

Diffstat:
A23/info.mk | 4++++
A23/input | 2++
A23/main.c | 242+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
A23/part1 | 37+++++++++++++++++++++++++++++++++++++
A23/part2 | 22++++++++++++++++++++++
5 files changed, 307 insertions(+), 0 deletions(-)

diff --git a/23/info.mk b/23/info.mk @@ -0,0 +1,4 @@ +23_SRC = 23/main.c common/main.c common/iccmp.c common/aoc.c common/util.c +23_SRC += lib/liballoc/build/liballoc.a lib/libmaxint/build/libmaxint.a +23_SRC += lib/libhmap/build/libhmap.a lib/liblist/build/liblist.a +23_HDR = common/aoc.h common/iccmp.h common/util.h diff --git a/23/input b/23/input @@ -0,0 +1,2 @@ +3,62,1001,62,11,10,109,2241,105,1,0,2066,1569,571,1239,2200,1342,2169,899,1173,2035,1540,1204,1637,1806,641,977,1272,1773,1144,1008,1699,2107,1107,1909,1872,833,802,1410,932,1072,1307,1938,2000,734,1837,2138,1039,1606,701,1373,608,866,1443,1478,771,1509,672,1969,1668,1738,0,0,0,0,0,0,0,0,0,0,0,0,3,64,1008,64,-1,62,1006,62,88,1006,61,170,1105,1,73,3,65,20102,1,64,1,21002,66,1,2,21102,105,1,0,1106,0,436,1201,1,-1,64,1007,64,0,62,1005,62,73,7,64,67,62,1006,62,73,1002,64,2,132,1,132,68,132,1002,0,1,62,1001,132,1,140,8,0,65,63,2,63,62,62,1005,62,73,1002,64,2,161,1,161,68,161,1102,1,1,0,1001,161,1,169,101,0,65,0,1102,1,1,61,1102,1,0,63,7,63,67,62,1006,62,203,1002,63,2,194,1,68,194,194,1006,0,73,1001,63,1,63,1106,0,178,21102,210,1,0,105,1,69,1202,1,1,70,1101,0,0,63,7,63,71,62,1006,62,250,1002,63,2,234,1,72,234,234,4,0,101,1,234,240,4,0,4,70,1001,63,1,63,1106,0,218,1105,1,73,109,4,21102,1,0,-3,21102,0,1,-2,20207,-2,67,-1,1206,-1,293,1202,-2,2,283,101,1,283,283,1,68,283,283,22001,0,-3,-3,21201,-2,1,-2,1106,0,263,21202,-3,1,-3,109,-4,2105,1,0,109,4,21101,1,0,-3,21101,0,0,-2,20207,-2,67,-1,1206,-1,342,1202,-2,2,332,101,1,332,332,1,68,332,332,22002,0,-3,-3,21201,-2,1,-2,1105,1,312,21202,-3,1,-3,109,-4,2105,1,0,109,1,101,1,68,359,20101,0,0,1,101,3,68,367,20102,1,0,2,21101,0,376,0,1105,1,436,22101,0,1,0,109,-1,2106,0,0,1,2,4,8,16,32,64,128,256,512,1024,2048,4096,8192,16384,32768,65536,131072,262144,524288,1048576,2097152,4194304,8388608,16777216,33554432,67108864,134217728,268435456,536870912,1073741824,2147483648,4294967296,8589934592,17179869184,34359738368,68719476736,137438953472,274877906944,549755813888,1099511627776,2199023255552,4398046511104,8796093022208,17592186044416,35184372088832,70368744177664,140737488355328,281474976710656,562949953421312,1125899906842624,109,8,21202,-6,10,-5,22207,-7,-5,-5,1205,-5,521,21101,0,0,-4,21101,0,0,-3,21101,0,51,-2,21201,-2,-1,-2,1201,-2,385,471,20102,1,0,-1,21202,-3,2,-3,22207,-7,-1,-5,1205,-5,496,21201,-3,1,-3,22102,-1,-1,-5,22201,-7,-5,-7,22207,-3,-6,-5,1205,-5,515,22102,-1,-6,-5,22201,-3,-5,-3,22201,-1,-4,-4,1205,-2,461,1106,0,547,21102,1,-1,-4,21202,-6,-1,-6,21207,-7,0,-5,1205,-5,547,22201,-7,-6,-7,21201,-4,1,-4,1105,1,529,21201,-4,0,-7,109,-8,2106,0,0,109,1,101,1,68,563,21002,0,1,0,109,-1,2106,0,0,1102,6581,1,66,1101,0,4,67,1101,598,0,68,1101,0,253,69,1101,0,1,71,1101,606,0,72,1106,0,73,0,0,0,0,0,0,0,0,27,85159,1102,6151,1,66,1101,0,2,67,1102,635,1,68,1101,302,0,69,1102,1,1,71,1101,0,639,72,1105,1,73,0,0,0,0,1,292724,1102,84653,1,66,1101,0,1,67,1101,0,668,68,1101,0,556,69,1101,0,1,71,1102,1,670,72,1106,0,73,1,11,34,14669,1102,96893,1,66,1101,0,1,67,1102,699,1,68,1102,556,1,69,1102,0,1,71,1102,701,1,72,1106,0,73,1,1705,1101,93557,0,66,1101,2,0,67,1101,728,0,68,1102,302,1,69,1101,1,0,71,1102,1,732,72,1106,0,73,0,0,0,0,41,155138,1101,102061,0,66,1101,4,0,67,1102,761,1,68,1102,1,302,69,1102,1,1,71,1102,1,769,72,1105,1,73,0,0,0,0,0,0,0,0,4,122394,1101,0,93497,66,1102,1,1,67,1102,1,798,68,1101,556,0,69,1101,1,0,71,1102,800,1,72,1106,0,73,1,-18,49,41897,1101,0,80071,66,1102,1,1,67,1101,0,829,68,1101,0,556,69,1102,1,1,71,1102,1,831,72,1105,1,73,1,-1474987,2,13162,1101,71473,0,66,1101,2,0,67,1102,860,1,68,1101,0,351,69,1102,1,1,71,1102,1,864,72,1105,1,73,0,0,0,0,255,32771,1101,77569,0,66,1101,0,2,67,1102,1,893,68,1102,1,302,69,1101,1,0,71,1102,1,897,72,1106,0,73,0,0,0,0,39,52396,1102,24799,1,66,1102,1,1,67,1101,926,0,68,1101,0,556,69,1101,2,0,71,1102,1,928,72,1105,1,73,1,211,39,13099,11,42299,1102,55399,1,66,1102,1,1,67,1101,959,0,68,1102,1,556,69,1101,8,0,71,1102,961,1,72,1105,1,73,1,2,41,77569,39,26198,27,170318,17,79714,3,78889,34,44007,4,61197,4,81596,1101,0,22993,66,1101,1,0,67,1102,1,1004,68,1102,1,556,69,1102,1,1,71,1101,0,1006,72,1105,1,73,1,2485433,2,19743,1101,0,32687,66,1101,0,1,67,1101,0,1035,68,1102,556,1,69,1102,1,1,71,1102,1037,1,72,1106,0,73,1,28661,16,15501,1102,1,44657,66,1101,1,0,67,1102,1,1066,68,1102,556,1,69,1102,1,2,71,1102,1,1068,72,1106,0,73,1,10,33,102061,4,40798,1102,53777,1,66,1101,3,0,67,1101,1099,0,68,1101,0,302,69,1101,0,1,71,1101,0,1105,72,1106,0,73,0,0,0,0,0,0,22,212991,1101,70997,0,66,1101,4,0,67,1102,1,1134,68,1102,1,253,69,1101,0,1,71,1101,0,1142,72,1106,0,73,0,0,0,0,0,0,0,0,38,93557,1102,93761,1,66,1101,1,0,67,1102,1171,1,68,1102,556,1,69,1102,1,0,71,1102,1,1173,72,1106,0,73,1,1625,1101,0,96973,66,1102,1,1,67,1102,1,1200,68,1102,556,1,69,1102,1,1,71,1102,1202,1,72,1105,1,73,1,13,24,102071,1101,0,42299,66,1102,1,3,67,1101,0,1231,68,1101,302,0,69,1102,1,1,71,1101,0,1237,72,1105,1,73,0,0,0,0,0,0,42,82763,1102,78889,1,66,1102,2,1,67,1102,1,1266,68,1102,1,302,69,1102,1,1,71,1102,1270,1,72,1105,1,73,0,0,0,0,34,29338,1102,5167,1,66,1102,3,1,67,1101,0,1299,68,1101,0,302,69,1101,0,1,71,1102,1,1305,72,1106,0,73,0,0,0,0,0,0,22,70997,1101,12697,0,66,1101,0,1,67,1101,1334,0,68,1101,0,556,69,1101,3,0,71,1101,0,1336,72,1105,1,73,1,5,33,306183,33,408244,4,20399,1102,1,99251,66,1101,0,1,67,1102,1369,1,68,1102,556,1,69,1102,1,1,71,1101,0,1371,72,1106,0,73,1,181,24,204142,1102,1,13099,66,1102,1,4,67,1102,1400,1,68,1101,302,0,69,1102,1,1,71,1102,1408,1,72,1106,0,73,0,0,0,0,0,0,0,0,1,73181,1102,1,85159,66,1102,1,2,67,1102,1437,1,68,1102,1,302,69,1101,1,0,71,1101,0,1441,72,1106,0,73,0,0,0,0,17,39857,1102,1,82763,66,1102,1,3,67,1101,1470,0,68,1102,1,302,69,1102,1,1,71,1101,0,1476,72,1106,0,73,0,0,0,0,0,0,1,146362,1102,44179,1,66,1102,1,1,67,1101,1505,0,68,1102,556,1,69,1102,1,1,71,1102,1507,1,72,1105,1,73,1,278,29,161331,1102,1,19457,66,1102,1,1,67,1101,1536,0,68,1102,1,556,69,1102,1,1,71,1102,1,1538,72,1105,1,73,1,17,39,39297,1101,0,60251,66,1101,0,1,67,1102,1567,1,68,1102,1,556,69,1102,1,0,71,1101,1569,0,72,1106,0,73,1,1621,1101,73181,0,66,1102,4,1,67,1101,0,1596,68,1101,0,253,69,1102,1,1,71,1102,1,1604,72,1105,1,73,0,0,0,0,0,0,0,0,25,71473,1101,0,99277,66,1102,1,1,67,1102,1633,1,68,1102,556,1,69,1101,1,0,71,1102,1635,1,72,1106,0,73,1,-661,24,408284,1102,1,2957,66,1101,1,0,67,1101,1664,0,68,1101,556,0,69,1101,1,0,71,1101,1666,0,72,1106,0,73,1,16,38,187114,1102,77687,1,66,1101,0,1,67,1101,1695,0,68,1102,1,556,69,1101,1,0,71,1101,1697,0,72,1105,1,73,1,160,4,101995,1102,79757,1,66,1102,1,1,67,1102,1,1726,68,1101,0,556,69,1101,5,0,71,1102,1728,1,72,1105,1,73,1,1,49,125691,29,53777,24,306213,16,5167,11,84598,1102,41897,1,66,1102,3,1,67,1102,1,1765,68,1102,302,1,69,1102,1,1,71,1102,1,1771,72,1105,1,73,0,0,0,0,0,0,22,141994,1102,1,39857,66,1102,2,1,67,1102,1800,1,68,1102,302,1,69,1102,1,1,71,1101,0,1804,72,1105,1,73,0,0,0,0,3,157778,1101,87671,0,66,1101,1,0,67,1102,1833,1,68,1102,556,1,69,1101,1,0,71,1101,1835,0,72,1105,1,73,1,64937,49,83794,1102,14669,1,66,1102,1,3,67,1102,1864,1,68,1101,0,302,69,1101,1,0,71,1101,0,1870,72,1105,1,73,0,0,0,0,0,0,40,6151,1101,0,102071,66,1102,4,1,67,1101,1899,0,68,1101,302,0,69,1102,1,1,71,1101,1907,0,72,1106,0,73,0,0,0,0,0,0,0,0,22,283988,1101,93169,0,66,1101,1,0,67,1102,1936,1,68,1101,0,556,69,1101,0,0,71,1101,1938,0,72,1105,1,73,1,1087,1102,1,92173,66,1101,0,1,67,1102,1,1965,68,1102,1,556,69,1101,1,0,71,1101,0,1967,72,1105,1,73,1,7751410,2,26324,1101,80897,0,66,1101,1,0,67,1102,1996,1,68,1101,0,556,69,1101,1,0,71,1102,1,1998,72,1106,0,73,1,-1275519,2,6581,1101,0,102481,66,1101,3,0,67,1101,2027,0,68,1102,302,1,69,1101,0,1,71,1101,0,2033,72,1106,0,73,0,0,0,0,0,0,1,219543,1102,1,2687,66,1102,1,1,67,1101,2062,0,68,1102,1,556,69,1101,1,0,71,1102,1,2064,72,1106,0,73,1,5807,29,107554,1101,0,32771,66,1101,0,1,67,1102,2093,1,68,1101,0,556,69,1102,6,1,71,1101,0,2095,72,1105,1,73,1,22083,40,12302,42,165526,42,248289,32,102481,32,204962,32,307443,1102,2791,1,66,1101,0,1,67,1101,0,2134,68,1101,0,556,69,1101,1,0,71,1102,2136,1,72,1106,0,73,1,-204,11,126897,1101,5669,0,66,1102,1,1,67,1102,2165,1,68,1101,556,0,69,1101,1,0,71,1101,2167,0,72,1106,0,73,1,125,33,204122,1101,94693,0,66,1102,1,1,67,1101,2196,0,68,1101,556,0,69,1101,1,0,71,1101,2198,0,72,1105,1,73,1,244,16,10334,1101,0,20399,66,1101,0,6,67,1102,1,2227,68,1101,0,302,69,1101,1,0,71,1102,1,2239,72,1106,0,73,0,0,0,0,0,0,0,0,0,0,0,0,25,142946 + diff --git a/23/main.c b/23/main.c @@ -0,0 +1,242 @@ +#include "aoc.h" +#include "iccmp.h" +#include "list.h" +#include "maxint.h" +#include "util.h" + +#include <assert.h> +#include <stdbool.h> +#include <stdlib.h> + +struct packet { + struct maxint x, y; + size_t src_ip, dst_ip; + + struct list_link link; +}; + +static struct packet nat_packet; +static bool nat_avail = false; + +void +feed_input(struct icc *icc, mi_ul imm) +{ + while (icc->state != ICC_HALT) { + if (icc->state == ICC_INPUT) { + mi_setv(&icc->in, imm, MI_POS); + icc_step_inst(icc); + break; + } + icc_step_inst(icc); + } +} + +void +free_packet(struct packet *packet) +{ + mi_deinit(&packet->x); + mi_deinit(&packet->y); + free(packet); +} + +bool +recv_packet(struct list *queues, struct maxint *val, int state, size_t ip) +{ + static struct packet *packet; + struct list_link *link; + char buf[64]; + + aoc_debug("INPUT %i\n", ip); + if (list_empty(&queues[ip])) { + mi_setv(val, 1, MI_NEG); + return false; + } else { + switch(state) { + case 0: + link = list_front(&queues[ip]); + packet = LIST_UPCAST(link, struct packet, link); + aoc_debug("%i <- %i (", packet->src_ip, packet->dst_ip); + mi_dec(&packet->x, buf, sizeof(buf), 0); + aoc_debug("%s, ", buf); + mi_dec(&packet->y, buf, sizeof(buf), 0); + aoc_debug("%s)\n", buf); + mi_set(val, &packet->x); + break; + case 1: + mi_set(val, &packet->y); + list_link_pop(&packet->link); + free_packet(packet); + break; + } + return true; + } +} + +void +send_packet(struct list *queues, struct maxint *val, int state, size_t ip) +{ + static struct packet *packet; + size_t dst; + char buf[64]; + + aoc_debug("OUTPUT %i\n", ip); + switch (state) { + case 0: + dst = (size_t) mi_cast_ul(val); + if (dst == 255) { + packet = &nat_packet; + } else { + packet = malloc(sizeof(struct packet)); + } + mi_init(&packet->x); + mi_init(&packet->y); + packet->src_ip = ip; + packet->dst_ip = dst; + packet->link = LIST_LINK_INIT; + break; + case 1: + mi_set(&packet->x, val); + break; + case 2: + mi_set(&packet->y, val); + if (packet->dst_ip != 255) { + assert(packet->dst_ip < 50); + list_insert_back(&queues[packet->dst_ip], &packet->link); + } else { + nat_avail = true; + } + aoc_debug("%i <- %i (", packet->dst_ip, packet->src_ip); + mi_dec(&packet->x, buf, sizeof(buf), 0); + aoc_debug("%s, ", buf); + mi_dec(&packet->y, buf, sizeof(buf), 0); + aoc_debug("%s)\n", buf); + break; + } +} + +bool +nic_tick(struct icc *icc, struct list *queues, size_t ip) +{ + int out_state, in_state; + bool idle, done; + + done = false; + idle = true; + in_state = 0; + out_state = 0; + while (!done && icc->state != ICC_HALT) { + switch (icc->state) { + case ICC_INPUT: + idle &= !recv_packet(queues, &icc->in, in_state, ip); + in_state = (in_state + 1) % 2; + if (!in_state) done = true; + break; + case ICC_OUTPUT: + send_packet(queues, &icc->out, out_state, ip); + out_state = (out_state + 1) % 3; + idle = false; + break; + defualt: + assert(icc->state == ICC_RUN); + } + icc_step_inst(icc); + } + assert(in_state == 0 && out_state == 0); + + return idle; +} + +void +part1(void) +{ + struct list queues[256]; + struct icc icc[50]; + struct list_link *link; + struct packet *packet; + char buf[64]; + size_t i; + + for (i = 0; i < 50; i++) { + icc_init(&icc[i]); + icc_parse_inst(&icc[i], aoc.input, aoc.input_size); + feed_input(&icc[i], (mi_ul) i); + } + + for (i = 0; i < 256; i++) { + list_init(&queues[i]); + } + + while (!nat_avail) { + aoc_debug("-- TICK --\n"); + for (i = 0; i < 50; i++) + nic_tick(&icc[i], queues, i); + } + + mi_dec(&nat_packet.y, buf, sizeof(buf), 0); + aoc.answer = aprintf("%s", buf); + aoc.solution = "20225"; + + for (i = 0; i < 256; i++) { + for (LIST_ITER(&queues[i], link)) { + packet = LIST_UPCAST(link, struct packet, link); + free_packet(packet); + } + list_clear(&queues[i]); + } + + for (i = 0; i < 50; i++) + icc_deinit(&icc[i]); +} + +void +part2(void) +{ + struct list queues[256]; + struct icc icc[50]; + struct list_link *link; + struct packet *packet; + size_t answer; + size_t last; + bool idle; + size_t i; + + for (i = 0; i < 50; i++) { + list_init(&queues[i]); + icc_init(&icc[i]); + icc_parse_inst(&icc[i], aoc.input, aoc.input_size); + feed_input(&icc[i], (mi_ul) i); + } + + while (1) { + aoc_debug("-- TICK --\n"); + + idle = true; + for (i = 0; i < 50; i++) + idle &= nic_tick(&icc[i], queues, i); + + if (idle) { + assert(nat_avail); + packet = malloc(sizeof(struct packet)); + memcpy(packet, &nat_packet, sizeof(struct packet)); + list_insert_back(&queues[0], &packet->link); + + if (mi_cast_ul(&packet->y) == last) { + answer = last; + break; + } + last = mi_cast_ul(&packet->y); + + } + } + + aoc.answer = aprintf("%lu", answer); + + for (i = 0; i < 50; i++) { + for (LIST_ITER(&queues[i], link)) { + packet = LIST_UPCAST(link, struct packet, link); + free_packet(packet); + } + list_clear(&queues[i]); + icc_deinit(&icc[i]); + } +} diff --git a/23/part1 b/23/part1 @@ -0,0 +1,37 @@ +--- Day 23: Category Six --- + +The droids have finished repairing as much of the ship as they can. Their report indicates that +this was a Category 6 disaster - not because it was that bad, but because it destroyed the stockpile +of Category 6 network cables as well as most of the ship's network infrastructure. + +You'll need to rebuild the network from scratch. + +The computers on the network are standard Intcode computers that communicate by sending packets to +each other. There are 50 of them in total, each running a copy of the same Network Interface +Controller (NIC) software (your puzzle input). The computers have network addresses 0 through 49; +when each computer boots up, it will request its network address via a single input instruction. Be +sure to give each computer a unique network address. + +Once a computer has received its network address, it will begin doing work and communicating over +the network by sending and receiving packets. All packets contain two values named X and Y. Packets +sent to a computer are queued by the recipient and read in the order they are received. + +To send a packet to another computer, the NIC will use three output instructions that provide the +destination address of the packet followed by its X and Y values. For example, three output +instructions that provide the values 10, 20, 30 would send a packet with X=20 and Y=30 to the +computer with address 10. + +To receive a packet from another computer, the NIC will use an input instruction. If the incoming +packet queue is empty, provide -1. Otherwise, provide the X value of the next packet; the computer +will then use a second input instruction to receive the Y value for the same packet. Once both +values of the packet are read in this way, the packet is removed from the queue. + +Note that these input and output instructions never block. Specifically, output instructions do not +wait for the sent packet to be received - the computer might send multiple packets before receiving +any. Similarly, input instructions do not wait for a packet to arrive - if no packet is waiting, +input instructions should receive -1. + +Boot up all 50 computers and attach them to your network. What is the Y value of the first packet +sent to address 255? + + diff --git a/23/part2 b/23/part2 @@ -0,0 +1,22 @@ +--- Part Two --- + +Packets sent to address 255 are handled by a device called a NAT (Not Always Transmitting). The NAT +is responsible for managing power consumption of the network by blocking certain packets and +watching for idle periods in the computers. + +If a packet would be sent to address 255, the NAT receives it instead. The NAT remembers only the +last packet it receives; that is, the data in each packet it receives overwrites the NAT's packet +memory with the new packet's X and Y values. + +The NAT also monitors all computers on the network. If all computers have empty incoming packet +queues and are continuously trying to receive packets without sending packets, the network is +considered idle. + +Once the network is idle, the NAT sends only the last packet it received to address 0; this will +cause the computers on the network to resume activity. In this way, the NAT can throttle power +consumption of the network when the ship needs power in other areas. + +Monitor packets released to the computer at address 0 by the NAT. What is the first Y value +delivered by the NAT to the computer at address 0 twice in a row? + +