Skip to content
Snippets Groups Projects
Verified Commit 2f1fdcf1 authored by Christopher Bohn's avatar Christopher Bohn :thinking:
Browse files

Completed 2023 Day 10

parent 1ba0b5b1
Branches main
No related tags found
No related merge requests found
import functools
from typing import List, Tuple
from ImportData import import_data
day: int = 10
# sample_data: List[str] = '''
# .....
# .S-7.
# .|.|.
# .L-J.
# .....
# '''.split('\n')[1:-1]
# sample_data: List[str] = '''
# 7-F7-
# .FJ|7
# SJLL7
# |F--J
# LJ.LJ
# '''.split('\n')[1:-1]
# sample_data: List[str] = '''
# ...........
# .S-------7.
# .|F-----7|.
# .||.....||.
# .||.....||.
# .|L-7.F-J|.
# .|..|.|..|.
# .L--J.L--J.
# ...........
# '''.split('\n')[1:-1]
# sample_data: List[str] = '''
# ..........
# .S------7.
# .|F----7|.
# .||....||.
# .||....||.
# .|L-7F-J|.
# .|..||..|.
# .L--JL--J.
# ..........
# '''.split('\n')[1:-1]
# sample_data: List[str] = '''
# .F----7F7F7F7F-7....
# .|F--7||||||||FJ....
# .||.FJ||||||||L7....
# FJL7L7LJLJ||LJ.L-7..
# L--J.L7...LJS7F-7L7.
# ....F-J..F7FJ|L7L7L7
# ....L7.F7||L7|.L7L7|
# .....|FJLJ|FJ|F7|.LJ
# ....FJL-7.||.||||...
# ....L---J.LJ.LJLJ...
# '''.split('\n')[1:-1]
sample_data: List[str] = '''
FF7FSF7F7F7F7F7F---7
L|LJ||||||||||||F--J
FL-7LJLJ||||||LJL-77
F--JF--7||LJLJ7F7FJ-
L---JF-JLJ.||-FJLJJ7
|F|F-JF---7F7-L7L|7|
|FFJF7L7F-JF7|JL---7
7-L-JL7||F7|L7F-7F7|
L.L7LFJ|||||FJL7||LJ
L7JLJL-JLJLJL--JLJ.L
'''.split('\n')[1:-1]
data_structure: type = Tuple[int, int, str, List[str]]
def parse_data(data: List[str]) -> data_structure:
initial_row: int = -1
initial_column: int = -1
initial_pipe: str
number_of_rows = len(data)
number_of_columns = len(data[0])
for row in range(number_of_rows):
for column in range(number_of_columns):
if data[row][column] == 'S':
initial_row = row
initial_column = column
initial_pipe = input('What is the shape of the initial pipe? ')
return initial_row, initial_column, initial_pipe, data
def part1(data: data_structure) -> int:
row, column, pipe, pipes = data
previous_locations: List[Tuple[int, int]] = [(row, column), (row, column)]
current_locations: List[Tuple[int, int]]
match pipe:
case '|':
current_locations = [(row + 1, column), (row - 1, column)]
case '-':
current_locations = [(row, column + 1), (row, column - 1)]
case 'L':
current_locations = [(row, column + 1), (row - 1, column)]
case 'J':
current_locations = [(row, column - 1), (row - 1, column)]
case '7':
current_locations = [(row, column - 1), (row + 1, column)]
case 'F':
current_locations = [(row, column + 1), (row + 1, column)]
case _:
raise ValueError(f'{pipe} at ({row},{column})')
distance: int = 1
while current_locations[0] != current_locations[1]:
distance += 1
for i in range(len(current_locations)):
previous_row, previous_column = previous_locations[i]
row, column = current_locations[i]
pipe = pipes[row][column]
previous_locations[i] = current_locations[i]
row_change = row - previous_row
column_change = column - previous_column
match pipe:
case '|' | '-':
current_locations[i] = (row + row_change, column + column_change)
case 'L' | '7':
current_locations[i] = (row + column_change, column + row_change)
case 'J' | 'F':
current_locations[i] = (row - column_change, column - row_change)
case _:
raise ValueError(f'{pipe} at ({row}, {column})')
return distance
def part2(data: data_structure) -> int:
row, column, pipe, pipes = data
# an extra copy of the pipes data, "zoomed in" to allow for gaps between pipes
tiles: [List[List[str]]] = [['I'] * (2 * len(pipes[0])) for _ in range(2 * len(pipes))]
# first, draw the main loop on the tiles copy
previous_location: Tuple[int, int] = (row, column)
current_location: Tuple[int, int]
match pipe:
case '|' | 'F':
current_location = (row + 1, column)
tiles[2 * row + 1][2 * column] = 'X'
case '-' | 'L':
current_location = (row, column + 1)
tiles[2 * row][2 * column + 1] = 'X'
case 'J' | '7':
current_location = (row, column - 1)
tiles[2 * row][2 * column - 1] = 'X'
case _:
raise ValueError(f'{pipe} at ({row},{column})')
previous_row, previous_column = previous_location
row, column = current_location
while tiles[2 * row][2 * column] != 'X':
tiles[2 * row][2 * column] = 'X'
pipe = pipes[row][column]
previous_location = current_location
row_change = row - previous_row
column_change = column - previous_column
match pipe:
case '|' | '-':
current_location = (row + row_change, column + column_change)
tiles[2 * row + row_change][2 * column + column_change] = 'X'
case 'L' | '7':
current_location = (row + column_change, column + row_change)
tiles[2 * row + column_change][2 * column + row_change] = 'X'
case 'J' | 'F':
current_location = (row - column_change, column - row_change)
tiles[2 * row - column_change][2 * column - row_change] = 'X'
case 'S':
pass
case _:
raise ValueError(f'{pipe} at ({row}, {column})')
previous_row, previous_column = previous_location
row, column = current_location
# now let's create a border
tiles = [['O'] * (2 * len(pipes[0]))] + tiles + [['O'] * (2 * len(tiles[0]))]
tiles = [['O'] + tile + ['O'] for tile in tiles]
# fill in the "outside"
finished: bool = False
while not finished:
finished = True
for row in range(1, len(tiles) - 1):
for column in range(1, len(tiles[0]) - 1):
if tiles[row][column] == 'I' and (tiles[row - 1][column] == 'O' or tiles[row][column - 1] == 'O' or
tiles[row + 1][column] == 'O' or tiles[row][column + 1] == 'O'):
tiles[row][column] = 'O'
finished = False
# now shrink it back down to size, step 1: remove the border
# arguably, this step is unnecessary, but it simplifies the expression in step 2
tiles = [row[1:-1] for row in tiles[1:-1]]
# shrink it back down to size, step 2: remove the "in between" tiles
new_tiles: List[List[str]] = []
for row in range(0, len(tiles), 2):
new_row: List[str] = []
for column in range(0, len(tiles[0]), 2):
new_row.append(tiles[row][column])
new_tiles.append(new_row)
# count the "inside"
return sum([functools.reduce(lambda x, y: x + y, map(lambda x: 1 if x == 'I' else 0, row)) for row in new_tiles])
if __name__ == '__main__':
production_ready = True
raw_data = import_data(day) if production_ready else sample_data
print(part1(parse_data(raw_data)))
print(part2(parse_data(raw_data)))
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment