155 lines
4.7 KiB
Python
155 lines
4.7 KiB
Python
#!/bin/python3
|
|
import sys,time,re
|
|
from pprint import pprint
|
|
from termcolor import colored
|
|
import secrets
|
|
|
|
sys.path.insert(0, '../../')
|
|
from fred import get_re,loadFile,addTuples,flood_fill
|
|
start_time = time.time()
|
|
|
|
input_f = 'test'
|
|
size_r = 7
|
|
size_c = 11
|
|
|
|
input_f = 'input'
|
|
size_r = 103
|
|
size_c = 101
|
|
|
|
grid = [['.']*size_c]*size_r
|
|
|
|
def nprint(grid,pos=None,x=None,positions:list=None):
|
|
for r in range(size_r):
|
|
for c in range(size_c):
|
|
if (c,r) == pos and positions is None:
|
|
print(x,end='')
|
|
elif positions is not None:
|
|
if (c,r) in positions:
|
|
print(colored(x,secrets.choice(['green','yellow','blue','magenta','white','red','cyan'])),end='')
|
|
else:
|
|
print(' ',end='')
|
|
else:
|
|
print(' ',end='')
|
|
print()
|
|
|
|
#########################################
|
|
# #
|
|
# Part 1 #
|
|
# #
|
|
#########################################
|
|
def part1():
|
|
instructions = loadFile(input_f)
|
|
for idx,inst in enumerate(instructions):
|
|
match = get_re(r"^p=(-?\d+),(-?\d+) v=(-?\d+),(-?\d+)",inst)
|
|
|
|
instructions[idx] = [(int(match.group(1)),int(match.group(2))),(int(match.group(3)),int(match.group(4)))]
|
|
|
|
coordinates = {}
|
|
initial = {}
|
|
for idx,inst in enumerate(instructions):
|
|
|
|
pos = inst[0]
|
|
vel = inst[1]
|
|
if pos not in initial:
|
|
initial[pos] = 0
|
|
initial[pos] += 1
|
|
|
|
length = 100
|
|
for i in range (0,length):
|
|
pos = addTuples(pos,vel)
|
|
if pos[0] < 0:
|
|
pos = (pos[0]+size_c,pos[1])
|
|
if pos[0] >= size_c:
|
|
pos = (pos[0]-size_c,pos[1])
|
|
if pos[1] < 0:
|
|
pos = (pos[0],pos[1]+size_r)
|
|
if pos[1] >= size_r:
|
|
pos = (pos[0],pos[1]-size_r)
|
|
|
|
if pos not in coordinates:
|
|
coordinates[pos] = 0
|
|
coordinates[pos] += 1
|
|
|
|
center = (int((size_r-1)/2),int((size_c-1)/2))
|
|
|
|
TL = 0 #top left
|
|
BL = 0 #bottom left
|
|
TR = 0 #top right
|
|
BR = 0 #bottom right
|
|
for v in coordinates:
|
|
if v[0] < center[1] and v[1] < center[0]:
|
|
#print(v,'top left',coordinates[v])
|
|
TL += coordinates[v]
|
|
if v[0] > center[1] and v[1] < center[0]:
|
|
#print(v,'top right',coordinates[v])
|
|
TR += coordinates[v]
|
|
if v[0] > center[1] and v[1] > center[0]:
|
|
#print(v,'bot right',coordinates[v])
|
|
BR += coordinates[v]
|
|
if v[0] < center[1] and v[1] > center[0]:
|
|
#print(v,'bot left',coordinates[v])
|
|
BL += coordinates[v]
|
|
|
|
#print(center)
|
|
return TL*TR*BR*BL
|
|
start_time = time.time()
|
|
print('Part 1:',part1(), '\t\t', round((time.time() - start_time)*1000), 'ms')
|
|
|
|
|
|
#########################################
|
|
# #
|
|
# Part 2 #
|
|
# #
|
|
#########################################
|
|
def part2():
|
|
instructions = loadFile(input_f)
|
|
cords = []
|
|
for idx,inst in enumerate(instructions):
|
|
match = get_re(r"^p=(-?\d+),(-?\d+) v=(-?\d+),(-?\d+)",inst)
|
|
|
|
instructions[idx] = [(int(match.group(1)),int(match.group(2))),(int(match.group(3)),int(match.group(4)))]
|
|
cords.append(instructions[idx][0])
|
|
|
|
count = 0
|
|
|
|
def generate():
|
|
coordinates = {}
|
|
for idx,inst in enumerate(instructions):
|
|
pos = inst[0]
|
|
vel = inst[1]
|
|
|
|
pos = addTuples(pos,vel)
|
|
if pos[0] < 0:
|
|
pos = (pos[0]+size_c,pos[1])
|
|
if pos[0] >= size_c:
|
|
pos = (pos[0]-size_c,pos[1])
|
|
if pos[1] < 0:
|
|
pos = (pos[0],pos[1]+size_r)
|
|
if pos[1] >= size_r:
|
|
pos = (pos[0],pos[1]-size_r)
|
|
instructions[idx] = [pos,vel]
|
|
cords[idx] = pos
|
|
if pos not in coordinates:
|
|
coordinates[pos] = 0
|
|
coordinates[pos] += 1
|
|
return coordinates
|
|
|
|
while True:
|
|
|
|
coordinates = generate()
|
|
|
|
count += 1
|
|
|
|
visited = []
|
|
if 2 not in coordinates.values():
|
|
for pos in coordinates.keys():
|
|
if pos not in visited:
|
|
t_visited = flood_fill(coordinates.keys(),pos)
|
|
visited += t_visited
|
|
|
|
if len(t_visited) > 10:
|
|
nprint(grid,x='*',positions=coordinates)
|
|
|
|
return count
|
|
start_time = time.time()
|
|
print('Part 2:',part2(), '\t\t', round((time.time() - start_time)*1000), 'ms') |