This commit is contained in:
Zack Buhman 2024-12-08 01:16:05 -06:00
parent 505fee997e
commit eef69e8406
21 changed files with 368 additions and 37 deletions

View File

@ -9,6 +9,7 @@ include dreamcast/headers.mk
MAKEFILE_PATH := $(patsubst %/,%,$(dir $(abspath $(firstword $(MAKEFILE_LIST)))))
CFLAGS += -I$(MAKEFILE_PATH)
CFLAGS += -I$(MAKEFILE_PATH)/dreamcast/
CFLAGS += -Wno-char-subscripts
LIB ?= $(MAKEFILE_PATH)/dreamcast
include aoc.mk

4
aoc.mk
View File

@ -3,7 +3,9 @@ OBJ = \
heapsort.o \
printf.o \
runner.o \
unparse.o
unparse.o \
cartesian.o \
array.o
DREAMCAST_OBJ = \
runner_dreamcast.o \

19
array.c Normal file
View File

@ -0,0 +1,19 @@
#include "array.h"
int array_sum_char(char * a, int length)
{
int sum = 0;
for (int i = 0; i < length; i++) {
sum += a[i];
}
return sum;
}
int array_sum_int(int * a, int length)
{
int sum = 0;
for (int i = 0; i < length; i++) {
sum += a[i];
}
return sum;
}

12
array.h Normal file
View File

@ -0,0 +1,12 @@
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
int array_sum_char(char * a, int length);
int array_sum_int(int * a, int length);
#ifdef __cplusplus
}
#endif

13
cartesian.c Normal file
View File

@ -0,0 +1,13 @@
#include <stdbool.h>
#include "cartesian.h"
bool cartesian_inside(int width, int height,
int x, int y)
{
return
x >= 0 &&
y >= 0 &&
x < width &&
y < height ;
}

12
cartesian.h Normal file
View File

@ -0,0 +1,12 @@
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
bool cartesian_inside(int width, int height,
int x, int y);
#ifdef __cplusplus
}
#endif

View File

