Skip to content

Commit

Permalink
aoc day9 part2
Browse files Browse the repository at this point in the history
  • Loading branch information
Akuli committed Dec 9, 2024
1 parent 7bf0a2b commit fcf38fa
Show file tree
Hide file tree
Showing 2 changed files with 108 additions and 1 deletion.
2 changes: 1 addition & 1 deletion examples/aoc2024/day09/part1.jou
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
107 changes: 107 additions & 0 deletions examples/aoc2024/day09/part2.jou
Original file line number Diff line number Diff line change
@@ -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

0 comments on commit fcf38fa

Please sign in to comment.