This commit is contained in:
Zack Buhman 2024-12-11 02:59:41 -06:00
parent 9271e4c3e5
commit 4547fe2238
11 changed files with 230 additions and 3 deletions

View File

@ -1,6 +1,6 @@
all: $(patsubst %.cpp,%.elf,$(wildcard example/*.cpp))
OPT = -Og
OPT = -O3
include dreamcast/base.mk
include dreamcast/common.mk

4
aoc.mk
View File

@ -20,6 +20,10 @@ DREAMCAST_OBJ = \
$(LIB)/font/dejavusansmono/dejavusansmono.data.o \
$(LIB)/sh7091/serial.o \
$(LIB)/maple/maple.o
# libgcc/_divdi3.o \
# libgcc/_moddi3.o \
# libgcc/_udiv_qrnnd_16.o \
# libgcc/_clz.o
include solutions.mk

1
day11/input.txt Normal file
View File

@ -0,0 +1 @@
70949 6183 4 3825336 613971 0 15 182

15
day11/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_day11_input_txt_start __asm("_binary_day11_input_txt_start");
extern uint32_t _binary_day11_input_txt_end __asm("_binary_day11_input_txt_end");
extern uint32_t _binary_day11_input_txt_size __asm("_binary_day11_input_txt_size");
#ifdef __cplusplus
}
#endif

1
day11/sample1.txt Normal file
View File

@ -0,0 +1 @@
125 17

15
day11/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_day11_sample1_txt_start __asm("_binary_day11_sample1_txt_start");
extern uint32_t _binary_day11_sample1_txt_end __asm("_binary_day11_sample1_txt_end");
extern uint32_t _binary_day11_sample1_txt_size __asm("_binary_day11_sample1_txt_size");
#ifdef __cplusplus
}
#endif

172
day11/solution.c Normal file
View File

@ -0,0 +1,172 @@
#include <stdint.h>
#include "parse.h"
#include "unparse.h"
#include "printf.h"
static void split_base10(int64_t n, int digits, int64_t * a, int64_t * b)
{
int pow = 1;
digits /= 2;
while (digits-- > 0)
pow *= 10;
int64_t split = pow;
*a = n / split;
*b = n % split;
}
static int stone_rule(int64_t n, int64_t * a, int64_t * b)
{
int digits;
if (n == 0) {
*a = 1;
return 1;
} else if ((digits = digits_base10_64(n)) % 2 == 0) {
split_base10(n, digits, a, b);
return 2;
} else {
*a = n * 2024;
return 1;
}
}
struct entry {
int64_t n;
int32_t depth;
int32_t _;
int64_t value;
};
#define CACHE_LENGTH (262144)
struct cache {
struct entry entry[CACHE_LENGTH];
volatile int length;
};
static void sift_up(struct entry * e, int ix)
{
while (ix > 0) {
int parent = (ix - 1) / 2;
if (e[parent].depth < e[ix].depth || e[parent].n < e[ix].n) {
// swap parent and ix
struct entry tmp = e[parent];
e[parent] = e[ix];
e[ix] = tmp;
ix = parent;
} else {
return;
}
}
}
static int search(struct entry * e, int length, int ix, int64_t n, int32_t depth)
{
if (e[ix].depth == depth && e[ix].n == n) {
/*
uint32_t r15;
asm volatile ("mov r15,%0"
: "=r" (r15));
if (r15 < min) {
//printf("%08x\n", r15);
min = r15;
}
*/
return ix;
}
int child_l = 2 * ix + 1;
int child_r = 2 * ix + 2;
if (child_r < length && (e[child_r].depth >= depth || e[child_r].n >= n)) {
int i = search(e, length, child_r, n, depth);
if (i >= 0)
return i;
}
if (child_l < length && (e[child_l].depth >= depth || e[child_l].n >= n)) {
int i = search(e, length, child_l, n, depth);
if (i >= 0)
return i;
}
return -1;
}
static void cache_add(struct cache * cache, int64_t n, int32_t depth, int64_t value)
{
if (cache->length >= CACHE_LENGTH)
return;
int ix = cache->length;
cache->entry[ix].n = n;
cache->entry[ix].depth = depth;
cache->entry[ix].value = value;
sift_up(cache->entry, ix);
cache->length += 1;
}
static int64_t simulate_step(int64_t n, int depth, int max_depth, struct cache * cache)
{
if (depth == max_depth)
return 1;
int cache_ix = search(cache->entry, cache->length, 0, n, depth);
if (cache_ix >= 0) {
//printf("hit ix:%l %d %l\n", n, depth, cache->entry[cache_ix].value);
return cache->entry[cache_ix].value;
}
int64_t a[2];
int new_stones = stone_rule(n, &a[0], &a[1]);
int64_t sum = 0;
for (int i = 0; i < new_stones; i++) {
sum += simulate_step(a[i], depth + 1, max_depth, cache);
}
//printf("store: %l %d %l\n", n, depth, sum);
cache_add(cache, n, depth, sum);
return sum;
}
static int parse_input(const char * input, int length,
int64_t * stones)
{
const char * end = input + length;
int i = 0;
while (input < end) {
input = parse_base10_64(input, &stones[i]);
input = parse_skip(input, ' ');
input = parse_skip(input, '\n');
i += 1;
}
return i;
}
static int64_t solve(const char * input, int length, int max_depth)
{
static struct cache cache;
int64_t stones[20];
int count = parse_input(input, length, stones);
int64_t sum = 0;
for (int i = 0; i < count; i++) {
cache.length = 0;
sum += simulate_step(stones[i], 0, max_depth, &cache);
}
return sum;
}
int64_t day11_part1(const char * input, int length)
{
return solve(input, length, 25);
}
int64_t day11_part2(const char * input, int length)
{
return solve(input, length, 75);
}

