BuildSystem: Rework the whole cmake build system

Now files are installed using the install() command instead of manually
copying files to their destinations. This allows automatic recompilation
of headers that did not work previously
This commit is contained in:
2024-06-19 04:20:23 +03:00
parent 318ce5dec8
commit ad6d95ba52
90 changed files with 546 additions and 1074 deletions

View File

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

View File

@@ -0,0 +1,191 @@
#include <BAN/HashSet.h>
#include <BAN/Sort.h>
#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 u8 = uint8_t;
using u16 = uint16_t;
using u32 = uint32_t;
using u64 = uint64_t;
struct Position
{
i64 x, y, z;
bool operator==(const Position& other) const
{
return x == other.x && y == other.y && z == other.z;
}
};
static constexpr bool rectangle_contains(const Position& c1, const Position& c2, const Position& p)
{
ASSERT(c1.x <= c2.x);
ASSERT(c1.y <= c2.y);
return (c1.x <= p.x && p.x <= c2.x) && (c1.y <= p.y && p.y <= c2.y);
}
struct Brick
{
Position corners[2];
BAN::HashSet<Brick*> supporting;
BAN::HashSet<Brick*> supported_by;
bool supports(const Brick& other) const
{
if (corners[1].z + 1 != other.corners[0].z)
return false;
for (i32 i = 0; i < 4; i++)
if (rectangle_contains(corners[0], corners[1], { other.corners[i / 2].x, other.corners[i % 2].y, 0 }))
return true;
for (i32 i = 0; i < 4; i++)
if (rectangle_contains(other.corners[0], other.corners[1], { corners[i / 2].x, corners[i % 2].y, 0 }))
return true;
return false;
}
};
i64 parse_i64(BAN::StringView str)
{
i64 result = 0;
for (char c : str)
{
ASSERT(isdigit(c));
result = (result * 10) + (c - '0');
}
return result;
}
BAN::Vector<Brick> parse_bricks(FILE* fp)
{
BAN::Vector<Brick> bricks;
char buffer[64];
while (fgets(buffer, sizeof(buffer), fp))
{
BAN::StringView line(buffer);
ASSERT(line.back() == '\n');
line = line.substring(0, line.size() - 1);
if (line.empty())
break;
auto corner_strs = MUST(line.split('~'));
ASSERT(corner_strs.size() == 2);
Brick brick;
for (i32 i = 0; i < 2; i++)
{
auto coords = MUST(corner_strs[i].split(','));
ASSERT(coords.size() == 3);
brick.corners[i].x = parse_i64(coords[0]);
brick.corners[i].y = parse_i64(coords[1]);
brick.corners[i].z = parse_i64(coords[2]);
}
ASSERT(brick.corners[0].x <= brick.corners[1].x);
ASSERT(brick.corners[0].y <= brick.corners[1].y);
ASSERT(brick.corners[0].z <= brick.corners[1].z);
MUST(bricks.push_back(brick));
}
return bricks;
}
i64 puzzle1(FILE* fp)
{
auto brick_comp = [](const Brick& b1, const Brick& b2) { return b1.corners[0].z < b2.corners[0].z; };
auto bricks = parse_bricks(fp);
BAN::sort::sort(bricks.begin(), bricks.end(), brick_comp);
// Simulate brick falling
for (size_t i = 0; i < bricks.size();)
{
bool can_fall = bricks[i].corners[0].z > 1;
for (size_t j = 0; j < i && can_fall; j++)
if (bricks[j].supports(bricks[i]))
can_fall = false;
if (!can_fall)
i++;
else
{
bricks[i].corners[0].z--;
bricks[i].corners[1].z--;
for (; i > 0; i--)
{
if (brick_comp(bricks[i - 1], bricks[i]))
break;
BAN::swap(bricks[i - 1], bricks[i]);
}
}
}
// Store brick supporting structures
for (size_t i = 0; i < bricks.size(); i++)
{
for (size_t j = 0; j < bricks.size(); j++)
{
if (i == j)
continue;
if (bricks[i].supports(bricks[j]))
{
MUST(bricks[i].supporting.insert(&bricks[j]));
MUST(bricks[j].supported_by.insert(&bricks[i]));
}
}
}
i64 result = 0;
for (const auto& brick : bricks)
{
bool disintegratable = true;
for (const auto* support : brick.supporting)
if (support->supported_by.size() <= 1)
disintegratable = false;
result += disintegratable;
}
// OFF BY 7
return result;
}
i64 puzzle2(FILE* fp)
{
(void)fp;
return -1;
}
int main(int argc, char** argv)
{
const char* file_path = "/usr/share/aoc2023/day22_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);
}