Files
adventofcode2024/day9/c/day9.c

113 lines
2.7 KiB
C
Raw Normal View History

2024-12-09 18:17:56 +01:00
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define char2i(c) (c - 48)
#define MAX_DISK_SIZE 1024*1024
int main() {
char c;
uint32_t *disk = calloc(MAX_DISK_SIZE, sizeof(disk[0]));
int disk_size = 0;
uint32_t file_count = 0;
int is_file = 1;
while ((c = getchar()) != EOF) {
int n = char2i(c);
uint32_t data = is_file ? file_count++ : UINT32_MAX;
for (int i = 0; i < n; i++) {
disk[disk_size++] = data;
}
is_file = !is_file;
}
// Create copy
uint32_t *disk_copy = calloc(disk_size, sizeof(disk_copy[0]));
memcpy(disk_copy, disk, disk_size * sizeof(disk[0]));
int last_empty = 0;
int inserted_back = 0;
for (;;) {
// Find next empty space
while (disk_copy[last_empty] != UINT32_MAX && last_empty < disk_size - inserted_back - 1) last_empty++;
if (last_empty >= disk_size - inserted_back - 1) {
break;
}
disk_copy[last_empty] = disk_copy[disk_size - inserted_back - 1];
disk_copy[disk_size - inserted_back - 1] = UINT32_MAX;
inserted_back++;
}
uint64_t checksum = 0;
for (int i = 0; i < disk_size; i++) {
if (disk_copy[i] != UINT32_MAX) {
checksum += disk_copy[i] * i;
}
}
free(disk_copy);
printf("%lu\n", checksum);
// Part two
for (int i = file_count - 1; i >= 0; i--) {
// Get file size inefficiently
int file_size = 0;
int file_begin = 0;
for (int j = 0; j < disk_size; j++) {
if (disk[j] == i) {
if (file_size == 0) {
file_begin = j;
}
file_size++;
}
}
// Find empty space
for (int j = 0; j < disk_size; j++) {
// We only place files left
if (disk[j] == i) {
break;
}
if (disk[j] == UINT32_MAX) {
// Let's see if we have enough space
int fit = 1;
for (int k = 0; k < file_size; k++) {
if (disk[j + k] != UINT32_MAX) {
fit = 0;
break;
}
}
if (fit) {
for (int k = 0; k < file_size; k++) {
disk[j + k] = i;
disk[file_begin + k] = UINT32_MAX;
}
break;
}
}
}
}
checksum = 0;
for (int i = 0; i < disk_size; i++) {
if (disk[i] != UINT32_MAX) {
checksum += disk[i] * i;
}
}
free(disk);
printf("%lu\n", checksum);
}