This commit is contained in:
Zack Buhman 2024-12-07 00:16:54 -06:00
parent 4db7412d48
commit 6f5ecad326
22 changed files with 1049 additions and 74 deletions

3
aoc.mk
View File

@ -14,7 +14,8 @@ DREAMCAST_OBJ = \
$(LIB)/holly/ta_fifo_polygon_converter.o \
$(LIB)/holly/video_output.o \
$(LIB)/font/dejavusansmono/dejavusansmono.data.o \
$(LIB)/sh7091/serial.o
$(LIB)/sh7091/serial.o \
$(LIB)/maple/maple.o
include solutions.mk

View File

@ -23,7 +23,7 @@ static int parse_input(const char * input, int length, struct list * list)
return i;
}
int day1_part1(char * input, int length)
int day1_part1(const char * input, int length)
{
struct list list;
int list_length = parse_input(input, length, &list);
@ -40,7 +40,7 @@ int day1_part1(char * input, int length)
return sum;
}
int day1_part2(char * input, int length)
int day1_part2(const char * input, int length)
{
struct list list;
int list_length = parse_input(input, length, &list);

View File

@ -53,7 +53,7 @@ static bool report_safe(struct report * report, int skip)
if (abs(rate) < 1 || abs(rate) > 3)
return false; // unsafe
int sign = int_sign(sign);
int sign = int_sign(rate);
if (last_sign != 0 && sign != last_sign)
return false; // unsafe
@ -64,7 +64,7 @@ static bool report_safe(struct report * report, int skip)
return true;
}
int day2_part1(char * input, int length)
int day2_part1(const char * input, int length)
{
struct report report[1000];
@ -78,7 +78,7 @@ int day2_part1(char * input, int length)
return sum;
}
int day2_part2(char * input, int length)
int day2_part2(const char * input, int length)
{
struct report report[1000];

View File

@ -88,7 +88,7 @@ int parse_input(const char * input, int length, struct instruction * ins)
return i;
}
int day3_part1(char * input, int length)
int day3_part1(const char * input, int length)
{
struct instruction ins[1000];
@ -103,7 +103,7 @@ int day3_part1(char * input, int length)
return sum;
}
int day3_part2(char * input, int length)
int day3_part2(const char * input, int length)
{
struct instruction ins[1000];

View File

@ -1,31 +1,7 @@
#include <stdbool.h>
#include "printf.h"
static int parse_stride(char * input, int length)
{
for (int i = 0; i < length; i++) {
if (input[i] == '\n') {
return i + 1;
}
}
return -1;
}
static int parse_height(char * input, int length)
{
int rows = 0;
int i;
for (i = 0; i < length; i++) {
if (input[i] == '\n') {
rows += 1;
}
}
if (input[i-1] != '\n') {
rows += 1;
}
return rows;
}
#include "parse.h"
enum offset_type {
N,
@ -61,7 +37,7 @@ static bool xy_inside(int width, int height,
return true;
}
static char get_char(char * input,
static char get_char(const char * input,
int stride,
int x, int y)
{
@ -69,7 +45,7 @@ static char get_char(char * input,
return input[ix];
}
static bool offset_match(char * input,
static bool offset_match(const char * input,
int stride,
int width, int height,
int x, int y,
@ -92,7 +68,7 @@ static bool offset_match(char * input,
return true;
}
static bool offset_match_centered(char * input,
static bool offset_match_centered(const char * input,
int stride,
int width, int height,
int x, int y,
@ -117,7 +93,7 @@ static bool offset_match_centered(char * input,
str_length);
}
static bool offset_match_cross(char * input,
static bool offset_match_cross(const char * input,
int stride,
int width, int height,
int x, int y,
@ -155,7 +131,7 @@ static bool offset_match_cross(char * input,
return match1 || match2;
}
int day4_part1(char * input, int length)
int day4_part1(const char * input, int length)
{
int stride = parse_stride(input, length);
int height = parse_height(input, length);
@ -183,7 +159,7 @@ int day4_part1(char * input, int length)
return match_count;
}
int day4_part2(char * input, int length)
int day4_part2(const char * input, int length)
{
int stride = parse_stride(input, length);
int height = parse_height(input, length);

130
day6/input.txt Normal file
View File

@ -0,0 +1,130 @@
.........................#...........#.#...#...............#..............##.....................#...........#..#.........#.......
.....................#.................#.......#.........................#...........#.#.......#..................................
.........#...........#........#.........#.........#...........#........................................#.........................#
.......#.........................#...........................#.............#......................................................
..................#................##...............#.#.....................##............#.......................................
......#...#................#..................................................................#....#.#............................
.......##................#........#..#.......#......................................#........#............#......###..........#...
.....................#....................................................#...........#..#...#..........................#.........
...........#....#...........................#.#...............#..#....................................#..............#......#.....
.....#........##...............#.......#..#..............................................#..........................#.............
.#.........#.#...........................#..........................#......................#...........#........#.................
.................................................................#..#.#.......#..#................................................
...............................................#.......#...................#....................#.................................
.......#......#......#......................#...............................#.....##........#...........#......#..................
........................................................................................................#.....#.#.................
..#...............................#.#..................................#.............#............................................
..............#..........................................#.....#.....#..........................#....#.........#..................
...................................#........................................#................#...........##.....#....#............
.#.....................................#.......#........................#...................##............#.......................
.#..................#...........#...........................................................................................#.....
........................#...................................................##.................................#..#..........##...
........#............................#.......#...........................#.#...#...................................#.....#........
...............................#............#.....#......................#.......#...#........................#...................
.........#.............#.................................................#.......................................#....#...........
...................................................................#...#.................................#...................#....
...#.....................#...#...............#..................................................#...#...#.........................
...................#........#....#....#..#..#...................#.........#..................#..#....#.......#.#.................#
..............................#........................................#......#.....#..............##................#............
............#..#.............#.......#........................................................##........#.....#...................
.....#.............................................................#...#.#.#.............................#..#.#...........#.......
.......#....#............................................#.................................#...................................#..
..#.................#.......#..........................#........................................#...............#..............#..
....#.#...................#............................#..#.......................................................................
.......................#...............#..............#......#......................#.....................#..............#........
.#..........#.......................................................................#....................................#........
.#.......#..................................................................#.....................................................
..................................................#.............#.............................................#................#.#
.......................#......#....#................#......................................................#.......#.........#....
..........................#.#........................................................#......#................................#....
....................................................................#...............................#.............................
..#...........#..............................#..#....#............................#...............##..............#...#...#...#..#
...................................#................................................................#....#...................#....
..#....#........#..##....#........................#...#...................................#.......................................
...................#................................................................................................#.............
.......#........#................#...#.......................................................................#....................
..............#....................#..........................##.........#.....................................#..................
.........................................................................#.................#........................#.............
.............................#..........#.......................................................#......................#..........
............###....................................................................#.......................#......................
........#........#...........#.............................#....................#..........#.........................#.#.....#....
.........................................................................................................#..#.....................
#.#.....#..........................................................#.....................#........................................
........##..........#....................................................#..#........#.......#........#................#..........
.............................................#..........................#.........#........................#......................
...........................##.............#........................#.#........................#..#................#.....#........#
#...#..............................................#........#...................................................#.................
.............#................#............................#............#.........................................................
#..........................#............#.....................#.....#.................#......#...##...#.............#.#...........
.....................#...#..#....#...................................#....................#..............#........#...............
.......................#.................#...........#....#.......#...........................................#..#................
.........#...........#.#.........#.........................#.....#................................................................
....................#........#...................................................................#............#..#.#.#............
..........#.......................#.......................#.......................................................................
......................................#......#............................#..............................................#........
.....................#...#.................#.............................#....#...................................................
..............##...................................................................#......................................##......
.....#....#...............................................#.......#.##........#.#.............#...............#...................
....................................#......................#........#.......................................................#.....
.....#.........................................#.....................#.............#.................#..................#.........
................................#.........#..#............................................#.........................#.............
....#.#.....................#......#...................................#..........................................#..#.....#...#..
.........##.......................#..........................................#.........................#...##.....................
...............................................................#................................................................#.
............#.........................................##.......................................#..................................
.............................#..............................#..................#.........#.....#..................................
..........................................................#...#.....#..................#................................#.........
......#...................#.........................................................................................#.............
#...............................#...........................#.....................................................................
.......#........#.................................................#.......................................................#.......
.#......................................................#..............#..................................#...........#...........
.............#..#.#.......................#..........#......#.##.........................................................#..#.....
.......#...............#........#......................................................................#..#...........#...........
............#.........................................#................................................#...................#......
............#...........................................#.#.......#....................................#..........................
...........................................#.........................................................#..............#.............
..................#..#....................................................#..................#....................................
..#........................#........#.............................................................................................
.............#........#......................#.......................................#...#....#............................#......
............#.......#.............#...#...........#.#.................................#.................##........................
.....................................................................................#.........#.......................#.....#....
.................#................................#..#....#......#..........................................#.....#...............
..#...............................#........................................................#.......#...#............#.............
#.........#..#..#.....................................#....................................#................#.................#...
.......................#..#...#............................................................................#..#.....#.......##....
..........#............#.......................#.........................^......#.#...................................#...........
...##........................##..........#..........#.................#...............#...........#.....##........................
..............#............#..........................#....#...........#......#......#......................#.....................
......#.....#....................................................#............#.#......................................#..........
......#.............................#......................#...............................#........#.............................
.#..........#.............................................#.............................................#.........................
...............................##.................................................................................................
.....................#................................................#...............#............#...............#.....#.....#..
..................#...........................................................................#...........#...................#...
##..............................#.#...#.#...............................#...........#.#...................#.......................
......................#.........#...................................#.................#...........................................
.......................#............................................................................#.........##...........#......
.....................................................................#.......#.....#.......................................#......
#....................................#........#.#.................................................................##.....#........
..............#..............................#......#..........###.........#................#..............#..................#...
..................................#..............................#.................##.............................#...#...........
...............#......#........................#....#........#............#.........#..........#..............#......#............
...#...........#........#...#...........................#.............#.....................................#.....................
..............###............#...........................................................#.............#.........##..#............
............#................................................#.......#..................#....#....................................
.........#.#...#.....#...........................#.....##......#.....................#..#........#......#.........................
.#....#.......#.......................#.................................................................#.......#..............#..
...................#................................................................#.............#...#...........#.........#.....
.......#.#.......#.......................#....#.....#...............#...#.....#...........................................#.......
.......#........#...........................................#...........#.........................#....#.......#..................
..................................#.#.................#.#............................................#...........#....#...........
....##......#.............#...................................#...#.........#...........................#......#..................
.........................#......#....#...#........................................................................................
...#...............#............................................................................#...........................#.....
....##.#..............................................#............#................#................................#......#.....
.........#...........................................#...#.......##..............................#................................
..................#..........#......#.......#......................................#........#...............#......#...........##.
........................................#......#..........#......................................................................#
..............#...#...................#.....#..........................................................#..............#......#....
...#........#........................#...#................#........#.............................##..........................#....
............#............................#.#........................#.................................#..........................#

15
day6/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_day6_input_txt_start __asm("_binary_day6_input_txt_start");
extern uint32_t _binary_day6_input_txt_end __asm("_binary_day6_input_txt_end");
extern uint32_t _binary_day6_input_txt_size __asm("_binary_day6_input_txt_size");
#ifdef __cplusplus
}
#endif

127
day6/pos.py Normal file
View File

@ -0,0 +1,127 @@
s = """
....#.....
....+---+#
....|...|.
..#.|...|.
....|..#|.
....|...|.
.#.O^---+.
........#.
#.........
......#...
....#.....
....+---+#
....|...|.
..#.|...|.
..+-+-+#|.
..|.|.|.|.
.#+-^-+-+.
......O.#.
#.........
......#...
....#.....
....+---+#
....|...|.
..#.|...|.
..+-+-+#|.
..|.|.|.|.
.#+-^-+-+.
.+----+O#.
#+----+...
......#...
....#.....
....+---+#
....|...|.
..#.|...|.
..+-+-+#|.
..|.|.|.|.
.#+-^-+-+.
..|...|.#.
#O+---+...
......#...
....#.....
....+---+#
....|...|.
..#.|...|.
..+-+-+#|.
..|.|.|.|.
.#+-^-+-+.
....|.|.#.
#..O+-+...
......#...
....#.....
....+---+#
....|...|.
..#.|...|.
..+-+-+#|.
..|.|.|.|.
.#+-^-+-+.
.+----++#.
#+----++..
......#O..
"""
ss = [i.strip() for i in s.strip().split('\n\n')]
ll = set([
(4, 3),
(7, 1),
(3, 6),
(6, 7),
(3, 8),
(1, 8),
(7, 7),
(7, 9),
])
def find_o(m):
x = 0
y = 0
ix = 0
while ix < len(m):
if m[ix] == 'O':
return (x, y)
if m[ix] == '\n':
y += 1
x = 0
else:
x += 1
ix += 1
oo = set([find_o(m) for m in ss])
print(oo)
print(ll - oo)
0123456789
0 ....#.....
1 ....|--O.#
2 ....|.|...
3 ..#.|.|...
4 ....|.|#..
5 ....|.|...
6 .#--------
7 .|....|.#.
8 #-----|...
9 ......#...
0123456789
0 ....#.....
1 .........#
2 ..........
3 ..#.......
4 .......#..
5 ..........
6 .#........
7 ........#.
8 #.........
9 ......#...

223
day6/render.cpp Normal file
View File

@ -0,0 +1,223 @@
#include "holly/isp_tsp.hpp"
#include "holly/ta_parameter.hpp"
#include "holly/ta_global_parameter.hpp"
#include "holly/ta_vertex_parameter.hpp"
#include "sh7091/store_queue.hpp"
#include "sh7091/serial.hpp"
#include "math/vec2.hpp"
#include "font/font.h"
#include "maple/maple_bus_ft0.hpp"
#include "solution.h"
extern void glyph_start(const uint32_t texture_width, uint32_t texture_height);
extern int32_t transform_char(const uint32_t texture_width,
const uint32_t texture_height,
const uint32_t first_char_code,
const glyph * glyphs,
const char c,
int32_t horizontal_advance,
int32_t vertical_advance);
using vec2 = vec<2, float>;
constexpr vec2 arrow_vertices[] = {
{-0.1, -0.15},
{ 0.0, -0.45},
{ 0.1, -0.15},
};
constexpr vec2 square_vertices[] = {
{0.475, 0.525},
{0.525, 0.525},
{0.475, 0.475},
{0.525, 0.475},
};
vec2 rotate(vec2 v, int n) {
switch (n) {
case 0: return {v.x, v.y};
case 1: return {-v.y, v.x};
case 2: return {-v.x, -v.y};
case 3: return {v.y, -v.x};
}
__builtin_unreachable();
}
void polygon_start()
{
const uint32_t parameter_control_word = para_control::para_type::polygon_or_modifier_volume
| para_control::list_type::translucent
| obj_control::col_type::packed_color;
const uint32_t isp_tsp_instruction_word = isp_tsp_instruction_word::depth_compare_mode::always
| isp_tsp_instruction_word::culling_mode::no_culling;
const uint32_t tsp_instruction_word = tsp_instruction_word::src_alpha_instr::one
| tsp_instruction_word::dst_alpha_instr::zero
| tsp_instruction_word::fog_control::no_fog;
*reinterpret_cast<ta_global_parameter::polygon_type_0 *>(store_queue) =
ta_global_parameter::polygon_type_0(parameter_control_word,
isp_tsp_instruction_word,
tsp_instruction_word,
0, // texture_control_word
0, // data_size_for_sort_dma
0 // next_address_for_sort_dma
);
sq_transfer_32byte(ta_fifo_polygon_converter);
}
constexpr int scale = 45;
void arrow(int cx, int cy, int rotation, uint32_t base_color)
{
float z = 1.0 / 10.0;
for (int i = 0; i < 3; i++) {
bool end_of_strip = i == 2;
vec2 v = arrow_vertices[i];
v = rotate(v, rotation);
v.x *= scale;
v.y *= scale;
v.x += scale / 2.0 + (640 - (scale * 10)) / 2 + cx * scale;
v.y += scale / 2.0 + (480 - (scale * 10)) / 2 + cy * scale;
*reinterpret_cast<ta_vertex_parameter::polygon_type_0 *>(store_queue) =
ta_vertex_parameter::polygon_type_0(polygon_vertex_parameter_control_word(end_of_strip),
v.x, v.y, z,
base_color);
sq_transfer_32byte(ta_fifo_polygon_converter);
}
}
void border(int cx, int cy, int rotation)
{
uint32_t base_color = 0xff'ff00ff;
float z = 1.0 / 10.0;
for (int i = 0; i < 4; i++) {
bool end_of_strip = i == 3;
vec2 v = square_vertices[i];
v = rotate(v, rotation);
v.x *= scale;
v.y *= scale;
v.x += scale / 2.0 + (640 - (scale * 10)) / 2 + cx * scale;
v.y += scale / 2.0 + (480 - (scale * 10)) / 2 + cy * scale;
*reinterpret_cast<ta_vertex_parameter::polygon_type_0 *>(store_queue) =
ta_vertex_parameter::polygon_type_0(polygon_vertex_parameter_control_word(end_of_strip),
v.x, v.y, z,
base_color);
sq_transfer_32byte(ta_fifo_polygon_converter);
}
}
void glyph(const struct font * font,
const struct glyph * glyphs,
int cx, int cy,
char c)
{
int32_t horizontal_advance = font->face_metrics.max_advance * 2 / 5; // 26.6 fixed point
int32_t vertical_advance = font->face_metrics.height * 5 / 4; // 26.6 fixed point
int x = (640 - (scale * 10)) / 2 + cx * scale;
int y = (480 - (scale * 10)) / 2 + cy * scale;
horizontal_advance += (x << 6);
vertical_advance += (y << 6);
transform_char(font->texture_width,
font->texture_height,
font->first_char_code,
glyphs,
c,
horizontal_advance,
vertical_advance);
}
extern "C" struct solution_state day6_state;
void a_press()
{
serial::string("press\n");
serial::integer<uint8_t>(day6_state.part);
day6_state.step = true;
}
extern "C"
void day6_render(const struct font * font,
const struct glyph * glyphs,
ft0::data_transfer::data_format * maple_ft0_data)
{
return;
static bool last_a = true;
if (maple_ft0_data[0].digital_button != 0) {
bool a = ft0::data_transfer::digital_button::a(maple_ft0_data[0].digital_button) == 0;
if (a && !last_a) {
a_press();
}
last_a = a;
}
polygon_start();
for (int y = 0; y < 10; y++) {
for (int x = 0; x < 10; x++) {
border(x, y, 0);
border(x, y, 2);
}
}
border(9, 0, 3);
border(0, 9, 1);
uint32_t base_color[2] = {
0xff'00ffff,
0xff'ff0000,
};
for (int y = 0; y < day6_state.height; y++) {
for (int x = 0; x < day6_state.width; x++) {
int ix = y * day6_state.width + x;
unsigned char c = day6_state.visited[ix];
for (int i = 0; i < 4; i++) {
if (c & (1 << i)) {
arrow(x,
y,
i,
0xff'005555);
}
}
}
}
arrow(day6_state.guard[0]->position.x,
day6_state.guard[0]->position.y,
day6_state.guard[0]->facing,
base_color[0]);
// render text
glyph_start(font->texture_width, font->texture_height);
glyph(font, glyphs, 11, 0, '0' + day6_state.part);
for (int y = 0; y < day6_state.height; y++) {
for (int x = 0; x < day6_state.width; x++) {
int ix = y * day6_state.stride + x;
char c = day6_state.input[ix];
if (c == '#')
glyph(font, glyphs, x, y, '#');
}
}
}

10
day6/sample1.txt Normal file
View File

@ -0,0 +1,10 @@
....#.....
.........#
..........
..#.......
.......#..
..........
.#..^.....
........#.
#.........
......#...

15
day6/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_day6_sample1_txt_start __asm("_binary_day6_sample1_txt_start");
extern uint32_t _binary_day6_sample1_txt_end __asm("_binary_day6_sample1_txt_end");
extern uint32_t _binary_day6_sample1_txt_size __asm("_binary_day6_sample1_txt_size");
#ifdef __cplusplus
}
#endif

256
day6/solution.c Normal file
View File

@ -0,0 +1,256 @@
#include <stdbool.h>
#include <stddef.h>
#include "printf.h"
#include "parse.h"
#include "solution.h"
static struct position find_guard(const char * input, int length,
int stride)
{
int x = 0;
int y = 0;
for (int i = 0; i < length; i++) {
if (input[i] == '^') {
break;
}
x += 1;
if (x >= stride) {
x = 0;
y += 1;
}
}
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))
return false;
char c = input[y * stride + x];
return c == '#';
}
static enum facing turn(enum facing facing)
{
switch (facing) {
case UP: return RIGHT;
case RIGHT: return DOWN;
case DOWN: return LEFT;
case LEFT: return UP;
}
__builtin_unreachable();
}
static struct position move(enum facing facing, int x, int y)
{
switch (facing) {
case UP: return (struct position){x , y - 1};
case DOWN: return (struct position){x , y + 1};
case LEFT: return (struct position){x - 1, y };
case RIGHT: return (struct position){x + 1, y };
}
__builtin_unreachable();
}
static void guard_move(struct guard * guard, bool collision)
{
if (collision) {
guard->facing = turn(guard->facing);
} else {
guard->position = move(guard->facing, guard->position.x, guard->position.y);
}
}
static bool guard_collision(const char * input,
int stride,
int width, int height,
const struct guard * guard)
{
struct position position = move(guard->facing, guard->position.x, guard->position.y);
return position_contains_obstacle(input, stride, width, height, position.x, position.y);
}
static bool guard_collision_obstacle(const char * input,
int stride,
int width, int height,
const struct guard * guard,
struct position obstacle)
{
struct position position = move(guard->facing, guard->position.x, guard->position.y);
return (position.x == obstacle.x && position.y == obstacle.y)
|| position_contains_obstacle(input, stride, width, height, position.x, position.y);
}
static int sum(unsigned char * l, int length)
{
int acc = 0;
for (int i = 0; i < length; i++) {
acc += (int)(l[i] > 0);
}
return acc;
}
struct solution_state day6_state = {0};
void state_init(int part,
const char * input,
int stride,
int width,
int height,
unsigned char * visited,
struct guard * guard)
{
day6_state.part = part;
day6_state.input = input;
day6_state.stride = stride;
day6_state.width = width;
day6_state.height = height;
day6_state.visited = visited;
day6_state.guard[0] = guard;
}
int day6_part1(const char * input, int length)
{
int stride = parse_stride(input, length);
int height = parse_height(input, length);
int width = stride - 1;
unsigned char visited[height * width];
for (int i = 0; i < width * height; i++) visited[i] = 0;
struct guard guard;
guard.facing = UP;
guard.position = find_guard(input, length, stride);
state_init(1, input, stride, width, height, visited, &guard);
while (true) {
/*
if (!day6_state.step)
continue;
day6_state.step = false;
*/
bool guard_inside_map = position_inside_map(width, height,
guard.position.x, guard.position.y);
if (!guard_inside_map)
break;
visited[guard.position.y * width + guard.position.x] |= (1 << (int)guard.facing);
bool collision = guard_collision(input,
stride,
width, height,
&guard);
guard_move(&guard, collision);
}
return sum(visited, height * width);
}
static bool speculative_obstacle_causes_loop(const char * input,
int stride,
int width, int height,
unsigned char * visited,
struct position origin,
struct position obstacle)
{
// reset visited
for (int i = 0; i < width * height; i++) visited[i] = 0;
struct guard guard;
guard.facing = UP;
guard.position = origin;
while (true) {
bool guard_inside_map = position_inside_map(width, height,
guard.position.x, guard.position.y);
if (!guard_inside_map)
break;
// is this a loop?
if (visited[guard.position.y * width + guard.position.x] & (1 << (int)guard.facing))
return true;
visited[guard.position.y * width + guard.position.x] |= (1 << (int)guard.facing);
bool collision = guard_collision_obstacle(input,
stride,
width, height,
&guard,
obstacle);
guard_move(&guard, collision);
}
return false;
}
int day6_part2(const char * input, int length)
{
int stride = parse_stride(input, length);
int height = parse_height(input, length);
int width = stride - 1;
unsigned char visited[height * width];
for (int i = 0; i < width * height; i++) visited[i] = 0;
struct position origin = find_guard(input, length, stride);
struct guard guard;
guard.facing = UP;
guard.position = origin;
state_init(2, input, stride, width, height, visited, &guard);
unsigned char obstacles[height * width];
for (int i = 0; i < width * height; i++) obstacles[i] = 0;
unsigned char loops[height * width];
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);
if (!guard_inside_map)
break;
bool collision = guard_collision(input,
stride,
width, height,
&guard);
if (!collision) {
struct position obstacle = move(guard.facing, guard.position.x, guard.position.y);
if (obstacles[obstacle.y * width + obstacle.x] == 0) {
obstacles[obstacle.y * width + obstacle.x] = 1;
bool loop = speculative_obstacle_causes_loop(input,
stride,
width, height,
visited,
origin,
obstacle);
loops[obstacle.y * width + obstacle.x] |= loop;
}
}
guard_move(&guard, collision);
}
return sum(loops, height * width);
}

39
day6/solution.h Normal file
View File

@ -0,0 +1,39 @@
#pragma once
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
struct position {
int x;
int y;
};
enum facing {
UP,
RIGHT,
DOWN,
LEFT,
};
struct guard {
struct position position;
enum facing facing;
};
struct solution_state {
bool step;
int part;
const char * input;
int stride;
int width;
int height;
struct guard * guard[2];
unsigned char * visited;
};
#ifdef __cplusplus
}
#endif

27
gen.sh
View File

@ -13,12 +13,12 @@ if [ ! -z "$day" ]; then
mkdir -p day${day}
cat <<EOF > day${day}/solution.c
int day${day}_part1(char * input, int length)
int day${day}_part1(const char * input, int length)
{
return -1;
}
int day${day}_part2(char * input, int length)
int day${day}_part2(const char * input, int length)
{
return -1;
}
@ -87,18 +87,33 @@ for i in day* ; do
echo " ${i}/sample2.txt.o \\" >> solutions.mk
fi
echo " ${i}/input.txt.o \\" >> solutions.mk
if [ -f ${i}/render.cpp ]; then
echo " ${i}/render.o \\" >> solutions.mk
fi
echo -n " ${i}/solution.o" >> solutions.mk
done
echo >> solutions.mk
truncate -s0 runner.inc
for i in day* ; do
echo "int ${i}_part1(char * input, int length);" >> runner.inc
echo "int ${i}_part2(char * input, int length);" >> runner.inc
echo "int ${i}_part1(const char * input, int length);" >> runner.inc
echo "int ${i}_part2(const char * input, int length);" >> runner.inc
if [ -f ${i}/render.cpp ]; then
echo "void ${i}_render(const struct font * font," >> runner.inc
echo " const struct glyph * glyphs," >> runner.inc
echo " const void * maple_ft0_data);" >> runner.inc
fi
done
echo >> runner.inc
echo "part_func solution[][2] = {" >> runner.inc
echo "struct day_funcs solution[] = {" >> runner.inc
for i in day* ; do
echo " {${i}_part1, ${i}_part2}," >> runner.inc
echo " {" >> runner.inc
echo " {${i}_part1, ${i}_part2}," >> runner.inc
if [ -f ${i}/render.cpp ]; then
echo " ${i}_render," >> runner.inc
else
echo " NULL," >> runner.inc
fi
echo " }," >> runner.inc
done
echo "};" >> runner.inc

View File

@ -9,6 +9,8 @@
#include "day4/input.txt.h"
#include "day5/sample1.txt.h"
#include "day5/input.txt.h"
#include "day6/sample1.txt.h"
#include "day6/input.txt.h"
static struct start_size sample[][2] = {
{
@ -41,6 +43,12 @@ static struct start_size sample[][2] = {
{ ( char *)&_binary_day5_sample1_txt_start,
(uint32_t)&_binary_day5_sample1_txt_size },
},
{
{ ( char *)&_binary_day6_sample1_txt_start,
(uint32_t)&_binary_day6_sample1_txt_size },
{ ( char *)&_binary_day6_sample1_txt_start,
(uint32_t)&_binary_day6_sample1_txt_size },
},
};
static struct start_size input[] = {
@ -54,4 +62,6 @@ static struct start_size input[] = {
(uint32_t)&_binary_day4_input_txt_size },
{ ( char *)&_binary_day5_input_txt_start,
(uint32_t)&_binary_day5_input_txt_size },
{ ( char *)&_binary_day6_input_txt_start,
(uint32_t)&_binary_day6_input_txt_size },
};

25
parse.c
View File

@ -54,3 +54,28 @@ const char * parse_match(const char * s, const char * m)
}
return s;
}
int parse_stride(const char * s, int length)
{
for (int i = 0; i < length; i++) {
if (s[i] == '\n') {
return i + 1;
}
}
return -1;
}
int parse_height(const char * s, int length)
{
int rows = 0;
int i;
for (i = 0; i < length; i++) {
if (s[i] == '\n') {
rows += 1;
}
}
if (s[i-1] != '\n') {
rows += 1;
}
return rows;
}

View File

@ -7,6 +7,8 @@ extern "C" {
const char * parse_skip(const char * s, char c);
const char * parse_base10(const char * s, int * n);
const char * parse_match(const char * s, const char * m);
int parse_stride(const char * s, int length);
int parse_height(const char * s, int length);
#ifdef __cplusplus
}

View File

@ -1,10 +1,19 @@
#include <stdbool.h>
#include <stddef.h>
#include "printf.h"
#include "input.h"
#include "runner.h"
typedef int (* part_func)(char * input, int length);
typedef int (* part_func)(const char * input, int length);
typedef void (* render_func)(const struct font * font,
const struct glyph * glyphs,
const void * maple_ft0_data);
struct day_funcs {
part_func part[2];
render_func render;
};
#include "runner.inc"
const int solution_days = (sizeof (solution)) / (sizeof (solution[0]));
@ -14,14 +23,18 @@ bool runner_tick(struct runner_state * runner_state)
int part = runner_state->tick % 2;
int day = runner_state->tick / 2;
if (day >= solution_days)
if (day >= solution_days) {
runner_state->want_render = false;
return true;
}
runner_state->want_render = solution[day].render != NULL;
char * buf;
int length;
//open_sample(day + 1, part + 1, &buf, &length);
open_input(day + 1, &buf, &length);
int answer = solution[day][part](buf, length);
int answer = solution[day].part[part](buf, length);
printf("day %d part %d: %d\n", day + 1, part + 1, answer);
@ -29,3 +42,18 @@ bool runner_tick(struct runner_state * runner_state)
return false;
}
void runner_render(struct runner_state * runner_state,
const struct font * font,
const struct glyph * glyphs,
const void * maple_ft0_data)
{
int day = runner_state->tick / 2;
if (day >= solution_days) {
return;
}
if (solution[day].render != NULL) {
solution[day].render(font, glyphs, maple_ft0_data);
}
}

View File

@ -2,15 +2,22 @@
#include <stdbool.h>
#include "font/font.h"
#ifdef __cplusplus
extern "C" {
#endif
struct runner_state {
int tick;
bool want_render;
};
bool runner_tick(struct runner_state * runner_state);
void runner_render(struct runner_state * runner_state,
const struct font * font,
const struct glyph * glyphs,
const void * maple_ft0_data);
#ifdef __cplusplus
}

View File

@ -1,18 +1,42 @@
int day1_part1(char * input, int length);
int day1_part2(char * input, int length);
int day2_part1(char * input, int length);
int day2_part2(char * input, int length);
int day3_part1(char * input, int length);
int day3_part2(char * input, int length);
int day4_part1(char * input, int length);
int day4_part2(char * input, int length);
int day5_part1(char * input, int length);
int day5_part2(char * input, int length);
int day1_part1(const char * input, int length);
int day1_part2(const char * input, int length);
int day2_part1(const char * input, int length);
int day2_part2(const char * input, int length);
int day3_part1(const char * input, int length);
int day3_part2(const char * input, int length);
int day4_part1(const char * input, int length);
int day4_part2(const char * input, int length);
int day5_part1(const char * input, int length);
int day5_part2(const char * input, int length);
int day6_part1(const char * input, int length);
int day6_part2(const char * input, int length);
void day6_render(const struct font * font,
const struct glyph * glyphs,
const void * maple_ft0_data);
part_func solution[][2] = {
{day1_part1, day1_part2},
{day2_part1, day2_part2},
{day3_part1, day3_part2},
{day4_part1, day4_part2},
{day5_part1, day5_part2},
struct day_funcs solution[] = {
{
{day1_part1, day1_part2},
NULL,
},
{
{day2_part1, day2_part2},
NULL,
},
{
{day3_part1, day3_part2},
NULL,
},
{
{day4_part1, day4_part2},
NULL,
},
{
{day5_part1, day5_part2},
NULL,
},
{
{day6_part1, day6_part2},
day6_render,
},
};

View File

@ -1,4 +1,5 @@
#include <cstdint>
#include <bit>
#include "holly/texture_memory_alloc2.hpp"
#include "holly/isp_tsp.hpp"
@ -23,7 +24,7 @@
#include "systembus.hpp"
#include "systembus_bits.hpp"
#include "font/font.hpp"
#include "font/font.h"
#include "font/dejavusansmono/dejavusansmono.data.h"
#include "palette.hpp"
@ -31,6 +32,61 @@
#include "printf.h"
#include "runner.h"
#include "maple/maple.hpp"
#include "maple/maple_host_command_writer.hpp"
#include "maple/maple_bus_bits.hpp"
#include "maple/maple_bus_commands.hpp"
#include "maple/maple_bus_ft0.hpp"
static ft0::data_transfer::data_format maple_ft0_data[4];
static uint8_t send_buf[1024] __attribute__((aligned(32)));
static uint8_t recv_buf[1024] __attribute__((aligned(32)));
static bool maple_wait = false;
void do_get_condition()
{
if (maple_wait)
maple::dma_wait_complete();
auto writer = maple::host_command_writer(send_buf, recv_buf);
writer.append_command_all_ports<maple::device_request, maple::device_status>(false);
using command_type = maple::get_condition;
using response_type = maple::data_transfer<ft0::data_transfer::data_format>;
auto [host_command, host_response]
= writer.append_command_all_ports<command_type, response_type>();
host_command->bus_data.data_fields.function_type = std::byteswap(function_type::controller);
maple::dma_start(send_buf, writer.send_offset,
recv_buf, writer.recv_offset);
maple_wait = true;
for (uint8_t port = 0; port < 4; port++) {
auto& bus_data = host_response[port].bus_data;
maple_ft0_data[port].digital_button = 0;
if (bus_data.command_code != response_type::command_code) {
return;
}
auto& data_fields = bus_data.data_fields;
if ((std::byteswap(data_fields.function_type) & function_type::controller) == 0) {
return;
}
maple_ft0_data[port].digital_button = data_fields.data.digital_button;
maple_ft0_data[port].analog_coordinate_axis[0] = data_fields.data.analog_coordinate_axis[0];
maple_ft0_data[port].analog_coordinate_axis[1] = data_fields.data.analog_coordinate_axis[1];
maple_ft0_data[port].analog_coordinate_axis[2] = data_fields.data.analog_coordinate_axis[2];
maple_ft0_data[port].analog_coordinate_axis[3] = data_fields.data.analog_coordinate_axis[3];
maple_ft0_data[port].analog_coordinate_axis[4] = data_fields.data.analog_coordinate_axis[4];
maple_ft0_data[port].analog_coordinate_axis[5] = data_fields.data.analog_coordinate_axis[5];
}
}
struct vertex {
float x;
float y;
@ -49,7 +105,7 @@ const struct vertex strip_vertices[4] = {
constexpr uint32_t strip_length = (sizeof (strip_vertices)) / (sizeof (struct vertex));
void transform_start(const uint32_t texture_width, uint32_t texture_height)
void glyph_start(const uint32_t texture_width, uint32_t texture_height)
{
const uint32_t parameter_control_word = para_control::para_type::polygon_or_modifier_volume
| para_control::list_type::translucent
@ -129,7 +185,7 @@ int32_t transform_char(const uint32_t texture_width,
void transfer_scene(const struct font * font,
const struct glyph * glyphs)
{
transform_start(font->texture_width, font->texture_height);
glyph_start(font->texture_width, font->texture_height);
int32_t horizontal_advance = font->face_metrics.max_advance / 5; // 26.6 fixed point
int32_t vertical_advance = font->face_metrics.height; // 26.6 fixed point
@ -151,10 +207,6 @@ void transfer_scene(const struct font * font,
vertical_advance);
}
}
*reinterpret_cast<ta_global_parameter::end_of_list *>(store_queue) =
ta_global_parameter::end_of_list(para_control::para_type::end_of_list);
sq_transfer_32byte(ta_fifo_polygon_converter);
}
void copy_font(const uint8_t * src,
@ -197,6 +249,8 @@ constexpr int tile_height = framebuffer_height / 32;
static uint32_t frame = 0;
struct runner_state runner_state = {0};
void render()
{
if (core >= 0) {
@ -236,7 +290,15 @@ void render()
ta_alloc,
tile_width,
tile_height);
///
transfer_scene(font, glyphs);
if (runner_state.want_render) {
runner_render(&runner_state, font, glyphs, maple_ft0_data);
}
*reinterpret_cast<ta_global_parameter::end_of_list *>(store_queue) =
ta_global_parameter::end_of_list(para_control::para_type::end_of_list);
sq_transfer_32byte(ta_fifo_polygon_converter);
}
void vbr600()
@ -254,6 +316,8 @@ void vbr600()
serial::integer<uint32_t>(system.ISTNRM & system.IML6NRM);
*/
do_get_condition();
render();
// reset v_blank_in interrupt
@ -271,6 +335,12 @@ void vbr400()
void vbr100()
{
serial::string("vbr100\n");
serial::string("expevt ");
serial::integer<uint16_t>(sh7091.CCN.EXPEVT);
serial::string("intevt ");
serial::integer<uint16_t>(sh7091.CCN.INTEVT);
serial::string("tra ");
serial::integer<uint16_t>(sh7091.CCN.TRA);
while (1);
}
@ -354,8 +424,6 @@ int main()
copy_font(texture, font->max_z_curve_ix);
palette_data<256>();
struct runner_state runner_state = {0};
video_output::set_mode_vga();
ta = -1;

View File

@ -14,4 +14,8 @@ DAY_OBJ = \
day4/solution.o \
day5/sample1.txt.o \
day5/input.txt.o \
day5/solution.o
day5/solution.o \
day6/sample1.txt.o \
day6/input.txt.o \
day6/render.o \
day6/solution.o