Compare commits

..

3 Commits

Author SHA1 Message Date
Bananymous 3e36834751 aoc2024: Implement day10 solution 2024-12-10 17:26:39 +02:00
Bananymous 581caff638 BuildSystem: Install base sysroot only once
Base sysroot is not only installed when creating the syroot directory
for the first time. To get it installed again, you have to either delete
the old sysroot diretory or run clean target

This makes it so its actually possible to edit files specified in the
base sysroot without random hacks.
2024-12-10 16:44:59 +02:00
Bananymous 8b612ba547 aoc2024: Implement day9 solution
part2 is kinda unoptimized, it should not use expanded input, but I did
not feel like rewriting my parsing code :)
2024-12-09 16:20:21 +02:00
8 changed files with 352 additions and 8 deletions

View File

@ -6,8 +6,6 @@ endif ()
project(banan-os CXX C ASM)
set(BANAN_BASE_SYSROOT ${CMAKE_SOURCE_DIR}/base-sysroot.tar.gz)
set(BANAN_INCLUDE ${BANAN_SYSROOT}/usr/include)
set(BANAN_LIB ${BANAN_SYSROOT}/usr/lib)
set(BANAN_BIN ${BANAN_SYSROOT}/usr/bin)
@ -57,8 +55,3 @@ add_subdirectory(kernel)
add_subdirectory(bootloader)
add_subdirectory(BAN)
add_subdirectory(userspace)
add_custom_target(sysroot
COMMAND ${CMAKE_COMMAND} -E make_directory ${BANAN_SYSROOT}
COMMAND cd ${BANAN_SYSROOT} && tar xf ${BANAN_BASE_SYSROOT}
)

View File

@ -66,6 +66,14 @@ run_bochs () {
$BANAN_SCRIPT_DIR/bochs.sh $@
}
if [ ! -d $BANAN_SYSROOT ]; then
mkdir -p $BANAN_SYSROOT
pushd $BANAN_SYSROOT
run_fakeroot tar xf ${BANAN_ROOT_DIR}/base-sysroot.tar.gz
popd
fi
if [ -v QEMU_ACCEL ]; then
:
elif type kvm-ok &> /dev/null; then

View File

@ -7,6 +7,8 @@ set(AOC2024_PROJECTS
day6
day7
day8
day9
day10
full
)

View File

@ -0,0 +1,9 @@
set(SOURCES
main.cpp
)
add_executable(aoc2024_day10 ${SOURCES})
banan_include_headers(aoc2024_day10 ban)
banan_link_library(aoc2024_day10 libc)
install(TARGETS aoc2024_day10 OPTIONAL)

View File

@ -0,0 +1,171 @@
#include <BAN/HashSet.h>
#include <BAN/Vector.h>
#include <inttypes.h>
#include <stdio.h>
using i8 = int8_t;
using i16 = int16_t;
using i32 = int32_t;
using i64 = int64_t;
using isize = ssize_t;
using u8 = uint8_t;
using u16 = uint16_t;
using u32 = uint32_t;
using u64 = uint64_t;
using usize = size_t;
struct Position
{
u32 x, y;
constexpr bool operator==(const Position& other) const
{
return x == other.x && y == other.y;
}
};
struct PositionHash
{
constexpr BAN::hash_t operator()(Position state) const
{
return BAN::hash<u64>{}((u64)state.x << 32 | (u64)state.y);
}
};
struct Grid2D
{
usize width { 0 };
usize height { 0 };
BAN::Vector<char> data;
inline char get(usize x, usize y) const
{
ASSERT(x < width && y < height);
return data[y * width + x];
}
};
static Grid2D read_grid2d(FILE* fp)
{
usize width { 0 };
usize height { 0 };
BAN::Vector<char> data;
char buffer[1024];
while (fgets(buffer, sizeof(buffer), fp))
{
const usize len = strlen(buffer);
if (len == 0 || buffer[0] == '\n')
break;
if (data.empty())
width = len - 1;
height++;
ASSERT(buffer[width] == '\n');
if (data.capacity() < height * width)
MUST(data.reserve(2 * height * width));
MUST(data.resize(height * width));
memcpy(&data[(height - 1) * width], buffer, width);
}
(void)data.shrink_to_fit();
return Grid2D {
.width = width,
.height = height,
.data = BAN::move(data),
};
}
i64 get_trailhead_score(const Grid2D& map, u32 x, u32 y, char curr, BAN::HashSet<Position, PositionHash>& trail_ends, bool allow_duplicate)
{
if (x >= map.width)
return 0;
if (y >= map.height)
return 0;
if (map.get(x, y) != curr)
return 0;
if (curr == '9')
{
const auto pos = Position { .x = x, .y = y };
if (trail_ends.contains(pos))
return allow_duplicate;
MUST(trail_ends.insert(Position { .x = x, .y = y }));
return 1;
}
i64 result = 0;
result += get_trailhead_score(map, x - 1, y, curr + 1, trail_ends, allow_duplicate);
result += get_trailhead_score(map, x, y - 1, curr + 1, trail_ends, allow_duplicate);
result += get_trailhead_score(map, x + 1, y, curr + 1, trail_ends, allow_duplicate);
result += get_trailhead_score(map, x, y + 1, curr + 1, trail_ends, allow_duplicate);
return result;
}
i64 part1(FILE* fp)
{
auto map = read_grid2d(fp);
i64 result = 0;
for (u32 y = 0; y < map.height; y++)
{
for (u32 x = 0; x < map.width; x++)
{
if (map.get(x, y) != '0')
continue;
BAN::HashSet<Position, PositionHash> trail_ends;
result += get_trailhead_score(map, x, y, '0', trail_ends, false);
}
}
return result;
}
i64 part2(FILE* fp)
{
auto map = read_grid2d(fp);
i64 result = 0;
for (u32 y = 0; y < map.height; y++)
{
for (u32 x = 0; x < map.width; x++)
{
if (map.get(x, y) != '0')
continue;
BAN::HashSet<Position, PositionHash> trail_ends;
result += get_trailhead_score(map, x, y, '0', trail_ends, true);
}
}
return result;
}
int main(int argc, char** argv)
{
const char* file_path = "/usr/share/aoc2024/day10_input.txt";
if (argc >= 2)
file_path = argv[1];
FILE* fp = fopen(file_path, "r");
if (fp == nullptr)
{
perror("fopen");
return 1;
}
printf("part1: %" PRId64 "\n", part1(fp));
fseek(fp, 0, SEEK_SET);
printf("part2: %" PRId64 "\n", part2(fp));
fclose(fp);
}

