Skip to content

Commit

Permalink
day15 part 2
Browse files Browse the repository at this point in the history
  • Loading branch information
Akuli committed Dec 16, 2024
1 parent be701a2 commit 4f3410b
Show file tree
Hide file tree
Showing 5 changed files with 226 additions and 6 deletions.
12 changes: 6 additions & 6 deletions examples/aoc2024/day15/part1.jou
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import "stdlib/str.jou"
import "../../aoc2023/grid.jou"


def move_right(grid: Grid*, start: byte*) -> None:
def move_right(start: byte*) -> None:
assert start != NULL
assert *start == '@'

Expand Down Expand Up @@ -36,27 +36,27 @@ def horizontal_mirror(grid: Grid*) -> None:

def move(grid: Grid*, how: byte) -> None:
if how == '>':
move_right(grid, strstr(grid->data, "@"))
move_right(strstr(grid->data, "@"))
elif how == 'v':
grid->transpose()
move_right(grid, strstr(grid->data, "@"))
move_right(strstr(grid->data, "@"))
grid->transpose()
elif how == '<':
horizontal_mirror(grid)
move_right(grid, strstr(grid->data, "@"))
move_right(strstr(grid->data, "@"))
horizontal_mirror(grid)
elif how == '^':
grid->transpose()
horizontal_mirror(grid)
move_right(grid, strstr(grid->data, "@"))
move_right(strstr(grid->data, "@"))
horizontal_mirror(grid)
grid->transpose()
else:
assert False


def main() -> int:
f = fopen("sampleinput.txt", "r")
f = fopen("sampleinput1.txt", "r")
assert f != NULL
grid = read_grid_from_file(f)

Expand Down
190 changes: 190 additions & 0 deletions examples/aoc2024/day15/part2.jou
Original file line number Diff line number Diff line change
@@ -0,0 +1,190 @@
import "stdlib/io.jou"
import "stdlib/mem.jou"
import "stdlib/str.jou"
import "../../aoc2023/grid.jou"


def move_right(start: byte*) -> None:
assert start != NULL
assert *start == '@'

relevant_length = strspn(start, "@.[]")

first_blank = -1
for i = 0; i < relevant_length; i++:
if start[i] == '.':
first_blank = i
break

if first_blank == -1:
# no room to move, do nothing
return

# shift boxes to the right
memmove(&start[2], &start[1], first_blank - 1)
start[0] = '.'
start[1] = '@'


# x_left and y specify the location of "[" part of box
def can_move_box_up(grid: Grid*, x: int, y: int) -> bool:
if grid->get([x, y]) == '[':
x_left = x
x_right = x+1
elif grid->get([x, y]) == ']':
x_left = x-1
x_right = x
else:
assert False

if grid->get([x_left, y-1]) == '#' or grid->get([x_right, y-1]) == '#':
# bumping into wall
return False

for x = x_left; x <= x_right; x++:
if strchr("[]", grid->get([x, y-1])) != NULL and not can_move_box_up(grid, x, y-1):
# Some kind of box (aligned or not) above, and it won't move.
return False

return True


def move_box_up(grid: Grid*, x: int, y: int) -> None:
if grid->get([x, y]) == '[':
x_left = x
x_right = x+1
elif grid->get([x, y]) == ']':
x_left = x-1
x_right = x
else:
assert False

for x = x_left; x <= x_right; x++:
if strchr("[]", grid->get([x, y-1])) != NULL:
move_box_up(grid, x, y-1)

assert grid->get([x_left, y-1]) == '.'
assert grid->get([x_right, y-1]) == '.'
assert grid->get([x_left, y]) == '['
assert grid->get([x_right, y]) == ']'

grid->set([x_left, y-1], '[')
grid->set([x_right, y-1], ']')
grid->set([x_left, y], '.')
grid->set([x_right, y], '.')


def can_move_up(grid: Grid*) -> bool:
pos: int[2] = grid->find_first('@')
above = [pos[0], pos[1] - 1]

return (
grid->get(above) == '.'
or (
strchr("[]", grid->get(above)) != NULL
and can_move_box_up(grid, above[0], above[1])
)
)


def move_up(grid: Grid*) -> None:
pos: int[2] = grid->find_first('@')
above = [pos[0], pos[1] - 1]

if strchr("[]", grid->get(above)) != NULL:
move_box_up(grid, above[0], above[1])

assert grid->get(above) == '.'
assert grid->get(pos) == '@'

grid->set(above, '@')
grid->set(pos, '.')


