#include #include #include #include #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); }