day 09
This commit is contained in:
parent
0f6f538786
commit
c627e6f917
|
|
@ -57,6 +57,12 @@ typedef double f64;
|
||||||
#define Megabytes(x) ((u64) (x) << 20)
|
#define Megabytes(x) ((u64) (x) << 20)
|
||||||
#define Gigabytes(x) ((u64) (x) << 30)
|
#define Gigabytes(x) ((u64) (x) << 30)
|
||||||
|
|
||||||
|
#define DYNAMIC_ARRAY(type) \
|
||||||
|
struct { \
|
||||||
|
type *data; \
|
||||||
|
isize len, cap; \
|
||||||
|
}
|
||||||
|
|
||||||
#define push(slice, arena) \
|
#define push(slice, arena) \
|
||||||
((slice)->len >= ((slice)->cap) \
|
((slice)->len >= ((slice)->cap) \
|
||||||
? grow(slice, sizeof(*(slice)->data), arena), \
|
? grow(slice, sizeof(*(slice)->data), arena), \
|
||||||
|
|
|
||||||
|
|
@ -134,7 +134,7 @@ vec2_sub(Vec2 a, Vec2 b) {
|
||||||
|
|
||||||
static inline Vec2
|
static inline Vec2
|
||||||
vec2(f32 x, f32 y) {
|
vec2(f32 x, f32 y) {
|
||||||
Vec2 result = { x, y };
|
Vec2 result = {{ x, y }};
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
File diff suppressed because one or more lines are too long
|
|
@ -0,0 +1,121 @@
|
||||||
|
#include "aoc.h"
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
int id; // -1 if free space
|
||||||
|
int len;
|
||||||
|
int offset;
|
||||||
|
} Block;
|
||||||
|
|
||||||
|
static void
|
||||||
|
dump(int *ids, int len) {
|
||||||
|
for (int i = 0; i < len; i++) {
|
||||||
|
if (ids[i] == -1) {
|
||||||
|
printf(".");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
printf("%d", ids[i] % 10);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
puts("");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
disk_from_blocks(i32 *disk, Block *blocks, usize block_count) {
|
||||||
|
for (usize i = 0; i < block_count; i++) {
|
||||||
|
Block *block = blocks + i;
|
||||||
|
for (int j = 0; j < block->len; j++) {
|
||||||
|
disk[j] = block->id;
|
||||||
|
}
|
||||||
|
disk += block->len;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char **argv) {
|
||||||
|
(void) argc;
|
||||||
|
Arena *arena = make_arena(Megabytes(10));
|
||||||
|
str input = str_trim(read_file(arena, argv[1]));
|
||||||
|
|
||||||
|
enum {
|
||||||
|
STATE_BLOCK,
|
||||||
|
STATE_SPACE,
|
||||||
|
} state = STATE_BLOCK;
|
||||||
|
int block_id = 0;
|
||||||
|
|
||||||
|
DYNAMIC_ARRAY(Block) blocks = {0};
|
||||||
|
|
||||||
|
isize total_size = 0;
|
||||||
|
for (usize i = 0; i < input.len; ++i) {
|
||||||
|
int len = input.data[i] - '0';
|
||||||
|
*push(&blocks, arena) = (Block) {
|
||||||
|
.id = (state == STATE_BLOCK) ? block_id : -1,
|
||||||
|
.len = len,
|
||||||
|
.offset = total_size
|
||||||
|
};
|
||||||
|
total_size += len;
|
||||||
|
if (state == STATE_BLOCK) {
|
||||||
|
block_id++;
|
||||||
|
state = STATE_SPACE;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
state = STATE_BLOCK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ASSERT(state == STATE_SPACE);
|
||||||
|
|
||||||
|
i32 *disk = ARENA_ALLOC_ARRAY(arena, i32, total_size);
|
||||||
|
disk_from_blocks(disk, blocks.data, blocks.len);
|
||||||
|
|
||||||
|
isize to = 0, from = total_size - 1;
|
||||||
|
for (;;) {
|
||||||
|
while (to <= from && disk[to] != -1) {
|
||||||
|
to++;
|
||||||
|
}
|
||||||
|
while (from > to && disk[from] == -1) {
|
||||||
|
from--;
|
||||||
|
}
|
||||||
|
if (to >= from) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
ASSERT((disk[to] == -1) && (disk[from] != -1));
|
||||||
|
disk[to] = disk[from];
|
||||||
|
disk[from] = -1;
|
||||||
|
from--;
|
||||||
|
to++;
|
||||||
|
}
|
||||||
|
|
||||||
|
i64 part_1 = 0;
|
||||||
|
for (isize i = 0; i < total_size && disk[i] != -1; i++) {
|
||||||
|
part_1 += i * disk[i];
|
||||||
|
}
|
||||||
|
printf("%ld\n", part_1);
|
||||||
|
|
||||||
|
// restore original layout
|
||||||
|
disk_from_blocks(disk, blocks.data, blocks.len);
|
||||||
|
|
||||||
|
for (isize from_block_index = blocks.len - 1; from_block_index >= 0; from_block_index -= 2) {
|
||||||
|
Block *from = blocks.data + from_block_index;
|
||||||
|
ASSERT(from->id != -1);
|
||||||
|
|
||||||
|
for (isize to_block_index = 1; to_block_index < from_block_index; to_block_index += 2) {
|
||||||
|
Block *to = blocks.data + to_block_index;
|
||||||
|
ASSERT(to->id == -1);
|
||||||
|
if (from->len <= to->len) {
|
||||||
|
for (isize i = 0; i < from->len; i++) {
|
||||||
|
disk[to->offset + i] = from->id;
|
||||||
|
disk[from->offset + i] = -1;
|
||||||
|
}
|
||||||
|
to->offset += from->len;
|
||||||
|
to->len -= from->len;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
i64 part_2 = 0;
|
||||||
|
for (isize i = 0; i < total_size; i++) {
|
||||||
|
if (disk[i] != -1) {
|
||||||
|
part_2 += i * disk[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
printf("%ld\n", part_2);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
2333133121414131402
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
233313312141413140223331331214141314022333133121414131402
|
||||||
Loading…
Reference in New Issue