def horizontal_mirror(grid: Grid*) -> None:
bytes_per_row = grid->width + 1
for y = 0; y < grid->height; y++:
first = &grid->data[bytes_per_row * y]
last = &first[grid->width - 1]
while first < last:
memswap(first++, last--, 1)


def vertical_mirror(grid: Grid*) -> None:
bytes_per_row = grid->width + 1
first = grid->data
last = &first[bytes_per_row*(grid->height - 1)]

while first < last:
memswap(first, last, grid->width)
first = &first[bytes_per_row]
last = &last[-bytes_per_row]


def move(grid: Grid*, how: byte) -> None:
if how == '>':
move_right(strstr(grid->data, "@"))
elif how == '<':
horizontal_mirror(grid)
move_right(strstr(grid->data, "@"))
horizontal_mirror(grid)
elif how == '^':
if can_move_up(grid):
move_up(grid)
elif how == 'v':
vertical_mirror(grid)
if can_move_up(grid):
move_up(grid)
vertical_mirror(grid)
else:
assert False


def double_width(grid: Grid*) -> None:
new_grid = Grid{
width = 2 * grid->width,
height = grid->height,
data = malloc((2*grid->width + 1)*grid->height + 1),
}
new_grid.data[0] = '\0'
for y = 0; y < grid->height; y++:
for x = 0; x < grid->width; x++:
if grid->get([x, y]) == 'O':
strcat(new_grid.data, "[]")
elif grid->get([x, y]) == '@':
strcat(new_grid.data, "@.")
else:
s = [grid->get([x, y]), grid->get([x, y]), '\0']
strcat(new_grid.data, s)
strcat(new_grid.data, "\n")

free(grid->data)
*grid = new_grid


def main() -> int:
f = fopen("sampleinput2.txt", "r")
assert f != NULL
grid = read_grid_from_file(f)
double_width(&grid)

while True:
#getchar()
c = fgetc(f)
if c == -1: # TODO: EOF constant
break
if c == '\n':
continue
move(&grid, c as byte)

fclose(f)

result = 0
for x = 0; x < grid.width; x++:
for y = 0; y < grid.height; y++:
if grid.get([x, y]) == '[':
result += 100*y + x
printf("%d\n", result) # Output: 9021

free(grid.data)
return 0
File renamed without changes.
9 changes: 9 additions & 0 deletions examples/aoc2024/day15/sampleinput2-simple.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#######
#...#.#
#.....#
#..OO@#
#..O..#
#.....#
#######

<vv<<^^<<^^
21 changes: 21 additions & 0 deletions examples/aoc2024/day15/sampleinput2.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
##########
#..O..O.O#
#......O.#
#.OO..O.O#
#[email protected].#
#O#..O...#
#O..O..O.#
#.OO.O.OO#
#....O...#
##########

<vv>^<v^>v>^vv^v>v<>v^v<v<^vv<<<^><<><>>v<vvv<>^v^>^<<<><<v<<<v^vv^v>^
vvv<<^>^v^^><<>>><>^<<><^vv^^<>vvv<>><^^v>^>vv<>v<<<<v<^v>^<^^>>>^<v<v
><>vv>v^v^<>><>>>><^^>vv>v<^^^>>v^v^<^^>v^^>v^<^v>v<>>v^v^<v>v^^<^^vv<
<<v<^>>^^^^>>>v^<>vvv^><v<<<>^^^vv^<vvv>^>v<^^^^v<>^>vvvv><>>v^<<^^^^^
^><^><>>><>^^<<^^v>>><^<v>^<vv>>v>>>^v><>^v><<<<v>>v<v<v>vvv>^<><<>^><
^>><>^v<><^vvv<^^<><v<<<<<><^v<<<><<<^^<v<^^^><^>>^<v^><<<^>>^v<v^v<v^
>^>>^v>vv>^<<^v<>><<><<v<<v><>v<^vv<<<>^^v^>^^>>><<^v>>v^v><^^>>^<>vv^
<><^^>^^^<><vvvvv^v<v<<>^v<v>v<<^><<><<><<<^^<<<^<<>><<><^^^>^^<>^>v<>
^^>vv<^v^v<vv>^<><v<^v>^^^>>>^^vvv^>vvv<>>>^<^>>>>>^<<^v>^vvv<>^<><<v>
v^^>>><<^^<>>^v^<v^vv<>v^<<>^<^v^v><^<<<><<^<v><v<>vv>>v><v^<vv<>v^<<^

0 comments on commit 4f3410b

Please sign in to comment.