From 017a288a3ba93fca866a4225a809b3f1e23362ac Mon Sep 17 00:00:00 2001 From: dobiadi Date: Tue, 17 Dec 2024 23:48:59 +0100 Subject: [PATCH] Day17 --- day17/c/day17 | Bin 0 -> 15968 bytes day17/c/day17.c | 179 ++++++++++++++++++++++++++++++++++++++++++++++ day17/input.txt | 5 ++ day17/sample.txt | 5 ++ day17/sample2.txt | 5 ++ 5 files changed, 194 insertions(+) create mode 100755 day17/c/day17 create mode 100644 day17/c/day17.c create mode 100644 day17/input.txt create mode 100644 day17/sample.txt create mode 100644 day17/sample2.txt diff --git a/day17/c/day17 b/day17/c/day17 new file mode 100755 index 0000000000000000000000000000000000000000..f54a12eaa9ff905d6b74e5fe0583eedd6b0714f5 GIT binary patch literal 15968 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 QTz`6tsj#+6p^6m$4^HIl`2YX_ literal 0 HcmV?d00001 diff --git a/day17/c/day17.c b/day17/c/day17.c new file mode 100644 index 0000000..d6e40ac --- /dev/null +++ b/day17/c/day17.c @@ -0,0 +1,179 @@ +#include +#include +#include +#include + +#define CHARS_MAX 128 +#define MAX_INSTRUCTIONS 128 + +#define BIT_JUMPED 0 + +enum { + A, + B, + C, + REGISTERS_LEN +}; + +enum { + ADV, + BXL, + BST, + JNZ, + BXC, + OUT, + BDV, + CDV +}; + +void execute(uint64_t registers[REGISTERS_LEN], uint8_t *instructions, uint32_t *pc, uint8_t *status, char *output_buffer, int *buf_len); +uint64_t combo(uint64_t registers[REGISTERS_LEN], uint8_t operand); +uint64_t revert(uint8_t *instructions_inverted, uint8_t *instructions, uint32_t instruction_count, uint64_t current_A, uint32_t i, int print_register); + +int main() { + char *p, *buf, c; + + buf = calloc(CHARS_MAX, sizeof(char)); + p = buf; + + uint64_t registers[3]; + int reading_register = 0, operand = 0; + uint8_t *instructions = calloc(MAX_INSTRUCTIONS, sizeof(instructions[0])); + uint32_t instruction_count = 0; + + while ((c = getchar()) != EOF) { + if (reading_register < 3) { + *p++ = c; + if (c != '\n') { + continue; + } + + p = buf; + while(*p++ != ':'); + p++; + sscanf(p, "%li", ®isters[reading_register++]); + + memset(buf, 0, CHARS_MAX); + p = buf; + } else { + if (c < 48 || c > 57) continue; + uint8_t num = c - 48; + instructions[instruction_count++] = num; + } + } + + uint32_t pc = 0; + uint8_t status = 0; + int buf_len = 0; + while (pc < instruction_count) { + execute(registers, instructions, &pc, &status, buf, &buf_len); + if (!(status & (1 << BIT_JUMPED))) { + pc += 2; + } + } + + buf[buf_len - 1] = '\0'; + printf("%s\n", buf); + + // Find print register + int print_register = A; + for (uint32_t i = 0; i < instruction_count; i+=2) { + if (instructions[i] == OUT) { + print_register = instructions[i+1] - 4; + break; + } + } + + // Invert instruction list + uint8_t *instructions_inverted = calloc(instruction_count, sizeof(instructions[0])); + for (uint32_t i = 0; i < instruction_count; i++) { + instructions_inverted[i] = instructions[instruction_count - i - 1]; + } + + printf("%lu\n", revert(instructions_inverted, instructions, instruction_count, 0, 0, print_register)); + + + free(buf); + free(instructions); + free(instructions_inverted); +} + +uint64_t revert(uint8_t *instructions_inverted, uint8_t *instructions, uint32_t instruction_count, uint64_t current_A, uint32_t i, int print_register) { + if (i == instruction_count) { + return current_A >> 3; + } + + // Try each 3-bit LSB of A + for (uint32_t j = 0; j < 8; j++) { + uint64_t next_A = current_A + j; + uint64_t registers_copy[3] = {next_A, 0, 0}; + uint32_t pc = 0; + uint8_t status = 0; + for (pc = 0; pc < instruction_count - 4; pc+=2) { + execute(registers_copy, instructions, &pc, &status, NULL, NULL); + } + // Check print register + uint64_t expected_output = instructions_inverted[i]; + if (registers_copy[print_register] % 8 == expected_output) { + uint64_t a = revert(instructions_inverted, instructions, instruction_count, next_A << 3, i + 1, print_register); + if (a) { + return a; + } + } + } + + return 0; +} + +void execute(uint64_t registers[REGISTERS_LEN], uint8_t *instructions, uint32_t *pc, uint8_t *status, char *output_buffer, int *buf_len) { + uint8_t opcode = instructions[*pc]; + uint8_t operand = instructions[(*pc) + 1]; + uint8_t current_status = *status; + uint8_t next_status = 0; + + switch (opcode) { + case ADV: + registers[A] = registers[A] / (1 << combo(registers, operand)); + break; + case BXL: + registers[B] = registers[B] ^ operand; + break; + case BST: + registers[B] = combo(registers, operand) % 8; + break; + case JNZ: + if (registers[A] != 0) { + *pc = operand; + next_status |= 1 << BIT_JUMPED; + } + break; + case BXC: + registers[B] = registers[B] ^ registers[C]; + break; + case OUT: + output_buffer[(*buf_len)++] = ((uint8_t)combo(registers, operand) & 7) + 48; + output_buffer[(*buf_len)++] = ','; + break; + case BDV: + registers[B] = registers[A] / combo(registers, operand); + break; + case CDV: + registers[C] = registers[A] / (1 << combo(registers, operand)); + break; + } + + *status = next_status; +} + +uint64_t combo(uint64_t registers[REGISTERS_LEN], uint8_t operand) { + if (operand < 4) { + return operand; + } + + if (operand == 7) { + printf("INVALID PROGRAM\n"); + return 0; + } + + return registers[operand - 4]; +} diff --git a/day17/input.txt b/day17/input.txt new file mode 100644 index 0000000..2924de7 --- /dev/null +++ b/day17/input.txt @@ -0,0 +1,5 @@ +Register A: 46187030 +Register B: 0 +Register C: 0 + +Program: 2,4,1,5,7,5,0,3,4,0,1,6,5,5,3,0 diff --git a/day17/sample.txt b/day17/sample.txt new file mode 100644 index 0000000..f09839b --- /dev/null +++ b/day17/sample.txt @@ -0,0 +1,5 @@ +Register A: 729 +Register B: 0 +Register C: 0 + +Program: 0,1,5,4,3,0 diff --git a/day17/sample2.txt b/day17/sample2.txt new file mode 100644 index 0000000..4a91c26 --- /dev/null +++ b/day17/sample2.txt @@ -0,0 +1,5 @@ +Register A: 2024 +Register B: 0 +Register C: 0 + +Program: 0,3,5,4,3,0