aoc-2019-c

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

commit 0ba2f1d3d01cec0e51ccbe6b144009a7440f7b7b
parent 3ef16bed60d82e4d87ba93d90c891615d4078d87
Author: Louis Burda <quent.burda@gmail.com>
Date:   Wed,  3 Nov 2021 01:15:53 +0100

Add day 5 part 1

Diffstat:
Mdata/helper/template/Makefile | 2+-
Mlibs/Makefile | 2+-
Alibs/include/icc.h | 52++++++++++++++++++++++++++++++++++++++++++++++++++++
Rsrc/day2/memvec.h -> libs/include/memvec.h | 0
Mlibs/include/util.h | 2++
Alibs/src/icc.c | 239+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Rsrc/day2/memvec.c -> libs/src/memvec.c | 0
Msrc/day2/Makefile | 5++---
Dsrc/day2/icc.c | 108-------------------------------------------------------------------------------
Dsrc/day2/icc.h | 33---------------------------------
Msrc/day2/main.c | 45++++++++++++++++++++++++---------------------
Asrc/day5/Makefile | 12++++++++++++
Asrc/day5/input | 1+
Asrc/day5/main.c | 34++++++++++++++++++++++++++++++++++
Asrc/day5/part1 | 98+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/day5/part2 | 76++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
16 files changed, 542 insertions(+), 167 deletions(-)

