#!/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')