2024 day17 (incomplete)

This commit is contained in:
Zack Buhman 2024-12-19 23:48:06 -06:00
parent 69febabee8
commit 307e990924
13 changed files with 334 additions and 7 deletions

View File

@ -1,7 +1,7 @@
#include <stdint.h> #include <stdint.h>
#include <stdio.h> //#include <stdio.h>
//#include "printf.h" #include "printf.h"
#include "dijkstra.h" #include "dijkstra.h"
#include "memory.h" #include "memory.h"
@ -95,6 +95,7 @@ int64_t _2024_day16_part2(const char * input, int length)
return -1; return -1;
} }
/*
#include <assert.h> #include <assert.h>
int main() int main()
@ -107,3 +108,4 @@ int main()
fclose(f); fclose(f);
printf("%ld\n", _2024_day16_part1(buf, length)); printf("%ld\n", _2024_day16_part1(buf, length));
} }
*/

5
2024/day17/input.txt Normal file
View File

@ -0,0 +1,5 @@
Register A: 59397658
Register B: 0
Register C: 0
Program: 2,4,1,1,7,5,4,6,1,4,0,3,5,5,3,0

15
2024/day17/input.txt.h Normal file
View File

@ -0,0 +1,15 @@
#pragma once
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
extern uint32_t _binary_2024_day17_input_txt_start __asm("_binary_2024_day17_input_txt_start");
extern uint32_t _binary_2024_day17_input_txt_end __asm("_binary_2024_day17_input_txt_end");
extern uint32_t _binary_2024_day17_input_txt_size __asm("_binary_2024_day17_input_txt_size");
#ifdef __cplusplus
}
#endif

5
2024/day17/sample1.txt Normal file
View File

@ -0,0 +1,5 @@
Register A: 729
Register B: 0
Register C: 0
Program: 0,1,5,4,3,0

15
2024/day17/sample1.txt.h Normal file
View File

@ -0,0 +1,15 @@
#pragma once
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
extern uint32_t _binary_2024_day17_sample1_txt_start __asm("_binary_2024_day17_sample1_txt_start");
extern uint32_t _binary_2024_day17_sample1_txt_end __asm("_binary_2024_day17_sample1_txt_end");
extern uint32_t _binary_2024_day17_sample1_txt_size __asm("_binary_2024_day17_sample1_txt_size");
#ifdef __cplusplus
}
#endif

5
2024/day17/sample2.txt Normal file
View File

@ -0,0 +1,5 @@
Register A: 2024
Register B: 0
Register C: 0
Program: 0,3,5,4,3,0

15
2024/day17/sample2.txt.h Normal file
View File

@ -0,0 +1,15 @@
#pragma once
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
extern uint32_t _binary_2024_day17_sample2_txt_start __asm("_binary_2024_day17_sample2_txt_start");
extern uint32_t _binary_2024_day17_sample2_txt_end __asm("_binary_2024_day17_sample2_txt_end");
extern uint32_t _binary_2024_day17_sample2_txt_size __asm("_binary_2024_day17_sample2_txt_size");
#ifdef __cplusplus
}
#endif

243
2024/day17/solution.c Normal file
View File