@ -3,6 +3,7 @@
#include "printf.h"
#include "parse.h"
#include "cartesian.h"
enum offset_type {
N,
@ -26,18 +27,6 @@ static char offsets[][2] = {
[SE] = { 1, 1},
};
static bool xy_inside(int width, int height,
int x, int y)
{
if (y < 0 || x < 0)
return false;
if (x >= width)
return false;
if (y >= height)
return false;
return true;
}
static char get_char(const char * input,
int stride,
int x, int y)
@ -55,7 +44,7 @@ static bool offset_match(const char * input,
int str_length)
{
for (int i = 0; i < str_length; i++) {
if (!xy_inside(width, height, x, y))
if (!cartesian_inside(width, height, x, y))
return false;
char c = get_char(input, stride, x, y);

View File

@ -4,6 +4,7 @@
#include "printf.h"
#include "parse.h"
#include "cartesian.h"
#include "solution.h"
@ -26,22 +27,12 @@ static struct position find_guard(const char * input, int length,
return (struct position){x, y};
}
static bool position_inside_map(int width, int height,
int x, int y)
{
return
x >= 0 &&
y >= 0 &&
x < width &&
y < height ;
}
static bool position_contains_obstacle(const char * input,
int stride,
int width, int height,
int x, int y)
{
if (!position_inside_map(width, height, x, y))
if (!cartesian_inside(width, height, x, y))
return false;
char c = input[y * stride + x];
@ -151,8 +142,8 @@ int64_t day6_part1(const char * input, int length)
day6_state.step = false;
*/
bool guard_inside_map = position_inside_map(width, height,
guard.position.x, guard.position.y);
bool guard_inside_map = cartesian_inside(width, height,
guard.position.x, guard.position.y);
if (!guard_inside_map)
break;
@ -183,8 +174,8 @@ static bool speculative_obstacle_causes_loop(const char * input,
guard.position = origin;
while (true) {
bool guard_inside_map = position_inside_map(width, height,
guard.position.x, guard.position.y);
bool guard_inside_map = cartesian_inside(width, height,
guard.position.x, guard.position.y);
if (!guard_inside_map)
break;
@ -227,8 +218,8 @@ int64_t day6_part2(const char * input, int length)
for (int i = 0; i < width * height; i++) loops[i] = 0;
while (true) {
bool guard_inside_map = position_inside_map(width, height,
guard.position.x, guard.position.y);
bool guard_inside_map = cartesian_inside(width, height,
guard.position.x, guard.position.y);
if (!guard_inside_map)
break;

50
day8/input.txt Normal file
View File

@ -0,0 +1,50 @@
.....8............1r.....a....................O...
.a..............4..q.........................0...9
....a.........8...................................
.................D.....................V0.........
.....d............................................
.r..........q....................................O
..................q...........................9...
..............D..............X..................V.
........D................X.................0......
.........8............X...........................
....................J....................9..0.....
..a..B............r..W........J...............R..Q
......WD...q.....1..........Q..............R..V...
.1W...................u...........................
..............................u.............R.....
....B..............d..c..................R........
.............J..............X............V........
......1...........................3...............
......B...........d...................3...........
............8..J.......u.....3....................
...........4.............6........................
.....4v.............d.......................O.....
..........................v.2.....................
.............................................s....
..................4...M..W..................s.....
......................m...........................
...........M......................................
..b..................c............................
....................Co..........KQ.......O.s......
.................C............................s...
.......x............c............................3
........o......A....U.....Q.........5.............
...............U..................j...5...........
.....K.......U................j..........2........
.......A.v.....w.....................c...5........
..K....................................j..........
...............K.yk....B.............2............
......C....b..............x...........Y...........
.....mA..C......U.................................
........M.....A.....................2..6...5......
.............................7.......Y............
.m.M......w..v....................................
............m...........x.....Y...................
....................k....w........................
......b.....w..S....7.............................
..............S..............x...........Y........
....................S...6.........................
.y...............S..........7.6.................9.
o..........k...............b......................
yo...........k....................................

15
day8/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_day8_input_txt_start __asm("_binary_day8_input_txt_start");
extern uint32_t _binary_day8_input_txt_end __asm("_binary_day8_input_txt_end");
extern uint32_t _binary_day8_input_txt_size __asm("_binary_day8_input_txt_size");
#ifdef __cplusplus
}
#endif

12
day8/sample1.txt Normal file
View File

@ -0,0 +1,12 @@
............
........0...
.....0......
.......0....
....0.......
......A.....
............
............
........A...
.........A..
............
............

15
day8/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_day8_sample1_txt_start __asm("_binary_day8_sample1_txt_start");
extern uint32_t _binary_day8_sample1_txt_end __asm("_binary_day8_sample1_txt_end");
extern uint32_t _binary_day8_sample1_txt_size __asm("_binary_day8_sample1_txt_size");
#ifdef __cplusplus
}
#endif

158
day8/solution.c Normal file
View File

@ -0,0 +1,158 @@
#include <stdint.h>
#include "parse.h"
#include "printf.h"
#include "cartesian.h"
#include "array.h"
struct position {
char x;
char y;
};
struct antenna {
struct position position[8];
char count;
};
#define FIRST_ANTENNA '0'
#define LAST_ANTENNA 'z'
#define ANTENNA_TYPES ((LAST_ANTENNA - FIRST_ANTENNA) + 1)
void parse_antennas(const char * input, int length, struct antenna * antennas)
{
int x = 0;
int y = 0;
for (int i = 0; i < length; i++) {
char c = input[i];
if (c >= FIRST_ANTENNA && c <= LAST_ANTENNA) {
struct antenna * ant = &antennas[c - FIRST_ANTENNA];
ant->position[ant->count++] = (struct position){x, y};
}
if (c == '\n') {
x = 0;
y += 1;
} else {
x += 1;
}
}
}
struct position vector(struct position a, struct position b)
{
return (struct position){b.x - a.x, b.y - a.y};
}
void part1_antinodes(int width, int height,
struct position p1, struct position p2,
char * antinodes)
{
struct position slope = vector(p1, p2);
struct position a[2] = {
{
p1.x - slope.x,
p1.y - slope.y,
},
{
p2.x + slope.x,
p2.y + slope.y,
}
};
for (int k = 0; k < 2; k++) {
if (cartesian_inside(width, height, a[k].x, a[k].y)) {
antinodes[a[k].y * width + a[k].x] = 1;
}
}
}
void interpolate_antinodes(int width,
int height,
struct position ant,
struct position slope,
char * antinodes)
{
int x = ant.x;
int y = ant.y;
while (true) {
if (!cartesian_inside(width, height, x, y))
break;
antinodes[y * width + x] = 1;
x -= slope.x;
y -= slope.y;
}
}
void part2_antinodes(int width, int height,
struct position p1, struct position p2,
char * antinodes)
{
struct position slope = vector(p1, p2);
interpolate_antinodes(width, height, p1, (struct position){-slope.x, -slope.y}, antinodes);
interpolate_antinodes(width, height, p2, (struct position){ slope.x, slope.y}, antinodes);
}
typedef void (* part_solver)(int width, int height,
struct position p1, struct position p2,
char * antinodes);
void find_antinodes(int width, int height,
const struct antenna * antennas,
char * antinodes,
part_solver func)
{
for (int t = FIRST_ANTENNA; t <= LAST_ANTENNA; t++) {
const struct antenna * ant = &antennas[t - FIRST_ANTENNA];
for (int i = 0; i < ant->count; i++) {
for (int j = i + 1; j < ant->count; j++) {
func(width, height,
ant->position[i], ant->position[j],
antinodes);
}
}
}
}
int64_t day8_part1(const char * input, int length)
{
int stride = parse_stride(input, length);
int height = parse_height(input, length);
int width = stride - 1;
struct antenna antennas[ANTENNA_TYPES];
for (int i = 0; i < ANTENNA_TYPES; i++)
antennas[i].count = 0;
char antinodes[width * height];
for (int i = 0; i < width * height; i++)
antinodes[i] = 0;
parse_antennas(input, length, antennas);
find_antinodes(width, height, antennas, antinodes, part1_antinodes);
return array_sum_char(antinodes, width * height);
}
int64_t day8_part2(const char * input, int length)
{
int stride = parse_stride(input, length);
int height = parse_height(input, length);
int width = stride - 1;
struct antenna antennas[ANTENNA_TYPES];
for (int i = 0; i < ANTENNA_TYPES; i++)
antennas[i].count = 0;
char antinodes[width * height];
for (int i = 0; i < width * height; i++)
antinodes[i] = 0;
parse_antennas(input, length, antennas);
find_antinodes(width, height, antennas, antinodes, part2_antinodes);
return array_sum_char(antinodes, width * height);
}

4
gen.sh
View File

@ -15,12 +15,12 @@ if [ ! -z "$day" ]; then
cat <<EOF > day${day}/solution.c
#include <stdint.h>
int day${day}_part1(const char * input, int length)
int64_t day${day}_part1(const char * input, int length)
{
return -1;
}
int day${day}_part2(const char * input, int length)
int64_t day${day}_part2(const char * input, int length)
{
return -1;
}

View File

@ -13,6 +13,8 @@
#include "day6/input.txt.h"
#include "day7/sample1.txt.h"
#include "day7/input.txt.h"
#include "day8/sample1.txt.h"
#include "day8/input.txt.h"
static struct start_size sample[][2] = {
{
@ -57,6 +59,12 @@ static struct start_size sample[][2] = {
{ ( char *)&_binary_day7_sample1_txt_start,
(uint32_t)&_binary_day7_sample1_txt_size },
},
{
{ ( char *)&_binary_day8_sample1_txt_start,
(uint32_t)&_binary_day8_sample1_txt_size },
{ ( char *)&_binary_day8_sample1_txt_start,
(uint32_t)&_binary_day8_sample1_txt_size },
},
};
static struct start_size input[] = {
@ -74,4 +82,6 @@ static struct start_size input[] = {
(uint32_t)&_binary_day6_input_txt_size },
{ ( char *)&_binary_day7_input_txt_start,
(uint32_t)&_binary_day7_input_txt_size },
{ ( char *)&_binary_day8_input_txt_start,
(uint32_t)&_binary_day8_input_txt_size },
};

View File

@ -11,6 +11,7 @@ enum format_type {
FORMAT_BASE10_64,
FORMAT_BASE16,
FORMAT_STRING,
FORMAT_CHAR,
FORMAT_PERCENT,
};
@ -48,6 +49,9 @@ static const char * parse_escape(const char * format, struct format * ft)
case 's':
ft->type = FORMAT_STRING;
return format + 1;
case 'c':
ft->type = FORMAT_CHAR;
return format + 1;
case '%':
ft->type = FORMAT_PERCENT;
return format + 1;
@ -105,6 +109,12 @@ void _printf(const char * format, ...)
}
}
break;
case FORMAT_CHAR:
{
const int c = va_arg(args, const int);
global_output_buffer.buf[global_output_buffer.buf_ix++] = (char)c;
}
break;
case FORMAT_PERCENT:
global_output_buffer.buf[global_output_buffer.buf_ix++] = '%';
break;

View File

@ -10,6 +10,8 @@ void _printf(const char * format, ...);
#define printf(...) _printf(__VA_ARGS__)
#endif
void print_char(char c);
struct output_buffer {
int buf_ix;
char buf[16 * 1024];

View File

@ -18,17 +18,20 @@ struct day_funcs {
#include "runner.inc"
const int solution_days = (sizeof (solution)) / (sizeof (solution[0]));
const int solution_ticks = solution_days * 2;
bool runner_tick(struct runner_state * runner_state)
{
int part = runner_state->tick % 2;
int day = runner_state->tick / 2;
int tick = (solution_ticks - 1) - runner_state->tick;
if (day >= solution_days) {
if (tick < 0) {
runner_state->want_render = false;
return true;
}
int part = tick % 2;
int day = tick / 2;
runner_state->want_render = solution[day].render != NULL;
char * buf;

View File

@ -15,6 +15,8 @@ void day6_render(const struct font * font,
const void * maple_ft0_data);
int64_t day7_part1(const char * input, int length);
int64_t day7_part2(const char * input, int length);
int64_t day8_part1(const char * input, int length);
int64_t day8_part2(const char * input, int length);
struct day_funcs solution[] = {
{
@ -45,4 +47,8 @@ struct day_funcs solution[] = {
{day7_part1, day7_part2},
NULL,
},
{
{day8_part1, day8_part2},
NULL,
},
};

View File

@ -444,3 +444,11 @@ int main()
serial::string("return\n");
}
extern "C"
void print_char(char c)
{
global_output_buffer.buf[global_output_buffer.buf_ix++] = c;
serial::character(c);
}

View File

@ -21,4 +21,7 @@ DAY_OBJ = \
day6/solution.o \
day7/sample1.txt.o \
day7/input.txt.o \
day7/solution.o
day7/solution.o \
day8/sample1.txt.o \
day8/input.txt.o \
day8/solution.o