2024 day13

This commit is contained in:
Zack Buhman 2024-12-13 23:58:42 -06:00
parent 9f3fb5b481
commit 992460f534
15 changed files with 1579 additions and 19 deletions

View File

@ -3,6 +3,8 @@
#include "parse.h" #include "parse.h"
#include "printf.h" #include "printf.h"
#include "double.h"
struct vec3 { struct vec3 {
double x; double x;
double y; double y;
@ -48,14 +50,6 @@ static bool line_line_intersection_2d(vec3 * a, vec3 * da,
return true; return true;
} }
static double int64_to_double(int64_t n)
{
double l = (uint32_t)n;
double h = (int32_t)(n >> 32);
return h * 4294967296.0 + l;
}
static const char * parse_line(const char * input, vec3 * p, vec3 * v) static const char * parse_line(const char * input, vec3 * p, vec3 * v)
{ {
int64_t x, y, z; int64_t x, y, z;
@ -81,12 +75,12 @@ static const char * parse_line(const char * input, vec3 * p, vec3 * v)
input = parse_skip(input, ' '); input = parse_skip(input, ' ');
input = parse_skip(input, '\n'); input = parse_skip(input, '\n');
p->x = int64_to_double(x); p->x = (double)(x);
p->y = int64_to_double(y); p->y = (double)(y);
p->z = int64_to_double(z); p->z = (double)(z);
v->x = int64_to_double(dx); v->x = (double)(dx);
v->y = int64_to_double(dy); v->y = (double)(dy);
v->z = int64_to_double(dz); v->z = (double)(dz);
return input; return input;
} }

1279
2024/day13/input.txt Normal file

File diff suppressed because it is too large Load Diff

15
2024/day13/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_day13_input_txt_start __asm("_binary_2024_day13_input_txt_start");
extern uint32_t _binary_2024_day13_input_txt_end __asm("_binary_2024_day13_input_txt_end");
extern uint32_t _binary_2024_day13_input_txt_size __asm("_binary_2024_day13_input_txt_size");
#ifdef __cplusplus
}
#endif

15
2024/day13/sample1.txt Normal file
View File

@ -0,0 +1,15 @@
Button A: X+94, Y+34
Button B: X+22, Y+67
Prize: X=8400, Y=5400
Button A: X+26, Y+66
Button B: X+67, Y+21
Prize: X=12748, Y=12176
Button A: X+17, Y+86
Button B: X+84, Y+37
Prize: X=7870, Y=6450
Button A: X+69, Y+23
Button B: X+27, Y+71
Prize: X=18641, Y=10279

15
2024/day13/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_day13_sample1_txt_start __asm("_binary_2024_day13_sample1_txt_start");
extern uint32_t _binary_2024_day13_sample1_txt_end __asm("_binary_2024_day13_sample1_txt_end");
extern uint32_t _binary_2024_day13_sample1_txt_size __asm("_binary_2024_day13_sample1_txt_size");
#ifdef __cplusplus
}
#endif

124
2024/day13/solution.c Normal file
View File

