advent-of-code-2024/aoc/aoc.c

89 lines
2.3 KiB
C

#define STR_IMPLEMENTATION
#include "str.h"
#include "aoc.h"
#include <stdlib.h>
Arena *make_arena(ptrdiff_t size) {
void *mem = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
Arena *arena = arena_init(mem, size);
return arena;
}
str read_file(Arena *arena, const char *filename) {
FILE *f = fopen(filename, "r");
ASSERT(f);
fseek(f, 0, SEEK_END);
size_t size = ftell(f);
fseek(f, 0, SEEK_SET);
char *data = ARENA_ALLOC_ARRAY(arena, char, size + 1);
size_t read_size = fread(data, 1, size, f);
ASSERT(read_size == size);
data[size] = '\0';
fclose(f);
return make_str((uint8_t *) data, size);
}
Tokens str_tokenize(Arena *arena, str s, str delim) {
// 1st pass: count number of tokens
str stuff = s;
isize token_count = 0;
for (; stuff.len > 0; str_next_token(&stuff, delim)) {
token_count++;
}
// 2nd pass: allocate memory and copy tokens
Tokens result = {
.len = token_count,
.tokens = ARENA_ALLOC_ARRAY(arena, str, token_count)
};
ASSERT(result.tokens);
stuff = s;
for (isize i = 0; i < token_count; ++i) {
result.tokens[i] = str_next_token(&stuff, delim);
}
return result;
}
Tokens read_lines(Arena *arena, const char *path) {
str file = read_file(arena, path);
Tokens lines = str_tokenize(arena, file, STR("\n"));
return lines;
}
char *
str_to_cstr(str s, Arena *a) {
char *result = ARENA_ALLOC_ARRAY(a, char, s.len + 1);
memcpy(result, s.data, s.len);
result[s.len] = '\0';
return result;
}
i64
parse_i64(str s, Arena temp) {
char *cs = str_to_cstr(s, &temp);
char *endptr;
i64 result = strtol(cs, &endptr, 10);
ASSERT(*endptr == '\0');
return result;
}
Grid parse_grid(str input, Arena *arena) {
Tokens lines = str_tokenize(arena, str_trim(input), STR("\n"));
ASSERT(lines.len > 0);
i32 width = lines.tokens[0].len;
for (i32 i = 0; i < lines.len; i++) {
ASSERT(lines.tokens[i].len == width);
}
Grid grid = { .width = width, .height = lines.len };
grid.grid = ARENA_ALLOC_ARRAY(arena, u8, grid.width * grid.height);
for (i32 i = 0; i < lines.len; i++) {
memcpy(grid.grid + i * grid.width, lines.tokens[i].data, grid.width);
}
return grid;
}