day11
This commit is contained in:
parent
9271e4c3e5
commit
4547fe2238
2
Makefile
2
Makefile
@ -1,6 +1,6 @@
|
|||||||
all: $(patsubst %.cpp,%.elf,$(wildcard example/*.cpp))
|
all: $(patsubst %.cpp,%.elf,$(wildcard example/*.cpp))
|
||||||
|
|
||||||
OPT = -Og
|
OPT = -O3
|
||||||
|
|
||||||
include dreamcast/base.mk
|
include dreamcast/base.mk
|
||||||
include dreamcast/common.mk
|
include dreamcast/common.mk
|
||||||
|
4
aoc.mk
4
aoc.mk
@ -20,6 +20,10 @@ DREAMCAST_OBJ = \
|
|||||||
$(LIB)/font/dejavusansmono/dejavusansmono.data.o \
|
$(LIB)/font/dejavusansmono/dejavusansmono.data.o \
|
||||||
$(LIB)/sh7091/serial.o \
|
$(LIB)/sh7091/serial.o \
|
||||||
$(LIB)/maple/maple.o
|
$(LIB)/maple/maple.o
|
||||||
|
# libgcc/_divdi3.o \
|
||||||
|
# libgcc/_moddi3.o \
|
||||||
|
# libgcc/_udiv_qrnnd_16.o \
|
||||||
|
# libgcc/_clz.o
|
||||||
|
|
||||||
include solutions.mk
|
include solutions.mk
|
||||||
|
|
||||||
|
1
day11/input.txt
Normal file
1
day11/input.txt
Normal file
@ -0,0 +1 @@
|
|||||||
|
70949 6183 4 3825336 613971 0 15 182
|
15
day11/input.txt.h
Normal file
15
day11/input.txt.h
Normal 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
1
day11/sample1.txt
Normal file
@ -0,0 +1 @@
|
|||||||
|
125 17
|
15
day11/sample1.txt.h
Normal file
15
day11/sample1.txt.h
Normal 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
172
day11/solution.c
Normal 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);
|
||||||
|
}
|
@ -19,6 +19,8 @@
|
|||||||
#include "day9/input.txt.h"
|
#include "day9/input.txt.h"
|
||||||
#include "day10/sample1.txt.h"
|
#include "day10/sample1.txt.h"
|
||||||
#include "day10/input.txt.h"
|
#include "day10/input.txt.h"
|
||||||
|
#include "day11/sample1.txt.h"
|
||||||
|
#include "day11/input.txt.h"
|
||||||
|
|
||||||
static struct start_size sample[][2] = {
|
static struct start_size sample[][2] = {
|
||||||
{
|
{
|
||||||
@ -81,6 +83,12 @@ static struct start_size sample[][2] = {
|
|||||||
{ ( char *)&_binary_day10_sample1_txt_start,
|
{ ( char *)&_binary_day10_sample1_txt_start,
|
||||||
(uint32_t)&_binary_day10_sample1_txt_size },
|
(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[] = {
|
static struct start_size input[] = {
|
||||||
@ -104,4 +112,6 @@ static struct start_size input[] = {
|
|||||||
(uint32_t)&_binary_day9_input_txt_size },
|
(uint32_t)&_binary_day9_input_txt_size },
|
||||||
{ ( char *)&_binary_day10_input_txt_start,
|
{ ( char *)&_binary_day10_input_txt_start,
|
||||||
(uint32_t)&_binary_day10_input_txt_size },
|
(uint32_t)&_binary_day10_input_txt_size },
|
||||||
|
{ ( char *)&_binary_day11_input_txt_start,
|
||||||
|
(uint32_t)&_binary_day11_input_txt_size },
|
||||||
};
|
};
|
||||||
|
2
runner.c
2
runner.c
@ -32,7 +32,7 @@ bool runner_tick(struct runner_state * runner_state)
|
|||||||
int part = tick % 2;
|
int part = tick % 2;
|
||||||
int day = tick / 2;
|
int day = tick / 2;
|
||||||
|
|
||||||
if (day < 9)
|
if (day < 10)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
runner_state->want_render = solution[day].render != NULL;
|
runner_state->want_render = solution[day].render != NULL;
|
||||||
|
@ -21,6 +21,8 @@ int64_t day9_part1(const char * input, int length);
|
|||||||
int64_t day9_part2(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_part1(const char * input, int length);
|
||||||
int64_t day10_part2(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[] = {
|
struct day_funcs solution[] = {
|
||||||
{
|
{
|
||||||
@ -63,4 +65,8 @@ struct day_funcs solution[] = {
|
|||||||
{day10_part1, day10_part2},
|
{day10_part1, day10_part2},
|
||||||
NULL,
|
NULL,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
{day11_part1, day11_part2},
|
||||||
|
NULL,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
@ -30,4 +30,7 @@ DAY_OBJ = \
|
|||||||
day9/solution.o \
|
day9/solution.o \
|
||||||
day10/sample1.txt.o \
|
day10/sample1.txt.o \
|
||||||
day10/input.txt.o \
|
day10/input.txt.o \
|
||||||
day10/solution.o
|
day10/solution.o \
|
||||||
|
day11/sample1.txt.o \
|
||||||
|
day11/input.txt.o \
|
||||||
|
day11/solution.o
|
||||||
|
Loading…
x
Reference in New Issue
Block a user