Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Aoc days 9, 10, 11 #446

Merged
merged 11 commits into from
Dec 11, 2023
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 7 additions & 6 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,12 @@
# ide stuff
/.vscode/

# Advent of Code input files https://adventofcode.com/
# These are large text files, and each AoC user gets different input files.
# Tests use sampleinput.txt files, copied from problem descriptions
# Advent of Code files https://adventofcode.com/
# Inputs are large text files, and each AoC user gets different input files.
# Tests use sampleinput.txt files, copied from problem descriptions.
#
# Creator of AoC tells people not to commit inputs to git. I also cannot
# commit problem descriptions to cit because of copyright.
Akuli marked this conversation as resolved.
Show resolved Hide resolved
/examples/aoc2023/day*/input
/examples/aoc2023/day*/input.txt

# files created by https://github.com/scarvalhojr/aoc-cli
# not sure if I can commit these to git because copyright
/examples/aoc2023/day*/puzzle.md
48 changes: 48 additions & 0 deletions examples/aoc2023/day09/part1.jou
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import "stdlib/io.jou"
import "stdlib/ascii.jou"
import "stdlib/str.jou"
import "stdlib/mem.jou"


def predict_next(nums: long*, len: int) -> long:
all_zero = True
for i = 0; i < len; i++:
if nums[i] != 0:
all_zero = False
break

if all_zero:
return 0

diffs: long* = malloc(sizeof(diffs[0]) * len)
for i = 1; i < len; i++:
diffs[i-1] = nums[i]-nums[i-1]

result = nums[len-1] + predict_next(diffs, len-1)
free(diffs)
return result


# return value is an array terminated by nums_len=-1
def main() -> int:
f = fopen("sampleinput.txt", "r")
assert f != NULL

line: byte[1000]
result: long = 0

while fgets(line, sizeof(line) as int, f) != NULL:
nums: long[100]
nnums = 0
parts = split_by_ascii_whitespace(line)
for p = parts; *p != NULL; p++:
assert nnums < sizeof(nums)/sizeof(nums[0])
nums[nnums++] = atoll(*p)
free(parts)

result += predict_next(nums, nnums)

fclose(f)

printf("%lld\n", result) # Output: 114
return 0
62 changes: 62 additions & 0 deletions examples/aoc2023/day09/part2.jou
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import "stdlib/io.jou"
import "stdlib/ascii.jou"
import "stdlib/str.jou"
import "stdlib/mem.jou"


def predict_next(nums: long*, len: int) -> long:
all_zero = True
for i = 0; i < len; i++:
if nums[i] != 0:
all_zero = False
break

if all_zero:
return 0

diffs: long* = malloc(sizeof(diffs[0]) * len)
for i = 1; i < len; i++:
diffs[i-1] = nums[i]-nums[i-1]

result = nums[len-1] + predict_next(diffs, len-1)
free(diffs)
return result


def swap(a: long*, b: long*) -> None:
tmp = *a
*a = *b
*b = tmp


def reverse(nums: long*, len: int) -> None:
p = nums
q = &nums[len-1]
while p < q:
swap(p++, q--)


# return value is an array terminated by nums_len=-1
def main() -> int:
f = fopen("sampleinput.txt", "r")
assert f != NULL

line: byte[1000]
result: long = 0

while fgets(line, sizeof(line) as int, f) != NULL:
nums: long[100]
nnums = 0
parts = split_by_ascii_whitespace(line)
for p = parts; *p != NULL; p++:
assert nnums < sizeof(nums)/sizeof(nums[0])
nums[nnums++] = atoll(*p)
free(parts)

reverse(nums, nnums)
result += predict_next(nums, nnums)

fclose(f)

printf("%lld\n", result) # Output: 2
return 0
3 changes: 3 additions & 0 deletions examples/aoc2023/day09/sampleinput.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
0 3 6 9 12 15
1 3 6 10 15 21
10 13 16 21 30 45
104 changes: 104 additions & 0 deletions examples/aoc2023/day10/part1.jou
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
import "stdlib/io.jou"
import "stdlib/mem.jou"
import "stdlib/str.jou"


class Input:
width: int
height: int
data: byte*

def is_in_bounds(self, point: int[2]) -> bool:
x = point[0]
y = point[1]
return 0 <= x and x < self->width and 0 <= y and y < self->height

def get(self, point: int[2]) -> byte:
assert self->is_in_bounds(point)
x = point[0]
y = point[1]
return self->data[(self->width + 1)*y + x]


def find_S(input: Input*) -> int[2]:
for x = 0; x < input->width; x++:
for y = 0; y < input->height; y++:
if input->get([x, y]) == 'S':
return [x, y]

assert False


def get_dirs(c: byte) -> int[2][2]:
if c == '7':
return [[-1, 0], [0, 1]]
if c == 'J':
return [[-1, 0], [0, -1]]
if c == 'L':
return [[1, 0], [0, -1]]
if c == 'F':
return [[1, 0], [0, 1]]
if c == '-':
return [[-1, 0], [1, 0]]
if c == '|':
return [[0, -1], [0, 1]]

assert False


def eq(a: int[2], b: int[2]) -> bool:
return a[0] == b[0] and a[1] == b[1]


def find_initial_direction(input: Input*, S: int[2]) -> int[2]:
directions = [[0,1], [0,-1], [1,0], [-1,0]]
for d = &directions[0]; d < &directions[4]; d++:
S_to_neighbor = *d
neighbor_to_S = [-S_to_neighbor[0], -S_to_neighbor[1]]
neighbor = [S[0] + S_to_neighbor[0], S[1] + S_to_neighbor[1]]

if input->is_in_bounds(neighbor) and input->get(neighbor) != '.':
dirs = get_dirs(input->get(neighbor))
if eq(dirs[0], S_to_neighbor) or eq(dirs[1], S_to_neighbor):
return S_to_neighbor

assert False


def main() -> int:
max_len = 100000
input = Input{data = calloc(1, max_len+1)}

f = fopen("sampleinput.txt", "r")
assert f != NULL
fread(input.data, 1, max_len, f)
fclose(f)

input.width = strcspn(input.data, "\n") as int
input.height = (strlen(input.data) as int) / (input.width + 1)

point = find_S(&input)

# take first step away from S
dir = find_initial_direction(&input, point)
point[0] += dir[0]
point[1] += dir[1]
loop_length = 1

while input.get(point) != 'S':
came_from = [-dir[0], -dir[1]]
dirs = get_dirs(input.get(point))
assert eq(came_from, dirs[0]) or eq(came_from, dirs[1])
if eq(came_from, dirs[0]):
dir = dirs[1]
else:
dir = dirs[0]
point[0] += dir[0]
point[1] += dir[1]
loop_length++

assert loop_length % 2 == 0
printf("%d\n", loop_length / 2) # Output: 4

free(input.data)
return 0
Loading
Loading