Files
banan-os/userspace/aoc2023/day9/main.cpp
Bananymous 00d57d783e LibC+userspace: Make everything compile with -Wall -Wextra -Werror
I added -Wall -Wextra -Werror as public compile flags to libc. Now
everything in userspace in compiled using these flags. I made all
necessary changes to allow compilation to work.

Only exception is execvp which has a large stack usage. Maybe it
should use malloc for the buffer but posix allows ENOMEM only when
kernel is out of memory... This can be fixed when fexecve is
implemented and there is no need for absolute path.
2023-12-10 19:20:14 +02:00

126 lines
2.2 KiB
C++

#include <BAN/String.h>
#include <BAN/Vector.h>
#include <ctype.h>
#include <inttypes.h>
#include <stdio.h>
#include <stdint.h>
using i32 = int32_t;
using i64 = int64_t;
using u32 = uint32_t;
using u64 = uint64_t;
i64 parse_i64(BAN::StringView sv)
{
bool negative = (!sv.empty() && sv.front() == '-');
if (negative)
sv = sv.substring(1);
i64 result = 0;
for (char c : sv)
{
if (!isdigit(c))
break;
result = (result * 10) + (c - '0');
}
return negative ? -result : result;
}
BAN::Vector<BAN::Vector<i64>> build_difference_tree(BAN::StringView input)
{
auto value_strs = MUST(input.split(' '));
if (value_strs.empty())
return {};
BAN::Vector<BAN::Vector<i64>> tree;
MUST(tree.emplace_back(value_strs.size(), 0));
for (size_t i = 0; i < value_strs.size(); i++)
tree.back()[i] = parse_i64(value_strs[i]);
bool all_zeroes = false;
while (!all_zeroes)
{
size_t last = tree.size();
MUST(tree.emplace_back(tree.back().size() - 1, 0));
all_zeroes = true;
for (size_t i = 0; i < tree.back().size(); i++)
{
i64 lhs = tree[last - 1][i + 0];
i64 rhs = tree[last - 1][i + 1];
tree[last][i] = rhs - lhs;
if (tree[last][i] != 0)
all_zeroes = false;
}
}
return tree;
}
i64 puzzle1(FILE* fp)
{
i64 result = 0;
char buffer[128];
while (fgets(buffer, sizeof(buffer), fp))
{
auto tree = build_difference_tree(buffer);
if (tree.empty())
continue;
i64 current = 0;
for (size_t i = tree.size(); i > 0; i--)
current = tree[i - 1].back() + current;
result += current;
}
return result;
}
i64 puzzle2(FILE* fp)
{
i64 result = 0;
char buffer[128];
while (fgets(buffer, sizeof(buffer), fp))
{
auto tree = build_difference_tree(buffer);
if (tree.empty())
continue;
i64 current = 0;
for (size_t i = tree.size(); i > 0; i--)
current = tree[i - 1].front() - current;
result += current;
}
return result;
}
int main(int argc, char** argv)
{
const char* file_path = "/usr/share/aoc2023/day9_input.txt";
if (argc >= 2)
file_path = argv[1];
FILE* fp = fopen(file_path, "r");
if (fp == nullptr)
{
perror("fopen");
return 1;
}
printf("puzzle1: %" PRId64 "\n", puzzle1(fp));
fseek(fp, 0, SEEK_SET);
printf("puzzle2: %" PRId64 "\n", puzzle2(fp));
fclose(fp);
}