Advent of Code 2022 day 22
Part 2 was incredibly painful. Maybe hand-coding if
statements isn’t the most
sensible idea.
It appears it wasn’t just me who found it painful:
Part 1
def get_card(data): return data.splitlines()[:-2] def clean_card(card): max_col = max(len(row) for row in card) return [ extend_line(row, max_col) for row in card ] def extend_line(line, col): return line + (" "*(col-len(line))) with open("22.txt") as f: data = f.read() card = clean_card(get_card(data)) instructions = data.splitlines()[-1] def get_instructions(instructions): instruction = "" for x in instructions: if x == "R" or x == "L": yield instruction instruction = "" instruction += x yield instruction def change_direction(instruction, direction): rotate = instruction[0] if rotate == "R": return (int(instruction[1:]), (direction+1)%4) elif rotate == "L": return (int(instruction[1:]), (direction-1)%4) else: return (int(instruction), direction) def get_answer(card, instructions): def valid(to, direction): row, col = to if row < 0: return valid((len(card)-1, col), direction) elif row == len(card): return valid((0, col), direction) elif col < 0: return valid((row, len(card[row])-1), direction) elif col >= len(card[row]): return valid((row, 0), direction) elif card[row][col] == "#": return False elif card[row][col] == ".": return to elif card[row][col] == " ": return next_move(to, direction) def next_move(start, direction): row, col = start if direction == 0: to = (row, col+1) elif direction == 1: to = (row+1, col) elif direction == 2: to = (row, col-1) elif direction == 3: to = (row-1, col) return valid(to, direction) def go(start, distance, direction): if distance == 0: return start if to := next_move(start, direction): return go(to, distance-1, direction) elif to is False: return start position = next_move((0, 0), 0) direction = 0 for instruction in get_instructions(instructions): distance, direction = change_direction(instruction, direction) position = go(position, distance, direction) row, col = position return (row+1)*1000 + (col+1)*4 + direction print(get_answer(card, instructions))
Part 2
# Not going to bother generalising def get_face(row, col): if row < 50: if col < 100: return 0 elif col < 150: return 1 elif row < 100: return 2 elif row < 150: # yes, I know, this is the wrong way round # I messed up. if col < 50: return 4 return 3 return 5 def get_cube(data): lines = data.splitlines()[:-2] cube = dict() for row, line in enumerate(lines): for col, char in enumerate(line): if char != " ": cube[(get_face(row, col), row%50, col%50)] = char return cube def face_to_value(position, direction): face, row, col = position if face == 0: col += 50 elif face == 1: col += 100 elif face == 2: row += 50 col += 50 elif face == 3: row += 100 col += 50 elif face == 4: row += 100 elif face == 5: row += 150 return (row+1)*1000 + (col+1)*4 + direction % 4 with open("22.txt") as f: data = f.read() cube = get_cube(data) instructions = data.splitlines()[-1] def get_instructions(instructions): instruction = "" for x in instructions: if x == "R" or x == "L": yield instruction instruction = "" instruction += x yield instruction def change_direction(instruction, direction): rotate = instruction[0] if rotate == "R": return (int(instruction[1:]), (direction+1)%4) elif rotate == "L": return (int(instruction[1:]), (direction-1)%4) else: return (int(instruction), direction) def get_answer(card, instructions): def next_move(start, direction): face, row, col = start if direction % 4 == 0: to = (face, row, col+1) elif direction % 4 == 1: to = (face, row+1, col) elif direction % 4 == 2: to = (face, row, col-1) elif direction % 4 == 3: to = (face, row-1, col) face, row, col = to new_direction = direction if row < 0: if face == 0: to = (5, col, 0) new_direction = direction+1 elif face == 1: to = (5, 49, col) elif face == 2: to = (0, 49, col) elif face == 3: to = (2, 49, col) elif face == 4: to = (2, col, 0) new_direction = direction+1 elif face == 5: to = (4, 49, col) elif row >= 50: if face == 0: to = (2, 0, col) elif face == 1: to = (2, col, 49) new_direction = direction+1 elif face == 2: to = (3, 0, col) elif face == 3: to = (5, col, 49) new_direction = direction+1 elif face == 4: to = (5, 0, col) elif face == 5: to = (1, 0, col) elif col < 0: if face == 0: to = (4, 49-row, 0) new_direction = direction+2 elif face == 1: to = (0, row, 49) elif face == 2: to = (4, 0, row) new_direction = direction-1 elif face == 3: to = (4, row, 49) elif face == 4: to = (0, 49-row, 0) new_direction = direction+2 elif face == 5: to = (0, 0, row) new_direction = direction-1 elif col >= 50: if face == 0: to = (1, row, 0) elif face == 1: to = (3, 49-row, 49) new_direction = direction+2 elif face == 2: to = (1, 49, row) new_direction = direction-1 elif face == 3: to = (1, 49-row, 49) new_direction = direction+2 elif face == 4: to = (3, row, 0) elif face == 5: to = (3, 49, row) new_direction = direction-1 if card[to] == "#": return direction % 4, False elif card[to] == ".": return new_direction % 4, to def go(start, distance, direction): if distance == 0: return direction, start new_direction, to = next_move(start, direction) if to: return go(to, distance-1, new_direction) elif to is False: return new_direction, start position = (0, 0, 0) direction = 0 for instruction in get_instructions(instructions): distance, direction = change_direction(instruction, direction) direction, position = go(position, distance, direction) return face_to_value(position, direction) print(get_answer(cube, instructions))