View File

@ -0,0 +1,9 @@
set(SOURCES
main.cpp
)
add_executable(aoc2024_day9 ${SOURCES})
banan_include_headers(aoc2024_day9 ban)
banan_link_library(aoc2024_day9 libc)
install(TARGETS aoc2024_day9 OPTIONAL)

View File

@ -0,0 +1,153 @@
#include <BAN/Vector.h>
#include <ctype.h>
#include <inttypes.h>
#include <stdio.h>
using i8 = int8_t;
using i16 = int16_t;
using i32 = int32_t;
using i64 = int64_t;
using isize = ssize_t;
using u8 = uint8_t;
using u16 = uint16_t;
using u32 = uint32_t;
using u64 = uint64_t;
using usize = size_t;
static BAN::Vector<u32> parse_input(FILE* fp)
{
BAN::Vector<u32> result;
u32 idx = 0;
char buffer[1024];
while (fgets(buffer, sizeof(buffer), fp))
{
usize len = strlen(buffer);
if (len > 0 && buffer[len - 1] == '\n')
len--;
for (usize i = 0; i < len; i++)
{
const u32 block_id = (idx % 2) ? 0xFFFFFFFF : idx / 2;
ASSERT(isdigit(buffer[i]));
for (i8 j = 0; j < buffer[i] - '0'; j++)
MUST(result.push_back(block_id));
idx++;
}
}
return result;
}
i64 part1(FILE* fp)
{
auto input = parse_input(fp);
usize l = 0;
usize r = input.size() - 1;
i64 result = 0;
while (l <= r)
{
if (input[l] != 0xFFFFFFFF)
{
result += input[l] * l;
l++;
continue;
}
while (l < r && input[r] == 0xFFFFFFFF)
r--;
if (l == r)
continue;
result += input[r] * l;
r--;
l++;
}
return result;
}
i64 part2(FILE* fp)
{
auto input = parse_input(fp);
for (usize r = input.size(); r > 0;)
{
if (input[r - 1] == 0xFFFFFFFF)
{
r--;
continue;
}
const u32 id = input[r - 1];
usize rlen = 0;
while (r - rlen - 1 > 0 && input[r - rlen - 1] == id)
rlen++;
usize l = 0;
for (; l < r - rlen; l++)
{
if (input[l] != 0xFFFFFFFF)
continue;
usize llen = 1;
while (llen < rlen && input[l + llen] == 0xFFFFFFFF)
llen++;
if (llen == rlen)
break;
}
if (l < r - rlen)
{
for (usize i = 0; i < rlen; i++)
input[r - i - 1] = 0xFFFFFFFF;
for (usize i = 0; i < rlen; i++)
input[l + i] = id;
}
r -= rlen;
while (r > 0 && input[r - 1] == id)
r--;
}
i64 result = 0;
for (usize i = 0; i < input.size(); i++)
if (input[i] != 0xFFFFFFFF)
result += i * input[i];
return result;
}
int main(int argc, char** argv)
{
const char* file_path = "/usr/share/aoc2024/day9_input.txt";
if (argc >= 2)
file_path = argv[1];
FILE* fp = fopen(file_path, "r");
if (fp == nullptr)
{
perror("fopen");
return 1;
}
printf("part1: %" PRId64 "\n", part1(fp));
fseek(fp, 0, SEEK_SET);
printf("part2: %" PRId64 "\n", part2(fp));
fclose(fp);
}

View File

@ -58,7 +58,6 @@ target_compile_options(objlibc PUBLIC -Wall -Wextra -Werror -Wno-error=stack-usa
function(add_crtx crtx)
add_custom_target(${crtx}
COMMAND ${CMAKE_CXX_COMPILER} -c -o ${CMAKE_INSTALL_LIBDIR}/${crtx}.o ${CMAKE_CURRENT_SOURCE_DIR}/arch/${BANAN_ARCH}/${crtx}.S
DEPENDS sysroot
)
add_dependencies(objlibc ${crtx})
endfunction()