@ -0,0 +1,243 @@
#include <stdint.h>
#include "printf.h"
#include "parse.h"
struct state {
int pc;
int64_t a;
int64_t b;
int64_t c;
char mem[256];
int mem_length;
char out[256];
int out_length;
};
static int64_t combo_operand(struct state * state, int operand)
{
switch (operand) {
case 0: return 0;
case 1: return 1;
case 2: return 2;
case 3: return 3;
case 4: return state->a;
case 5: return state->b;
case 6: return state->c;
default:
printf("invalid combo operand %d\n", operand);
return -1;
}
}
static bool op_adv(struct state * state, int operand)
{
int64_t value = combo_operand(state, operand);
const int64_t one = 1;
state->a = state->a / (one << value);
return true;
}
static bool op_bxl(struct state * state, int operand)
{
state->b = state->b ^ (int64_t)operand;
return true;
}
static bool op_bst(struct state * state, int operand)
{
int64_t value = combo_operand(state, operand);
state->b = value % 8;
return true;
}
static bool op_jnz(struct state * state, int operand)
{
if (state->a != 0) {
state->pc = operand;
return false;
} else {
return true;
}
}
static bool op_bxc(struct state * state, int operand)
{
state->b = state->b ^ state->c;
return true;
}
static bool op_out(struct state * state, int operand)
{
int64_t value = combo_operand(state, operand);
state->out[state->out_length++] = value % 8;
return true;
}
static bool op_bdv(struct state * state, int operand)
{
int64_t value = combo_operand(state, operand);
state->b = state->a / (1 << value);
return true;
}
static bool op_cdv(struct state * state, int operand)
{
int64_t value = combo_operand(state, operand);
state->c = state->a / (1 << value);
return true;
}
static const char * parse_register(const char * input, char c, int * value)
{
input = parse_match(input, "Register ");
input = parse_skip(input, c);
input = parse_match(input, ": ");
input = parse_base10(input, value);
input = parse_skip(input, '\n');
return input;
}
static void step(struct state * state)
{
int op = state->mem[state->pc];
int operand = state->mem[state->pc+1];
bool incpc;
switch (op) {
case 0: incpc = op_adv(state, operand); break;
case 1: incpc = op_bxl(state, operand); break;
case 2: incpc = op_bst(state, operand); break;
case 3: incpc = op_jnz(state, operand); break;
case 4: incpc = op_bxc(state, operand); break;
case 5: incpc = op_out(state, operand); break;
case 6: incpc = op_bdv(state, operand); break;
case 7: incpc = op_cdv(state, operand); break;
default:
printf("invalid opcode %d\n", op);
return;
}
if (incpc)
state->pc = state->pc + 2;
}
static const char * parse_program(const char * input, const char * end, struct state * state)
{
input = parse_match(input, "Program: ");
int value;
state->mem_length = 0;
input = parse_base10(input, &value);
state->mem[state->mem_length++] = value;
while (input < end) {
input = parse_skip(input, ',');
input = parse_base10(input, &value);
state->mem[state->mem_length++] = value;
input = parse_skip(input, '\n');
}
return input;
}
static inline void run_until_halt(struct state * state)
{
while (state->pc < state->mem_length) {
step(state);
}
}
static void parse_input(const char * input, int length, struct state * state)
{
const char * end = input + length;
state->pc = 0;
state->out_length = 0;
int reg;
input = parse_register(input, 'A', &reg);
state->a = reg;
input = parse_register(input, 'B', &reg);
state->b = reg;
input = parse_register(input, 'C', &reg);
state->c = reg;
input = parse_skip(input, '\n');
parse_program(input, end, state);
}
static void print_out(struct state * state)
{
printf("%d", state->out[0]);
for (int i = 1; i < state->out_length; i++) {
printf(",%d", state->out[i]);
}
print_char('\n');
}
int64_t _2024_day17_part1(const char * input, int length)
{
struct state state;
parse_input(input, length, &state);
run_until_halt(&state);
print_out(&state);
return -1;
}
static inline bool out_eq_mem(const struct state * state)
{
if (state->mem_length != state->out_length) {
return false;
}
for (int i = 0; i < state->mem_length; i++) {
if (state->mem[i] != state->out[i]) {
return false;
}
}
return true;
}
int64_t _2024_day17_part2(const char * input, int length)
{
struct state state;
parse_input(input, length, &state);
int64_t a = 1;
int64_t last_a = a;
while (true) {
state.a = a;
state.b = 0;
state.c = 0;
state.pc = 0;
state.out_length = 0;
run_until_halt(&state);
if (state.out_length < state.mem_length) {
last_a = a;
a *= 2;
} else {
break;
}
}
a = last_a;
while (true) {
state.a = a;
state.b = 0;
state.c = 0;
state.pc = 0;
state.out_length = 0;
run_until_halt(&state);
if (out_eq_mem(&state))
break;
a += 1;
}
print_out(&state);
return a;
}

View File

