135 lines
3.6 KiB
Python
135 lines
3.6 KiB
Python
#!/bin/python3
|
|
import sys,re
|
|
from pprint import pprint
|
|
sys.path.insert(0, '../../')
|
|
from fred import list2int,get_re,nprint,lprint,loadFile,toGrid,get_value_in_direction,grid_valid
|
|
|
|
input_f = 'input'
|
|
|
|
part = 2
|
|
|
|
#########################################
|
|
# #
|
|
# Part 1 #
|
|
# #
|
|
#########################################
|
|
|
|
if part == 1:
|
|
offsets = {
|
|
'up': (-1, 0),
|
|
'down': (1, 0),
|
|
'left': (0, -1),
|
|
'right': (0, 1),
|
|
}
|
|
|
|
next_direction = {
|
|
'up': 'right',
|
|
'right': 'down',
|
|
'down': 'left',
|
|
'left': 'up'
|
|
}
|
|
grid = toGrid(input_f)
|
|
|
|
center = ()
|
|
steps = []
|
|
for r in range(len(grid)):
|
|
for c in range(len(grid[0])):
|
|
if grid[r][c] == '^':
|
|
center = (r,c)
|
|
|
|
pos = center
|
|
direction = 'up'
|
|
while grid_valid(pos[0],pos[1],grid):
|
|
|
|
#dir = get_value_in_direction(grid, pos)
|
|
if get_value_in_direction(grid,pos,direction) != '#':
|
|
if pos not in steps:
|
|
steps.append(pos)
|
|
pos = (pos[0]+offsets[direction][0],pos[1]+offsets[direction][1])
|
|
elif get_value_in_direction(grid,pos,direction) == '#':
|
|
direction = next_direction[direction]
|
|
|
|
print(len(steps))
|
|
|
|
|
|
|
|
#########################################
|
|
# #
|
|
# Part 2 #
|
|
# #
|
|
#########################################
|
|
if part == 2:
|
|
offsets = {
|
|
'up': (-1, 0),
|
|
'down': (1, 0),
|
|
'left': (0, -1),
|
|
'right': (0, 1),
|
|
}
|
|
|
|
next_direction = {
|
|
'up': 'right',
|
|
'right': 'down',
|
|
'down': 'left',
|
|
'left': 'up'
|
|
}
|
|
|
|
direction = 'up'
|
|
|
|
def isLoop(grid,pos,direction):
|
|
positions = []
|
|
count = 0
|
|
l = len(grid)
|
|
|
|
while grid_valid(pos[0],pos[1],grid):
|
|
next = get_value_in_direction(grid,pos,direction)
|
|
if next == '#':
|
|
direction = next_direction[direction]
|
|
else:
|
|
cur = (pos[0],pos[1],direction)
|
|
count += 1
|
|
|
|
# Instead of loging all visited positions and their direction,
|
|
# we can break out if we have visited more places than 4x the
|
|
# grid size (4 being once for each direction).
|
|
# This actually gives us the right result
|
|
|
|
#if cur not in positions:
|
|
# positions.append(cur)
|
|
#elif cur in positions:
|
|
# return 1
|
|
|
|
if count > 4*l*l:
|
|
return 1
|
|
|
|
pos = (pos[0]+offsets[direction][0],pos[1]+offsets[direction][1])
|
|
|
|
return 0
|
|
|
|
grid = toGrid(input_f)
|
|
|
|
|
|
start = ()
|
|
steps = []
|
|
for r in range(len(grid)):
|
|
for c in range(len(grid[0])):
|
|
if grid[r][c] == '^':
|
|
start = (r,c)
|
|
|
|
pos = start
|
|
while grid_valid(pos[0],pos[1],grid):
|
|
dir = get_value_in_direction(grid, pos)
|
|
if get_value_in_direction(grid,pos,direction) != '#':
|
|
if pos not in steps:
|
|
steps.append(pos)
|
|
pos = (pos[0]+offsets[direction][0],pos[1]+offsets[direction][1])
|
|
elif get_value_in_direction(grid,pos,direction) == '#':
|
|
direction = next_direction[direction]
|
|
steps.remove(start)
|
|
print(len(steps))
|
|
|
|
result = 0
|
|
for idx,i in enumerate(steps):
|
|
grid[i[0]][i[1]] = '#'
|
|
result += isLoop(grid,start,'up')
|
|
grid[i[0]][i[1]] = '.'
|
|
print(result) |