View File

@ -19,6 +19,8 @@
#include "day9/input.txt.h"
#include "day10/sample1.txt.h"
#include "day10/input.txt.h"
#include "day11/sample1.txt.h"
#include "day11/input.txt.h"
static struct start_size sample[][2] = {
{
@ -81,6 +83,12 @@ static struct start_size sample[][2] = {
{ ( char *)&_binary_day10_sample1_txt_start,
(uint32_t)&_binary_day10_sample1_txt_size },
},
{
{ ( char *)&_binary_day11_sample1_txt_start,
(uint32_t)&_binary_day11_sample1_txt_size },
{ ( char *)&_binary_day11_sample1_txt_start,
(uint32_t)&_binary_day11_sample1_txt_size },
},
};
static struct start_size input[] = {
@ -104,4 +112,6 @@ static struct start_size input[] = {
(uint32_t)&_binary_day9_input_txt_size },
{ ( char *)&_binary_day10_input_txt_start,
(uint32_t)&_binary_day10_input_txt_size },
{ ( char *)&_binary_day11_input_txt_start,
(uint32_t)&_binary_day11_input_txt_size },
};

View File

@ -32,7 +32,7 @@ bool runner_tick(struct runner_state * runner_state)
int part = tick % 2;
int day = tick / 2;
if (day < 9)
if (day < 10)
return true;
runner_state->want_render = solution[day].render != NULL;

View File

@ -21,6 +21,8 @@ int64_t day9_part1(const char * input, int length);
int64_t day9_part2(const char * input, int length);
int64_t day10_part1(const char * input, int length);
int64_t day10_part2(const char * input, int length);
int64_t day11_part1(const char * input, int length);
int64_t day11_part2(const char * input, int length);
struct day_funcs solution[] = {
{
@ -63,4 +65,8 @@ struct day_funcs solution[] = {
{day10_part1, day10_part2},
NULL,
},
{
{day11_part1, day11_part2},
NULL,
},
};

View File

@ -30,4 +30,7 @@ DAY_OBJ = \
day9/solution.o \
day10/sample1.txt.o \
day10/input.txt.o \
day10/solution.o
day10/solution.o \
day11/sample1.txt.o \
day11/input.txt.o \
day11/solution.o