#include "aoc.h" #include "iccmp.h" #include "allocator.h" #include "dvec_s.h" #include "util.h" #include #include #include bool deploy(struct icc *icc, size_t x, size_t y) { int input; input = 0; while (icc->state != ICC_HALT) { icc_step_inst(icc); switch (icc->state) { case ICC_INPUT: switch (input) { case 0: mi_setv(&icc->in, x, MI_POS); input++; break; case 1: mi_setv(&icc->in, y, MI_POS); input++; break; } break; case ICC_OUTPUT: return mi_cast_ul(&icc->out); } } assert(false); } void part1(void) { struct icc icc, save; size_t x, y; size_t answer; bool inbeam; bool inbeam_p; size_t beam_start; icc_init(&icc); icc_parse_inst(&icc, aoc.input, aoc.input_size); while (icc.state == ICC_RUN) icc_step_inst(&icc); assert(icc.state == ICC_INPUT); icc_init(&save); icc_copy(&save, &icc); answer = 0; beam_start = 0; for (y = 0; y < 50; y++) { inbeam_p = false; for (x = beam_start; x < 50; x++) { icc_copy(&icc, &save); inbeam = deploy(&icc, x, y); aoc_debug("%lu %lu %i\n", y, x, inbeam); if (inbeam && !inbeam_p) beam_start = x; if (!inbeam && inbeam_p) break; inbeam_p = inbeam; answer += inbeam; } } aoc.answer = aprintf("%lu", answer); aoc.solution = "141"; icc_deinit(&save); icc_deinit(&icc); } void part2(void) { const size_t sqw = 100, sqh = 100; struct icc icc, save; struct dvec ends; size_t x, y; size_t answer; size_t beam_start; size_t beam_end; size_t *end; bool inbeam; icc_init(&icc); icc_parse_inst(&icc, aoc.input, aoc.input_size); while (icc.state == ICC_RUN) icc_step_inst(&icc); assert(icc.state == ICC_INPUT); icc_init(&save); icc_copy(&save, &icc); dvec_init(&ends, sizeof(size_t), 10, &stdlib_strict_heap_allocator); answer = 0; beam_start = beam_end = 0; for (y = 0; ; y++) { inbeam = false; for (x = beam_start; !inbeam; x++) { if (x > beam_start + 10) { aoc_debug("SKIP %lu\n", y); end = dvec_add_slot(&ends); *end = 0; goto skip; } icc_copy(&icc, &save); inbeam = deploy(&icc, x, y); } beam_start = x - 1; inbeam = true; if (beam_end < beam_start) beam_end = beam_start + 1; for (x = beam_end; inbeam; x++) { icc_copy(&icc, &save); inbeam = deploy(&icc, x, y); } beam_end = x - 1; end = dvec_add_slot(&ends); *end = beam_end; if (y >= sqh - 1) { end = dvec_at(&ends, y - (sqh - 1)); if (*end >= beam_start + sqw) { answer = beam_start * 10000 + (y - (sqh - 1)); goto exit; } } skip: aoc_debug("%lu %lu %lu\n", y, beam_start, beam_end); } exit: aoc.answer = aprintf("%lu", answer); aoc.solution = "15641348"; dvec_deinit(&ends); icc_deinit(&save); icc_deinit(&icc); }