From fcf38fa8b63e64551a7d942f34a9b66d9c240ad5 Mon Sep 17 00:00:00 2001 From: Akuli Date: Mon, 9 Dec 2024 19:23:28 +0200 Subject: [PATCH] aoc day9 part2 --- examples/aoc2024/day09/part1.jou | 2 +- examples/aoc2024/day09/part2.jou | 107 +++++++++++++++++++++++++++++++ 2 files changed, 108 insertions(+), 1 deletion(-) create mode 100644 examples/aoc2024/day09/part2.jou diff --git a/examples/aoc2024/day09/part1.jou b/examples/aoc2024/day09/part1.jou index e2b8db7b2..12e30b946 100644 --- a/examples/aoc2024/day09/part1.jou +++ b/examples/aoc2024/day09/part1.jou @@ -67,7 +67,7 @@ def main() -> int: assert disk_map_string != NULL disk_map_string[0] = '\0' - f = fopen("input", "r") + f = fopen("sampleinput.txt", "r") assert f != NULL fgets(disk_map_string, max_size, f) fclose(f) diff --git a/examples/aoc2024/day09/part2.jou b/examples/aoc2024/day09/part2.jou new file mode 100644 index 000000000..67b53e347 --- /dev/null +++ b/examples/aoc2024/day09/part2.jou @@ -0,0 +1,107 @@ +import "stdlib/io.jou" +import "stdlib/str.jou" +import "stdlib/mem.jou" +import "stdlib/ascii.jou" + + +# Return value contains: +# >=0 file id +# -1 blank +# -2 last of disk +def parse_disk_map(disk_map_string: byte*) -> int*: + result: int* = malloc((strlen(disk_map_string) * 10 + 1) * sizeof(result[0])) + p = result + + for i = 0; disk_map_string[i] != '\0'; i++: + assert is_ascii_digit(disk_map_string[i]) + + if i % 2 == 0: + # It is a file + file_id = i/2 + size = disk_map_string[i] - '0' + while size --> 0: + *p++ = file_id + else: + # It is blank space + size = disk_map_string[i] - '0' + while size --> 0: + *p++ = -1 + + *p = -2 + return result + + +def swap(a: int*, b: int*) -> None: + temp = *a + *a = *b + *b = temp + + +def swap_slice(a: int*, b: int*, length: int) -> None: + for i = 0; i < length; i++: + swap(&a[i], &b[i]) + + +def find_blank_spot(start: int*, end: int*, length_required: int) -> int*: + for p = start; p <= &end[-length_required]; p++: + ok = True + for i = 0; i < length_required; i++: + if p[i] != -1: + ok = False + break + if ok: + return p + return NULL + + +def fill_slots(disk_map: int*) -> None: + assert disk_map[0] != -2 # not empty + last = disk_map + while last[1] != -2: + last++ + + assert *last != -1 # not blank at end + + for file_id = *last; file_id >= 0; file_id--: + # Attempt to move file + start = disk_map + while *start != file_id: + start++ + + length = 0 + while start[length] == file_id: + length++ + + blank_spot = find_blank_spot(disk_map, start, length) + if blank_spot != NULL: + swap_slice(blank_spot, start, length) + + +def compute_checksum(disk_map: int*) -> long: + result = 0L + for i = 0; disk_map[i] != -2; i++: + if disk_map[i] != -1: + result += (disk_map[i] as long) * (i as long) + return result + + +def main() -> int: + max_size = 100000 + disk_map_string: byte* = malloc(max_size) + assert disk_map_string != NULL + disk_map_string[0] = '\0' + + f = fopen("sampleinput.txt", "r") + assert f != NULL + fgets(disk_map_string, max_size, f) + fclose(f) + trim_ascii_whitespace(disk_map_string) + + disk_map = parse_disk_map(disk_map_string) + free(disk_map_string) + + fill_slots(disk_map) + printf("%lld\n", compute_checksum(disk_map)) # Output: 2858 + + free(disk_map) + return 0