aoc-2019-c

Advent of Code 2019 Solutions in C
git clone https://git.sinitax.com/sinitax/aoc-2019-c
Log | Files | Refs | README | sfeed.txt

main.c (2780B)


      1#include "aoc.h"
      2#include "iccmp.h"
      3#include "allocator.h"
      4#include "dvec_s.h"
      5#include "util.h"
      6
      7#include <assert.h>
      8#include <stdbool.h>
      9#include <stdlib.h>
     10
     11bool
     12deploy(struct icc *icc, size_t x, size_t y)
     13{
     14	int input;
     15
     16	input = 0;
     17	while (icc->state != ICC_HALT) {
     18		icc_step_inst(icc);
     19		switch (icc->state) {
     20		case ICC_INPUT:
     21			switch (input) {
     22			case 0:
     23				mi_setv(&icc->in, x, MI_POS);
     24				input++;
     25				break;
     26			case 1:
     27				mi_setv(&icc->in, y, MI_POS);
     28				input++;
     29				break;
     30			}
     31			break;
     32		case ICC_OUTPUT:
     33			return mi_cast_ul(&icc->out);
     34		}
     35	}
     36
     37	assert(false);
     38}
     39
     40void
     41part1(void)
     42{
     43	struct icc icc, save;
     44	size_t x, y;
     45	size_t answer;
     46	bool inbeam;
     47	bool inbeam_p;
     48	size_t beam_start;
     49
     50	icc_init(&icc);
     51	icc_parse_inst(&icc, aoc.input, aoc.input_size);
     52
     53	while (icc.state == ICC_RUN)
     54		icc_step_inst(&icc);
     55	assert(icc.state == ICC_INPUT);
     56
     57	icc_init(&save);
     58	icc_copy(&save, &icc);
     59
     60	answer = 0;
     61	beam_start = 0;
     62	for (y = 0; y < 50; y++) {
     63		inbeam_p = false;
     64		for (x = beam_start; x < 50; x++) {
     65			icc_copy(&icc, &save);
     66			inbeam = deploy(&icc, x, y);
     67			aoc_debug("%lu %lu %i\n", y, x, inbeam);
     68			if (inbeam && !inbeam_p)
     69				beam_start = x;
     70			if (!inbeam && inbeam_p)
     71				break;
     72			inbeam_p = inbeam;
     73
     74			answer += inbeam;
     75		}
     76	}
     77
     78	aoc.answer = aprintf("%lu", answer);
     79	aoc.solution = "141";
     80
     81	icc_deinit(&save);
     82	icc_deinit(&icc);
     83}
     84
     85void
     86part2(void)
     87{
     88	const size_t sqw = 100, sqh = 100;
     89	struct icc icc, save;
     90	struct dvec ends;
     91	size_t x, y;
     92	size_t answer;
     93	size_t beam_start;
     94	size_t beam_end;
     95	size_t *end;
     96	bool inbeam;
     97
     98	icc_init(&icc);
     99	icc_parse_inst(&icc, aoc.input, aoc.input_size);
    100
    101	while (icc.state == ICC_RUN)
    102		icc_step_inst(&icc);
    103	assert(icc.state == ICC_INPUT);
    104
    105	icc_init(&save);
    106	icc_copy(&save, &icc);
    107
    108	dvec_init(&ends, sizeof(size_t), 10, &stdlib_strict_heap_allocator);
    109
    110	answer = 0;
    111
    112	beam_start = beam_end = 0;
    113	for (y = 0; ; y++) {
    114		inbeam = false;
    115		for (x = beam_start; !inbeam; x++) {
    116			if (x > beam_start + 10) {
    117				aoc_debug("SKIP %lu\n", y);
    118				end = dvec_add_slot(&ends);
    119				*end = 0;
    120				goto skip;
    121			}
    122			icc_copy(&icc, &save);
    123			inbeam = deploy(&icc, x, y);
    124		}
    125		beam_start = x - 1;
    126
    127		inbeam = true;
    128		if (beam_end < beam_start) beam_end = beam_start + 1;
    129		for (x = beam_end; inbeam; x++) {
    130			icc_copy(&icc, &save);
    131			inbeam = deploy(&icc, x, y);
    132		}
    133		beam_end = x - 1;
    134
    135		end = dvec_add_slot(&ends);
    136		*end = beam_end;
    137
    138		if (y >= sqh - 1) {
    139			end = dvec_at(&ends, y - (sqh - 1));
    140			if (*end >= beam_start + sqw) {
    141				answer = beam_start * 10000 + (y - (sqh - 1));
    142				goto exit;
    143			}
    144		}
    145
    146skip:
    147		aoc_debug("%lu %lu %lu\n", y, beam_start, beam_end);
    148	}
    149
    150exit:
    151	aoc.answer = aprintf("%lu", answer);
    152	aoc.solution = "15641348";
    153
    154	dvec_deinit(&ends);
    155	icc_deinit(&save);
    156	icc_deinit(&icc);
    157}