@ -0,0 +1,124 @@
#include <stdint.h>
#include "linear_algebra.h"
#include "parse.h"
struct button {
int x;
int y;
};
struct prize {
int x;
int y;
};
struct claw_machine {
struct {
struct button a;
struct button b;
} button;
struct prize prize;
};
static const char * parse_button(const char * input, char c,
int * x, int * y)
{
input = parse_match(input, "Button ");
input = parse_skip(input, c);
input = parse_match(input, ": X+");
input = parse_base10(input, x);
input = parse_match(input, ", Y+");
input = parse_base10(input, y);
input = parse_skip(input, '\n');
return input;
}
static const char * parse_prize(const char * input,
int * x, int * y)
{
input = parse_match(input, "Prize: X=");
input = parse_base10(input, x);
input = parse_match(input, ", Y=");
input = parse_base10(input, y);
input = parse_skip(input, '\n');
return input;
}
static const char * parse_claw_machine(const char * input,
struct claw_machine * cm)
{
input = parse_button(input, 'A', &cm->button.a.x, &cm->button.a.y);
input = parse_button(input, 'B', &cm->button.b.x, &cm->button.b.y);
input = parse_prize(input, &cm->prize.x, &cm->prize.y);
return input;
}
static bool is_integral(double x)
{
int64_t ix = x;
double dx = ix;
double diff = dx - x;
return (diff < 0.00000001) && (diff > -0.00000001);
}
int64_t _2024_day13_part1(const char * input, int length)
{
const char * end = input + length;
int cost = 0;
while (input < end) {
struct claw_machine cm;
input = parse_claw_machine(input, &cm);
double ax = cm.button.a.x;
double ay = cm.button.a.y;
double bx = cm.button.b.x;
double by = cm.button.b.y;
double x = cm.prize.x;
double y = cm.prize.y;
struct double2 r = cramers_rule_2x2(ax, bx, x,
ay, by, y);
if (is_integral(r.x) && is_integral(r.y)) {
int a = (int)r.x;
int b = (int)r.y;
cost += a * 3 + b;
}
}
return cost;
}
int64_t _2024_day13_part2(const char * input, int length)
{
const char * end = input + length;
int64_t cost = 0;
while (input < end) {
struct claw_machine cm;
input = parse_claw_machine(input, &cm);
double ax = cm.button.a.x;
double ay = cm.button.a.y;
double bx = cm.button.b.x;
double by = cm.button.b.y;
double x = cm.prize.x;
double y = cm.prize.y;
x += 10000000000000;
y += 10000000000000;
struct double2 r = cramers_rule_2x2(ax, bx, x,
ay, by, y);
if (r.x == infinity || r.y == infinity) {
continue;
}
if (is_integral(r.x) && is_integral(r.y)) {
int64_t a = (int64_t)(r.x);
int64_t b = (int64_t)(r.y);
cost += a * 3 + b;
}
}
return cost;
}

View File

