2024 day13
This commit is contained in:
parent
9f3fb5b481
commit
992460f534
@ -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
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
15
2024/day13/input.txt.h
Normal 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
15
2024/day13/sample1.txt
Normal 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
15
2024/day13/sample1.txt.h
Normal 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
124
2024/day13/solution.c
Normal 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;
|
||||||
|
}
|
3
Makefile
3
Makefile
@ -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
8
aoc.mk
@ -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
18
double.h
Normal 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
|
@ -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
56
linear_algebra.c
Normal 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
19
linear_algebra.h
Normal 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
|
2
runner.c
2
runner.c
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
@ -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
|
||||||
|
Loading…
x
Reference in New Issue
Block a user