c 2024 day 9

This commit is contained in:
Bill Rossi 2024-12-09 07:12:02 -05:00
parent d9628ea099
commit 01e2a6a00f

101
c/2024/9/disk_fragmenter.c Normal file
View File

@ -0,0 +1,101 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#include "../../lib/aoc.h"
#define EMPTY -1
typedef struct File {
int id;
int *location;
int size;
bool free;
} File;
int main() {
char *input = aoc_read_input();
int input_size = strlen(input);
int disk[200000];
int *write_head = disk;
int file_number = 0;
int total_file_size = 0;
File files[10000];
int files_count = 0;
File empties[10000];
int empties_count = 0;
int i = 0;
while (i < input_size) {
int file_size = input[i++] - '0';
total_file_size += file_size;
files[files_count].id = file_number;
files[files_count].location = write_head;
files[files_count].size = file_size;
files_count++;
for (int j = 0; j < file_size; j++) {
*write_head = file_number;
write_head++;
}
file_number++;
int empty_size = input[i++] - '0';
if (empty_size > 0) {
empties[empties_count].id = EMPTY;
empties[empties_count].location = write_head;
empties[empties_count].size = empty_size;
empties_count++;
}
for (int j = 0; j < empty_size; j++) {
*write_head = EMPTY;
write_head++;
}
}
int *read_head = write_head - 1;
write_head = disk;
while (read_head > write_head) {
if (*read_head == EMPTY) read_head--;
else if (*write_head != EMPTY) write_head++;
else {
*write_head = *read_head;
*read_head = EMPTY;
}
}
long checksum = 0l;
for (int i = 0; i < total_file_size; i++) checksum += i * disk[i];
for (int i = files_count - 1; i >= 0; i--) {
for (int j = 0; j < empties_count; j++) {
if (empties[j].size >= files[i].size) {
files[i].location = empties[j].location;
empties[j].size -= files[i].size;
empties[j].location += files[i].size;
break;
}
if (empties[j].location > files[i].location) break;
}
}
long second_checksum = 0l;
for (int i = 0; i < files_count; i++) {
for (int j = 0; j < files[i].size; j++) {
second_checksum += (files[i].id * (files[i].location - disk + j));
}
}
printf("Part 1: %ld\n", checksum);
printf("Part 2: %ld\n", second_checksum);
aoc_free();
return 0;
}