@ -1,12 +1,13 @@
all: $(patsubst %.cpp,%.elf,$(wildcard example/*.cpp)) all: $(patsubst %.cpp,%.elf,$(wildcard example/*.cpp))
OPT = -Og OPT = -O0
MAKEFILE_PATH := $(patsubst %/,%,$(dir $(abspath $(firstword $(MAKEFILE_LIST))))) MAKEFILE_PATH := $(patsubst %/,%,$(dir $(abspath $(firstword $(MAKEFILE_LIST)))))
CFLAGS += -I$(MAKEFILE_PATH) CFLAGS += -I$(MAKEFILE_PATH)
CFLAGS += -I$(MAKEFILE_PATH)/dreamcast/ CFLAGS += -I$(MAKEFILE_PATH)/dreamcast/
CFLAGS += -Wno-char-subscripts CFLAGS += -Wno-char-subscripts
LIB ?= $(MAKEFILE_PATH)/dreamcast LIB ?= $(MAKEFILE_PATH)/dreamcast
CARCH = -m4 -ml CARCH = -m4 -ml
include dreamcast/base.mk include dreamcast/base.mk

8
aoc.mk
View File

@ -7,7 +7,8 @@ OBJ = \
cartesian.o \ cartesian.o \
array.o \ array.o \
memory.o \ memory.o \
heap.o heap.o \
linear_algebra.o
DREAMCAST_OBJ = \ DREAMCAST_OBJ = \
runner_dreamcast.o \ runner_dreamcast.o \
@ -25,7 +26,10 @@ DREAMCAST_OBJ = \
libgcc/_moddi3.o \ libgcc/_moddi3.o \
libgcc/_udiv_qrnnd_16.o \ libgcc/_udiv_qrnnd_16.o \
libgcc/_clz.o \ libgcc/_clz.o \
libgcc/_div_table.o libgcc/_div_table.o \
libgcc/_fixdfdi.o \
libgcc/_fixunsdfdi.o \
libgcc/_floatdidf.o
include solutions.mk include solutions.mk

18
double.h Normal file
View File

@ -0,0 +1,18 @@
#pragma once
#include <stdint.h>
#define infinity (__builtin_inf())
#ifdef __cplusplus
extern "C" {
#endif
struct double2 {
double x;
double y;
};
#ifdef __cplusplus
}
#endif

View File

@ -33,6 +33,8 @@
#include "2024/day12/sample1.txt.h" #include "2024/day12/sample1.txt.h"
#include "2024/day12/sample2.txt.h" #include "2024/day12/sample2.txt.h"
#include "2024/day12/input.txt.h" #include "2024/day12/input.txt.h"
#include "2024/day13/sample1.txt.h"
#include "2024/day13/input.txt.h"
static struct start_size sample[][2] = { static struct start_size sample[][2] = {
{ {
@ -131,6 +133,12 @@ static struct start_size sample[][2] = {
{ ( char *)&_binary_2024_day12_sample2_txt_start, { ( char *)&_binary_2024_day12_sample2_txt_start,
(uint32_t)&_binary_2024_day12_sample2_txt_size }, (uint32_t)&_binary_2024_day12_sample2_txt_size },
}, },
{
{ ( char *)&_binary_2024_day13_sample1_txt_start,
(uint32_t)&_binary_2024_day13_sample1_txt_size },
{ ( char *)&_binary_2024_day13_sample1_txt_start,
(uint32_t)&_binary_2024_day13_sample1_txt_size },
},
}; };
static struct start_size input[] = { static struct start_size input[] = {
@ -166,4 +174,6 @@ static struct start_size input[] = {
(uint32_t)&_binary_2024_day11_input_txt_size }, (uint32_t)&_binary_2024_day11_input_txt_size },
{ ( char *)&_binary_2024_day12_input_txt_start, { ( char *)&_binary_2024_day12_input_txt_start,
(uint32_t)&_binary_2024_day12_input_txt_size }, (uint32_t)&_binary_2024_day12_input_txt_size },
{ ( char *)&_binary_2024_day13_input_txt_start,
(uint32_t)&_binary_2024_day13_input_txt_size },
}; };

56
linear_algebra.c Normal file
View File

@ -0,0 +1,56 @@
#include "linear_algebra.h"
#include "printf.h"
//#include <stdio.h>
double determinant_2x2(double a, double b,
double c, double d)
{
/*
a b
c d
*/
return a * d - b * c;
}
/*
5550.00 450000000444000.00 600000000222000.00
81081081161.08 108108108148.11
-3876.00 -460000000548084.00 -400000000524792.00
118679050709.00 103199174542.00
-6595.00 -470000000250610.00 -690000000567170.00
71266110727.92 104624715779.71
4278.00 440000001045978.00 460000000280508.00
102851800151.00 107526881786.00
*/
union di {
double d;
int64_t i;
};
static int64_t raw_double(double n)
{
union di di;
di.d = n;
return di.i;
}
struct double2 cramers_rule_2x2(double a1, double b1, double c1,
double a2, double b2, double c2)
{
double denom = determinant_2x2(a1, b1,
a2, b2);
double x_numer = determinant_2x2(c1, b1,
c2, b2);
double y_numer = determinant_2x2(a1, c1,
a2, c2);
return (struct double2){x_numer / denom, y_numer / denom};
}

19
linear_algebra.h Normal file
View File

@ -0,0 +1,19 @@
#pragma once
#include <stdint.h>
#include "double.h"
#ifdef __cplusplus
extern "C" {
#endif
double determinant_2x2(double a, double b,
double c, double d);
struct double2 cramers_rule_2x2(double a1, double b1, double c1,
double a2, double b2, double c2);
#ifdef __cplusplus
}
#endif

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 != 2023 || day != 24) { if (year != 2024 || day != 13) {
return false; return false;
} }

View File

@ -33,6 +33,8 @@ int64_t _2024_day11_part1(const char * input, int length);
int64_t _2024_day11_part2(const char * input, int length); int64_t _2024_day11_part2(const char * input, int length);
int64_t _2024_day12_part1(const char * input, int length); int64_t _2024_day12_part1(const char * input, int length);
int64_t _2024_day12_part2(const char * input, int length); int64_t _2024_day12_part2(const char * input, int length);
int64_t _2024_day13_part1(const char * input, int length);
int64_t _2024_day13_part2(const char * input, int length);
struct day_funcs solution[] = { struct day_funcs solution[] = {
{ {
@ -115,4 +117,9 @@ struct day_funcs solution[] = {
{_2024_day12_part1, _2024_day12_part2}, {_2024_day12_part1, _2024_day12_part2},
NULL, NULL,
}, },
{
2024, 13,
{_2024_day13_part1, _2024_day13_part2},
NULL,
},
}; };

View File

@ -50,4 +50,7 @@ DAY_OBJ = \
2024/day12/sample1.txt.o \ 2024/day12/sample1.txt.o \
2024/day12/sample2.txt.o \ 2024/day12/sample2.txt.o \
2024/day12/input.txt.o \ 2024/day12/input.txt.o \
2024/day12/solution.o 2024/day12/solution.o \
2024/day13/sample1.txt.o \
2024/day13/input.txt.o \
2024/day13/solution.o