@ -2,10 +2,10 @@
#include "dijkstra.h" #include "dijkstra.h"
#include "heap.h" #include "heap.h"
#include "memory.h" #include "memory.h"
//#include "printf.h" #include "printf.h"
#include <stdio.h> //#include <stdio.h>
#include <assert.h> //#include <assert.h>
void dijkstra_cartesian(const char * graph, void dijkstra_cartesian(const char * graph,
int stride, int stride,

View File

@ -43,6 +43,9 @@
#include "2024/day15/input.txt.h" #include "2024/day15/input.txt.h"
#include "2024/day16/sample1.txt.h" #include "2024/day16/sample1.txt.h"
#include "2024/day16/input.txt.h" #include "2024/day16/input.txt.h"
#include "2024/day17/sample1.txt.h"
#include "2024/day17/sample2.txt.h"
#include "2024/day17/input.txt.h"
static struct start_size sample[][2] = { static struct start_size sample[][2] = {
{ {
@ -171,6 +174,12 @@ static struct start_size sample[][2] = {
{ ( char *)&_binary_2024_day16_sample1_txt_start, { ( char *)&_binary_2024_day16_sample1_txt_start,
(uint32_t)&_binary_2024_day16_sample1_txt_size }, (uint32_t)&_binary_2024_day16_sample1_txt_size },
}, },
{
{ ( char *)&_binary_2024_day17_sample1_txt_start,
(uint32_t)&_binary_2024_day17_sample1_txt_size },
{ ( char *)&_binary_2024_day17_sample2_txt_start,
(uint32_t)&_binary_2024_day17_sample2_txt_size },
},
}; };
static struct start_size input[] = { static struct start_size input[] = {
@ -216,4 +225,6 @@ static struct start_size input[] = {
(uint32_t)&_binary_2024_day15_input_txt_size }, (uint32_t)&_binary_2024_day15_input_txt_size },
{ ( char *)&_binary_2024_day16_input_txt_start, { ( char *)&_binary_2024_day16_input_txt_start,
(uint32_t)&_binary_2024_day16_input_txt_size }, (uint32_t)&_binary_2024_day16_input_txt_size },
{ ( char *)&_binary_2024_day17_input_txt_start,
(uint32_t)&_binary_2024_day17_input_txt_size },
}; };

View File

@ -38,7 +38,7 @@ bool runner_tick(struct runner_state * runner_state)
int year = solution[ix].year; int year = solution[ix].year;
int day = solution[ix].day; int day = solution[ix].day;
if (year != 2024 || day != 16) { if (year != 2024 || day != 17) {
return false; return false;
} }

View File

@ -46,6 +46,8 @@ int64_t _2024_day15_part1(const char * input, int length);
int64_t _2024_day15_part2(const char * input, int length); int64_t _2024_day15_part2(const char * input, int length);
int64_t _2024_day16_part1(const char * input, int length); int64_t _2024_day16_part1(const char * input, int length);
int64_t _2024_day16_part2(const char * input, int length); int64_t _2024_day16_part2(const char * input, int length);
int64_t _2024_day17_part1(const char * input, int length);
int64_t _2024_day17_part2(const char * input, int length);
struct day_funcs solution[] = { struct day_funcs solution[] = {
{ {
@ -153,4 +155,9 @@ struct day_funcs solution[] = {
{_2024_day16_part1, _2024_day16_part2}, {_2024_day16_part1, _2024_day16_part2},
NULL, NULL,
}, },
{
2024, 17,
{_2024_day17_part1, _2024_day17_part2},
NULL,
},
}; };

View File

@ -66,4 +66,8 @@ DAY_OBJ = \
2024/day15/solution.o \ 2024/day15/solution.o \
2024/day16/sample1.txt.o \ 2024/day16/sample1.txt.o \
2024/day16/input.txt.o \ 2024/day16/input.txt.o \
2024/day16/solution.o 2024/day16/solution.o \
2024/day17/sample1.txt.o \
2024/day17/sample2.txt.o \
2024/day17/input.txt.o \
2024/day17/solution.o