summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--2024/9.c76
-rw-r--r--2024/Makefile9
2 files changed, 83 insertions, 2 deletions
diff --git a/2024/9.c b/2024/9.c
new file mode 100644
index 0000000..fc7c48a
--- /dev/null
+++ b/2024/9.c
@@ -0,0 +1,76 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <assert.h>
+
+#define INPUTLEN 20000
+
+static int* expand(size_t *lenp, const char *mp, size_t maplen) {
+ size_t len = 0;
+ for (size_t i = 0; i < maplen; i++) len += mp[i] - '0';
+
+ int *disk = malloc(len * sizeof(int));
+ size_t cursor = 0;
+ for (size_t i = 0; i + 1 < maplen; i += 2) {
+ for (int j = 0; j < mp[i] - '0'; j++) disk[cursor++] = i / 2;
+ for (int j = 0; j < mp[i+1] - '0'; j++) disk[cursor++] = -1;
+ }
+ if (maplen % 2 == 1) {
+ size_t i = maplen - 1;
+ for (int j = 0; j < mp[i] - '0'; j++) disk[cursor++] = i / 2;
+ }
+ *lenp = len;
+ return disk;
+}
+
+static size_t compact(int *disk, size_t len) {
+ size_t j = len; // one past the last non-empty block
+ while (j > 0 && disk[j-1] == -1) j--;
+ for (size_t i = 0; i < j - 1; i++) {
+ if (disk[i] != -1) continue;
+ disk[i] = disk[--j];
+ while (j > 0 && disk[j-1] == -1) j--;
+ }
+ return j;
+}
+
+static size_t defragment(int *disk, size_t len) {
+ // TODO
+}
+
+static size_t checksum(int *disk, size_t len) {
+ size_t sum = 0;
+ for (size_t i = 0; i < len && disk[i] != -1; i++) {
+ sum += i * disk[i];
+ }
+ return sum;
+}
+
+static void print_disk(int *disk, size_t len) {
+ for (size_t i = 0; i < len; i++) {
+ if (i != 0) putchar(' ');
+ if (disk[i] == -1) putchar('.');
+ else printf("%d", disk[i]);
+ }
+ putchar('\n');
+}
+
+int main(void) {
+ char *diskmap = malloc(INPUTLEN + 1);
+ size_t nr = fread(diskmap, 1, INPUTLEN, stdin);
+ assert(nr <= INPUTLEN);
+ while (nr > 0 && isspace(diskmap[nr-1])) nr--;
+ diskmap[nr] = 0;
+
+ size_t disklen;
+ int *disk = expand(&disklen, diskmap, nr);
+ int *disk2 = malloc(disklen * sizeof(int));
+ memcpy(disk2, disk, disklen * sizeof(int));
+
+ size_t disklen1 = compact(disk, disklen);
+ printf("%zu\n", checksum(disk, disklen1));
+
+ size_t disklen2 = defragment(disk2, disklen);
+ printf("%zu\n", checksum(disk2, disklen2));
+}
diff --git a/2024/Makefile b/2024/Makefile
index 0d5001f..97c6c1c 100644
--- a/2024/Makefile
+++ b/2024/Makefile
@@ -1,13 +1,18 @@
+C_SRC := $(wildcard *.c)
+C_EXE := $(C_SRC:.c=)
HS_SRC := $(wildcard *.hs)
HS_EXE := $(HS_SRC:.hs=)
OBJDIR := .obj
.PHONY: all clean
-all: $(HS_EXE)
+all: $(C_EXE) $(HS_EXE)
clean:
- rm -rf $(HS_EXE) $(OBJDIR)
+ rm -rf $(C_EXE) $(HS_EXE) $(OBJDIR)
+
+$(C_EXE): %: %.c
+ gcc -Wall -Wextra -std=c23 -O2 -o $@ $<
$(HS_EXE): %: %.hs | $(OBJDIR)
ghc -Wall -hidir $(OBJDIR) -odir $(OBJDIR) -o $@ $<