diff --git a/data/helper/template/Makefile b/data/helper/template/Makefile @@ -9,4 +9,4 @@ clean: lib: make -C ../../libs -main: main.c +main: main.c ../../libs/build/libaoc.so diff --git a/libs/Makefile b/libs/Makefile @@ -15,7 +15,7 @@ build/%.o: src/%.c include/%.h | build build/wrapper.o: src/wrapper.c $(CC) -c -o $@ $< $(CFLAGS) $(LDLIBS) -build/libaoc.a: build/util.o build/aoc.o build/wrapper.o +build/libaoc.a: build/util.o build/aoc.o build/wrapper.o build/memvec.o build/icc.o ar rcs $@ $^ build/test_%: tests/%.c diff --git a/libs/include/icc.h b/libs/include/icc.h @@ -0,0 +1,52 @@ +#include "aoc.h" +#include "util.h" +#include "memvec.h" + +#include <stdlib.h> + +enum { + ICC_PARAM_IMM, + ICC_PARAM_POS +}; + +enum { + ICC_INST_ADD = 1, + ICC_INST_MULT = 2, + ICC_INST_STORE = 3, + ICC_INST_LOAD = 4, + + ICC_INST_HALT = 99 +}; + +enum { + ICC_OK, + ICC_INPUT, + ICC_OUTPUT, + ICC_HALT +}; + +struct icc { + int status; + int in, out; + + size_t instp; + struct memvec instructions; +}; + +int icc_init(struct icc *icc); +void icc_free(struct icc *icc); + +int icc_parse_inst(struct icc *icc, const char *str, size_t len); +void icc_step_inst(struct icc *icc); + +void icc_set_inst(struct icc *icc, size_t addr, int in); +void icc_get_inst(struct icc *icc, size_t addr, int *out); + +int icc_param_mode(int inst, int param); +void icc_get_param(struct icc *icc, int param, int *out); +void icc_get_dest(struct icc *icc, int param, int *out); + +void icc_input_callback(struct icc *icc, int (*callback)(int)); + +void * icc_inst_copy(struct icc *icc); +void icc_reset(struct icc *icc, void *instcopy); diff --git a/src/day2/memvec.h b/libs/include/memvec.h diff --git a/libs/include/util.h b/libs/include/util.h @@ -13,6 +13,8 @@ #define ASSERT(expr) assert(expr, \ "Assert '" #expr "' at " LOC() " failed\n") +#define ASSERTV(expr, msg, ...) assert(expr, \ + LOC() " : " msg "\n" __VA_OPT__(,) __VA_ARGS__) #define CHKP(ptr) chkp(ptr, \ "Unexpected NULL pointer '" #ptr "' at " LOC() "\n") diff --git a/libs/src/icc.c b/libs/src/icc.c @@ -0,0 +1,239 @@ +#include "icc.h" + +int +icc_init(struct icc *icc) +{ + icc->instp = 0; + icc->status = ICC_OK; + return memvec_init(&icc->instructions, 0, sizeof(int)); +} + +void +icc_free(struct icc *icc) +{ + memvec_free(&icc->instructions); +} + +int +icc_parse_inst(struct icc *icc, const char *str, size_t len) +{ + const char *line = str, *nline, *end = str + len; + char *endptr = NULL; + size_t linelen; + int val; + + do { + nline = ntoken(line, end, &linelen, ",\n"); + val = strtoul(line, &endptr, 10); + if (endptr && !memchr(",\n", *endptr, 3)) + return FAIL; + if (memvec_add(&icc->instructions, &val) == FAIL) + return FAIL; + line = nline; + } while (nline); + + return OK; +} + +const char* +icc_param_str(struct icc *icc, int param) +{ + static char buf[32]; + int val; + + icc_get_inst(icc, icc->instp + param, &val); + snprintf(buf, sizeof(buf), "%i", val); + + return buf; +} + +void +icc_debug_op(struct icc *icc, const char *opstr, int n) +{ + int i, val, inst; + + if (!aoc.debug) return; + + icc_get_inst(icc, icc->instp, &inst); + + fprintf(stderr, "%04li: (%05i) %s ", icc->instp, inst, opstr); + + for (i = 1; i <= n; i++) { + if (i > 1) fprintf(stderr, ", "); + icc_get_inst(icc, icc->instp + i, &val); + switch (icc_param_mode(inst, i)) { + case ICC_PARAM_IMM: + fprintf(stderr, "%i", val); + break; + case ICC_PARAM_POS: + fprintf(stderr, "[%i]", val); + break; + default: + die("ICC: Unknown parmeter mode\n"); + } + } + + fprintf(stderr, "\n"); +} + +void +icc_inst_add(struct icc *icc) +{ + int a, b, dst; + + icc_get_param(icc, 1, &a); + icc_get_param(icc, 2, &b); + icc_get_dest(icc, 3, &dst); + + icc_debug_op(icc, "ADD", 3); + icc_set_inst(icc, dst, a + b); + + icc->instp += 4; + icc->status = ICC_OK; +} + +void +icc_inst_mul(struct icc *icc) +{ + int a, b, dst; + + icc_get_param(icc, 1, &a); + icc_get_param(icc, 2, &b); + icc_get_dest(icc, 3, &dst); + + icc_debug_op(icc, "MUL", 3); + icc_set_inst(icc, dst, a * b); + + icc->instp += 4; + icc->status = ICC_OK; +} + +void +icc_inst_store(struct icc *icc) +{ + int dst; + + if (icc->status != ICC_INPUT) { + icc_debug_op(icc, "INPUT", 0); + icc->status = ICC_INPUT; + } else { + icc_debug_op(icc, "STORE", 1); + icc_get_dest(icc, 1, &dst); + icc_set_inst(icc, dst, icc->in); + + icc->instp += 2; + icc->status = ICC_OK; + } +} + +void +icc_inst_load(struct icc *icc) +{ + int out; + + if (icc->status != ICC_OUTPUT) { + icc_debug_op(icc, "LOAD", 1); + icc_get_param(icc, 1, &out); + + icc->out = out; + icc->status = ICC_OUTPUT; + icc_debug_op(icc, "OUTPUT", 0); + } else { + icc->instp += 2; + icc->status = ICC_OK; + } +} + +void +icc_step_inst(struct icc *icc) +{ + int inst; + + icc_get_inst(icc, icc->instp, &inst); + inst %= 100; + + switch (inst) { + case ICC_INST_ADD: + icc_inst_add(icc); + break; + case ICC_INST_MULT: + icc_inst_mul(icc); + break; + case ICC_INST_STORE: + icc_inst_store(icc); + break; + case ICC_INST_LOAD: + icc_inst_load(icc); + break; + case ICC_INST_HALT: + icc->status = ICC_HALT; + break; + default: + die("ICC: Unknown instruction: '%i'\n", inst); + } +} + +void +icc_set_inst(struct icc *icc, size_t addr, int val) +{ + memvec_set(&icc->instructions, addr, &val); +} + +void +icc_get_inst(struct icc *icc, size_t addr, int *out) +{ + *out = *(int*)memvec_get(&icc->instructions, addr); +} + +int +icc_param_mode(int inst, int param) +{ + int div, i; + + div = 100; + for (i = 1; i < param; i++) div *= 10; + + return (inst / div) % 10 == 1 ? ICC_PARAM_IMM : ICC_PARAM_POS; +} + +void +icc_get_param(struct icc *icc, int param, int *out) +{ + int inst, val; + + icc_get_inst(icc, icc->instp, &inst); + icc_get_inst(icc, icc->instp + param, &val); + + switch (icc_param_mode(inst, param)) { + case ICC_PARAM_IMM: + *out = val; + break; + case ICC_PARAM_POS: + icc_get_inst(icc, val, out); + break; + default: + die("ICC: Unknown parmeter mode\n"); + }; +} + +void +icc_get_dest(struct icc *icc, int param, int *out) +{ + icc_get_inst(icc, icc->instp + param, out); +} + +void* +icc_inst_copy(struct icc *icc) +{ + return memdup(icc->instructions.data, icc->instructions.len); +} + +void +icc_reset(struct icc *icc, void *instcopy) +{ + icc->status = ICC_OK; + icc->instp = 0; + if (instcopy) + memcpy(icc->instructions.data, instcopy, icc->instructions.len); +} + diff --git a/src/day2/memvec.c b/libs/src/memvec.c diff --git a/src/day2/Makefile b/src/day2/Makefile @@ -1,4 +1,4 @@ -CFLAGS = -I ../../libs/include -L ../../libs/build -g +CFLAGS = -g -I ../../libs/include -L ../../libs/build LDLIBS = -laoc all: lib main @@ -9,5 +9,4 @@ lib: clean: rm main -main: *.c *.h - $(CC) -o $@ *.c $(CFLAGS) $(LDLIBS) +main: main.c ../../libs/build/libaoc.a diff --git a/src/day2/icc.c b/src/day2/icc.c @@ -1,108 +0,0 @@ -#include "icc.h" - -int -icc_init(struct icc *config) -{ - config->instp = 0; - config->status = ICC_OK; - return memvec_init(&config->instructions, 0, sizeof(int)); -} - -void -icc_free(struct icc *config) -{ - memvec_free(&config->instructions); -} - -int -icc_parse_inst(struct icc *config, const char *str, size_t len) -{ - const char *line = str, *nline, *end = str + len; - char *endptr = NULL; - size_t linelen; - int val; - - do { - nline = ntoken(line, end, &linelen, ",\n"); - val = strtoul(line, &endptr, 10); - if (endptr && !memchr(",\n", *endptr, 3)) - return FAIL; - if (memvec_add(&config->instructions, &val) == FAIL) - return FAIL; - line = nline; - } while (nline); - - return OK; -} - -void -icc_inst_add(struct icc *config) -{ - int a, b, res, dst; - a = ICC_GET_INST(config, config->instp + 1); - b = ICC_GET_INST(config, config->instp + 2); - res = ICC_GET_INST(config, a) - + ICC_GET_INST(config, b); - dst = ICC_GET_INST(config, config->instp + 3); - debug("%i <= %i + %i\n", dst, a, b); - memvec_set(&config->instructions, dst, &res); - config->instp += 4; -} - -void -icc_inst_mul(struct icc *config) -{ - int a, b, res, dst; - a = ICC_GET_INST(config, config->instp + 1); - b = ICC_GET_INST(config, config->instp + 2); - res = ICC_GET_INST(config, a) - * ICC_GET_INST(config, b); - dst = ICC_GET_INST(config, config->instp + 3); - debug("%i <= %i * %i\n", dst, a, b); - memvec_set(&config->instructions, dst, &res); - config->instp += 4; -} - -void -icc_step_inst(struct icc *config) -{ - int inst; - - inst = ICC_GET_INST(config, config->instp); - - switch (inst) { - case ICC_INST_ADD: - icc_inst_add(config); - break; - case ICC_INST_MULT: - icc_inst_mul(config); - break; - case ICC_INST_HALT: - config->status = ICC_HALT; - break; - default: - die("Hit unknown instruction: '%i'\n", inst); - } -} - -void -icc_set_inst(struct icc *config, size_t index, int val) -{ - memvec_set(&config->instructions, index, &val); -} - -void* -icc_inst_copy(struct icc *config) -{ - return memdup(config->instructions.data, config->instructions.len); -} - -void -icc_reset(struct icc *config, void *instcopy) -{ - config->status = ICC_OK; - config->instp = 0; - if (instcopy) - memcpy(config->instructions.data, instcopy, config->instructions.len); -} - diff --git a/src/day2/icc.h b/src/day2/icc.h @@ -1,33 +0,0 @@ -#include "aoc.h" -#include "util.h" -#include "memvec.h" - -#include <stdlib.h> - -#define ICC_GET_INST(conf, addr) (*(int*)memvec_get(&(conf)->instructions, addr)) - -enum { - ICC_INST_ADD = 1, - ICC_INST_MULT = 2, - ICC_INST_HALT = 99 -}; - -enum { - ICC_OK, - ICC_HALT -}; - -struct icc { - int status; - size_t instp; - struct memvec instructions; -}; - -int icc_init(struct icc *config); -void icc_free(struct icc *config); -int icc_parse_inst(struct icc *config, const char *str, size_t len); -void icc_step_inst(struct icc *config); -void icc_set_inst(struct icc *config, size_t index, int val); -void* icc_inst_copy(struct icc *config); -void icc_reset(struct icc *config, void *instcopy); - diff --git a/src/day2/main.c b/src/day2/main.c @@ -7,54 +7,57 @@ void part1(void) { - struct icc config; + struct icc icc; + int res; - ASSERT(icc_init(&config) == OK); - ASSERT(icc_parse_inst(&config, aoc.input, aoc.input_size) == OK); + ASSERT(icc_init(&icc) == OK); + ASSERT(icc_parse_inst(&icc, aoc.input, aoc.input_size) == OK); - icc_set_inst(&config, 1, 12); - icc_set_inst(&config, 2, 2); + icc_set_inst(&icc, 1, 12); + icc_set_inst(&icc, 2, 2); - while (config.status != ICC_HALT) - icc_step_inst(&config); + while (icc.status != ICC_HALT) + icc_step_inst(&icc); - aoc.answer = CHKP(aprintf("%i", ICC_GET_INST(&config, 0))); + icc_get_inst(&icc, 0, &res); + aoc.answer = CHKP(aprintf("%i", res)); aoc.solution = "5098658"; - icc_free(&config); + icc_free(&icc); } void part2(void) { - struct icc config; + struct icc icc; void *instcopy; - int a, b; + int a, b, c; - ASSERT(icc_init(&config) == OK); - ASSERT(icc_parse_inst(&config, aoc.input, aoc.input_size) == OK); - instcopy = icc_inst_copy(&config); + ASSERT(icc_init(&icc) == OK); + ASSERT(icc_parse_inst(&icc, aoc.input, aoc.input_size) == OK); + instcopy = icc_inst_copy(&icc); for (a = 0; a < 100; a++) { for (b = 0; b < 100; b++) { - icc_set_inst(&config, 1, a); - icc_set_inst(&config, 2, b); + icc_set_inst(&icc, 1, a); + icc_set_inst(&icc, 2, b); debug("\nTrying a:%i b:%i\n\n", a, b); - while (config.status != ICC_HALT) - icc_step_inst(&config); + while (icc.status != ICC_HALT) + icc_step_inst(&icc); - if (ICC_GET_INST(&config, 0) == 19690720) { + icc_get_inst(&icc, 0, &c); + if (c == 19690720) { aoc.answer = CHKP(aprintf("%02i%02i", a, b)); aoc.solution = "5064"; goto exit; } else { - icc_reset(&config, instcopy); + icc_reset(&icc, instcopy); } } } exit: free(instcopy); - icc_free(&config); + icc_free(&icc); } diff --git a/src/day5/Makefile b/src/day5/Makefile @@ -0,0 +1,12 @@ +CFLAGS = -g -I ../../libs/include -L ../../libs/build +LDLIBS = -laoc + +all: lib main + +clean: + rm main + +lib: + make -C ../../libs + +main: main.c ../../libs/build/libaoc.a diff --git a/src/day5/input b/src/day5/input @@ -0,0 +1 @@ +3,225,1,225,6,6,1100,1,238,225,104,0,1002,114,19,224,1001,224,-646,224,4,224,102,8,223,223,1001,224,7,224,1,223,224,223,1101,40,62,225,1101,60,38,225,1101,30,29,225,2,195,148,224,1001,224,-40,224,4,224,1002,223,8,223,101,2,224,224,1,224,223,223,1001,143,40,224,101,-125,224,224,4,224,1002,223,8,223,1001,224,3,224,1,224,223,223,101,29,139,224,1001,224,-99,224,4,224,1002,223,8,223,1001,224,2,224,1,224,223,223,1101,14,34,225,102,57,39,224,101,-3420,224,224,4,224,102,8,223,223,1001,224,7,224,1,223,224,223,1101,70,40,225,1102,85,69,225,1102,94,5,225,1,36,43,224,101,-92,224,224,4,224,1002,223,8,223,101,1,224,224,1,224,223,223,1102,94,24,224,1001,224,-2256,224,4,224,102,8,223,223,1001,224,1,224,1,223,224,223,1102,8,13,225,1101,36,65,224,1001,224,-101,224,4,224,102,8,223,223,101,3,224,224,1,223,224,223,4,223,99,0,0,0,677,0,0,0,0,0,0,0,0,0,0,0,1105,0,99999,1105,227,247,1105,1,99999,1005,227,99999,1005,0,256,1105,1,99999,1106,227,99999,1106,0,265,1105,1,99999,1006,0,99999,1006,227,274,1105,1,99999,1105,1,280,1105,1,99999,1,225,225,225,1101,294,0,0,105,1,0,1105,1,99999,1106,0,300,1105,1,99999,1,225,225,225,1101,314,0,0,106,0,0,1105,1,99999,8,677,226,224,1002,223,2,223,1006,224,329,1001,223,1,223,1108,226,226,224,1002,223,2,223,1005,224,344,101,1,223,223,1108,226,677,224,1002,223,2,223,1006,224,359,101,1,223,223,107,226,226,224,1002,223,2,223,1005,224,374,101,1,223,223,1107,226,226,224,1002,223,2,223,1005,224,389,101,1,223,223,107,677,677,224,102,2,223,223,1006,224,404,101,1,223,223,1008,226,226,224,1002,223,2,223,1006,224,419,101,1,223,223,108,677,226,224,1002,223,2,223,1006,224,434,101,1,223,223,1108,677,226,224,102,2,223,223,1005,224,449,101,1,223,223,1008,677,226,224,102,2,223,223,1006,224,464,1001,223,1,223,108,677,677,224,102,2,223,223,1005,224,479,101,1,223,223,7,677,677,224,102,2,223,223,1005,224,494,1001,223,1,223,8,226,677,224,102,2,223,223,1006,224,509,101,1,223,223,107,677,226,224,1002,223,2,223,1005,224,524,1001,223,1,223,7,677,226,224,1002,223,2,223,1005,224,539,1001,223,1,223,1007,226,677,224,1002,223,2,223,1005,224,554,1001,223,1,223,8,677,677,224,102,2,223,223,1006,224,569,101,1,223,223,7,226,677,224,102,2,223,223,1006,224,584,1001,223,1,223,1008,677,677,224,102,2,223,223,1005,224,599,101,1,223,223,1007,677,677,224,1002,223,2,223,1006,224,614,101,1,223,223,1107,677,226,224,1002,223,2,223,1006,224,629,101,1,223,223,1107,226,677,224,1002,223,2,223,1006,224,644,101,1,223,223,1007,226,226,224,102,2,223,223,1005,224,659,1001,223,1,223,108,226,226,224,102,2,223,223,1006,224,674,101,1,223,223,4,223,99,226 diff --git a/src/day5/main.c b/src/day5/main.c @@ -0,0 +1,34 @@ +#include "aoc.h" +#include "icc.h" + +#include <stdlib.h> +#include <stdio.h> + +void +part1(void) +{ + struct icc icc; + + ASSERT(icc_init(&icc) == OK); + ASSERT(icc_parse_inst(&icc, aoc.input, aoc.input_size) == OK); + + while (icc.status != ICC_HALT) { + icc_step_inst(&icc); + switch (icc.status) { + case ICC_INPUT: + icc.in = 1; + break; + case ICC_OUTPUT: + printf("%i\n", icc.out); + break; + } + } + + icc_free(&icc); +} + +void +part2(void) +{ + +} diff --git a/src/day5/part1 b/src/day5/part1 @@ -0,0 +1,98 @@ +--- Day 5: Sunny with a Chance of Asteroids --- + +You're starting to sweat as the ship makes its way toward Mercury. The Elves suggest that you get +the air conditioner working by upgrading your ship computer to support the Thermal Environment +Supervision Terminal. + +The Thermal Environment Supervision Terminal (TEST) starts by running a diagnostic +program (your puzzle input). The TEST diagnostic program will run on your existing Intcode +computer after a few modifications: + +First, you'll need to add two new instructions: + + + - Opcode 3 takes a single integer as input and saves it to the position given by its +only parameter. For example, the instruction 3,50 would take an input value and store it at address +50. + + - Opcode 4 outputs the value of its only parameter. For example, the instruction 4,50 +would output the value at address 50. + + +Programs that use these instructions will come with documentation that explains what should be +connected to the input and output. The program 3,0,4,0,99 outputs whatever it gets as input, then +halts. + +Second, you'll need to add support for parameter modes: + +Each parameter of an instruction is handled based on its parameter mode. Right now, your ship +computer already understands parameter mode 0, position mode, which causes the +parameter to be interpreted as a position - if the parameter is 50, its value is +the value stored at address 50 in memory. Until now, all parameters have been in +position mode. + +Now, your ship computer will also need to handle parameters in mode 1, immediate mode. +In immediate mode, a parameter is interpreted as a value - if the parameter is 50, its +value is simply 50. + +Parameter modes are stored in the same value as the instruction's opcode. The opcode is a two-digit +number based only on the ones and tens digit of the value, that is, the opcode is the rightmost two +digits of the first value in an instruction. Parameter modes are single digits, one per parameter, +read right-to-left from the opcode: the first parameter's mode is in the hundreds digit, the second +parameter's mode is in the thousands digit, the third parameter's mode is in the ten-thousands +digit, and so on. Any missing modes are 0. + +For example, consider the program 1002,4,3,4,33. + +The first instruction, 1002,4,3,4, is a multiply instruction - the rightmost two digits +of the first value, 02, indicate opcode 2, multiplication. Then, going right to left, the parameter +modes are 0 (hundreds digit), 1 (thousands digit), and 0 (ten-thousands digit, not present and +therefore zero): + +ABCDE + 1002 + +DE - two-digit opcode, 02 == opcode 2 + C - mode of 1st parameter, 0 == position mode + B - mode of 2nd parameter, 1 == immediate mode + A - mode of 3rd parameter, 0 == position mode, + omitted due to being a leading zero + +This instruction multiplies its first two parameters. The first parameter, 4 in position mode, +works like it did before - its value is the value stored at address 4 (33). The second parameter, 3 +in immediate mode, simply has value 3. The result of this operation, 33 * 3 = 99, is written +according to the third parameter, 4 in position mode, which also works like it did before - 99 is +written to address 4. + +Parameters that an instruction writes to will never be in immediate mode. + +Finally, some notes: + + + - It is important to remember that the instruction pointer should increase by the number +of values in the instruction after the instruction finishes. Because of the new instructions, +this amount is no longer always 4. + + - Integers can be negative: 1101,100,-1,4,0 is a valid program (find 100 + -1, store the result in +position 4). + + +The TEST diagnostic program will start by requesting from the user the ID of the system to test by +running an input instruction - provide it 1, the ID for the ship's air conditioner +unit. + +It will then perform a series of diagnostic tests confirming that various parts of the Intcode +computer, like parameter modes, function correctly. For each test, it will run an +output instruction indicating how far the result of the test was from the expected +value, where 0 means the test was successful. Non-zero outputs mean that a function is not working +correctly; check the instructions that were run before the output instruction to see which one +failed. + +Finally, the program will output a diagnostic code and immediately halt. This final +output isn't an error; an output followed immediately by a halt means the program finished. If all +outputs were zero except the diagnostic code, the diagnostic program ran successfully. + +After providing 1 to the only input instruction and passing all the tests, what diagnostic +code does the program produce? + + diff --git a/src/day5/part2 b/src/day5/part2 @@ -0,0 +1,76 @@ +--- Part Two --- + +The air conditioner comes online! Its cold air feels good for a while, but then the TEST alarms +start to go off. Since the air conditioner can't vent its heat anywhere but back into the +spacecraft, it's actually making the air inside the ship warmer. + +Instead, you'll need to use the TEST to extend the thermal radiators. Fortunately, the diagnostic +program (your puzzle input) is already equipped for this. Unfortunately, your Intcode computer is +not. + +Your computer is only missing a few opcodes: + + + - Opcode 5 is jump-if-true: if the first parameter is non-zero, it sets +the instruction pointer to the value from the second parameter. Otherwise, it does nothing. + + - Opcode 6 is jump-if-false: if the first parameter is zero, it sets the +instruction pointer to the value from the second parameter. Otherwise, it does nothing. + + - Opcode 7 is less than: if the first parameter is less than the second +parameter, it stores 1 in the position given by the third parameter. Otherwise, it stores 0. + + - Opcode 8 is equals: if the first parameter is equal to the second +parameter, it stores 1 in the position given by the third parameter. Otherwise, it stores 0. + + +Like all instructions, these instructions need to support parameter modes as described +above. + +Normally, after an instruction is finished, the instruction pointer increases by the number of +values in that instruction. However, if the instruction modifies the instruction +pointer, that value is used and the instruction pointer is not automatically increased. + +For example, here are several programs that take one input, compare it to the value 8, and then +produce one output: + + + - 3,9,8,9,10,9,4,9,99,-1,8 - Using position mode, consider whether the input is +equal to 8; output 1 (if it is) or 0 (if it is not). + + - 3,9,7,9,10,9,4,9,99,-1,8 - Using position mode, consider whether the input is +less than 8; output 1 (if it is) or 0 (if it is not). + + - 3,3,1108,-1,8,3,4,3,99 - Using immediate mode, consider whether the input is +equal to 8; output 1 (if it is) or 0 (if it is not). + + - 3,3,1107,-1,8,3,4,3,99 - Using immediate mode, consider whether the input is +less than 8; output 1 (if it is) or 0 (if it is not). + + +Here are some jump tests that take an input, then output 0 if the input was zero or 1 if the input +was non-zero: + + + - 3,12,6,12,15,1,13,14,13,4,13,99,-1,0,1,9 (using position mode) + + - 3,3,1105,-1,9,1101,0,0,12,4,12,99,1 (using immediate mode) + + +Here's a larger example: + +3,21,1008,21,8,20,1005,20,22,107,8,21,20,1006,20,31, +1106,0,36,98,0,0,1002,21,125,20,4,20,1105,1,46,104, +999,1105,1,46,1101,1000,1,20,4,20,1105,1,46,98,99 + +The above example program uses an input instruction to ask for a single number. The program will +then output 999 if the input value is below 8, output 1000 if the input value is equal to 8, or +output 1001 if the input value is greater than 8. + +This time, when the TEST diagnostic program runs its input instruction to get the ID of the system +to test, provide it 5, the ID for the ship's thermal radiator controller. This +diagnostic test suite only outputs one number, the diagnostic code. + +What is the diagnostic code for system ID 5? + +