Skip to content

Commit

Permalink
Merge branch 'main' into self-hosted-half
Browse files Browse the repository at this point in the history
  • Loading branch information
Akuli committed Dec 16, 2023
2 parents fbc186e + 0023fec commit e169dc9
Show file tree
Hide file tree
Showing 14 changed files with 688 additions and 201 deletions.
52 changes: 10 additions & 42 deletions examples/aoc2023/day10/part1.jou
Original file line number Diff line number Diff line change
@@ -1,32 +1,6 @@
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
import "../grid.jou"


def get_dirs(c: byte) -> int[2][2]:
Expand All @@ -50,43 +24,37 @@ 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]:
def find_initial_direction(grid: Grid*, 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 = [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 grid->is_in_bounds(neighbor) and grid->get(neighbor) != '.':
dirs = get_dirs(grid->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)
grid = read_grid_from_file(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)
point = grid.find_first('S')

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

while input.get(point) != 'S':
while grid.get(point) != 'S':
came_from = [-dir[0], -dir[1]]
dirs = get_dirs(input.get(point))
dirs = get_dirs(grid.get(point))
assert eq(came_from, dirs[0]) or eq(came_from, dirs[1])
if eq(came_from, dirs[0]):
dir = dirs[1]
Expand All @@ -99,5 +67,5 @@ def main() -> int:
assert loop_length % 2 == 0
printf("%d\n", loop_length / 2) # Output: 4

free(input.data)
free(grid.data)
return 0
54 changes: 11 additions & 43 deletions examples/aoc2023/day10/part2.jou
Original file line number Diff line number Diff line change
@@ -1,33 +1,7 @@
import "stdlib/io.jou"
import "stdlib/mem.jou"
import "stdlib/str.jou"
import "stdlib/math.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
import "../grid.jou"


def get_dirs(c: byte) -> int[2][2]:
Expand All @@ -51,14 +25,14 @@ 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]:
def find_initial_direction(grid: Grid*, 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 = [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 grid->is_in_bounds(neighbor) and grid->get(neighbor) != '.':
dirs = get_dirs(grid->get(neighbor))
if eq(dirs[0], S_to_neighbor) or eq(dirs[1], S_to_neighbor):
return S_to_neighbor

Expand Down Expand Up @@ -107,31 +81,25 @@ def polygon_area(corners: int[2]*, ncorners: int) -> int:


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

f = fopen("sampleinput2.txt", "r")
assert f != NULL
fread(input.data, 1, max_len, f)
grid = read_grid_from_file(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)
point = grid.find_first('S')

loop: int[2]* = malloc(input.width * input.height * sizeof(loop[0]))
loop: int[2]* = malloc(grid.width * grid.height * sizeof(loop[0]))
loop[0] = point

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

while input.get(point) != 'S':
while grid.get(point) != 'S':
came_from = [-dir[0], -dir[1]]
dirs = get_dirs(input.get(point))
dirs = get_dirs(grid.get(point))
assert eq(came_from, dirs[0]) or eq(came_from, dirs[1])
if eq(came_from, dirs[0]):
dir = dirs[1]
Expand Down Expand Up @@ -161,6 +129,6 @@ def main() -> int:
# towards the inside.
printf("%d\n", area_along_middle_of_path + 1 - loop_length/2) # Output: 4

free(input.data)
free(grid.data)
free(loop)
return 0
80 changes: 22 additions & 58 deletions examples/aoc2023/day11/part1.jou
Original file line number Diff line number Diff line change
Expand Up @@ -2,85 +2,49 @@ import "stdlib/io.jou"
import "stdlib/mem.jou"
import "stdlib/str.jou"
import "stdlib/math.jou"
import "../grid.jou"


class Input:
width: int
height: int
data: byte*
def duplicate_blank_lines(grid: Grid*) -> None:
grid->data = realloc(grid->data, 2*strlen(grid->data) + 1)
assert grid->data != NULL

def duplicate_blank_lines(self) -> None:
self->data = realloc(self->data, 2*strlen(self->data) + 1)
assert self->data != NULL

y = 0
while y < self->height:
if strspn(&self->data[(self->width + 1)*y], ".") == self->width:
# duplicate row
blank_start = &self->data[(self->width + 1)*y]
next_start = &self->data[(self->width + 1)*(y+1)]
memmove(next_start, blank_start, strlen(blank_start) + 1)
y += 2
self->height++
else:
y++

def transpose(self) -> None:
old_content = strdup(self->data)
old_width = self->width
old_height = self->height
self->width = old_height
self->height = old_width

memset(self->data, '\n', strlen(self->data))
for x = 0; x < self->width; x++:
for y = 0; y < self->height; y++:
self->data[(self->width + 1)*y + x] = old_content[(old_width + 1)*x + y]

free(old_content)

# array is terminated by [-1, -1]
def get_hashtag_coords(self) -> int[2]*:
result: int[2]* = malloc(sizeof(result[0]) * (self->width * self->height + 1))
result_len = 0
for y = 0; y < self->height; y++:
for x = 0; x < self->width; x++:
if self->data[(self->width + 1)*y + x] == '#':
result[result_len++] = [x, y]

result[result_len] = [-1, -1]
return result
y = 0
while y < grid->height:
if strspn(&grid->data[(grid->width + 1)*y], ".") == grid->width:
# duplicate row
blank_start = &grid->data[(grid->width + 1)*y]
next_start = &grid->data[(grid->width + 1)*(y+1)]
memmove(next_start, blank_start, strlen(blank_start) + 1)
y += 2
grid->height++
else:
y++


def manhattan_distance(a: int[2], b: int[2]) -> int:
return abs(a[0]-b[0]) + abs(a[1]-b[1])


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)
grid = read_grid_from_file(f)
fclose(f)

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

input.duplicate_blank_lines()
input.transpose()
input.duplicate_blank_lines()
input.transpose()
duplicate_blank_lines(&grid)
grid.transpose()
duplicate_blank_lines(&grid)
grid.transpose()

coords = input.get_hashtag_coords()
coords = grid.find_all('#')

sum = 0
for i = 0; coords[i][0] != -1; i++:
for k = 0; k < i; k++:
sum += manhattan_distance(coords[i], coords[k])
printf("%d\n", sum) # Output: 374

free(input.data)
free(grid.data)
free(coords)
return 0
Loading

0 comments on commit e169dc9

Please sign in to comment.