#!/bin/python3 import sys,time,re from pprint import pprint import numpy as np sys.path.insert(0, '../../') from fred import list2int,get_re,nprint,lprint,loadFile,toGrid,bfs,get_value_in_direction,addTuples,grid_valid start_time = time.time() input_f = 'input' ######################################### # # # Part 1 # # # ######################################### directions = { 'up': (-1, 0), 'down': (1, 0), 'left': (0, -1), 'right': (0, 1), } def get_neighbors(grid,node,visited): neighbors = [] for d in directions.keys(): t = get_value_in_direction(grid,node) if get_value_in_direction(grid,node,d) == t: n = addTuples(directions[d],node) if n not in visited: neighbors.append(n) visited.append(n) neighbors+=get_neighbors(grid,n,visited) return neighbors def part1(): grid = toGrid(input_f) visited = [] total_plots = [] for r,row in enumerate(grid): for c,col in enumerate(row): pos = (r,c) plot = [] current = get_value_in_direction(grid,pos) if pos not in visited: x = get_neighbors(grid,pos,visited) plot += x if pos not in plot: plot.append(pos) total_plots.append(plot) result = 0 for v in total_plots: sides = 0 for x,y in v: for dx, dy in directions.values(): neighbor = (x + dx, y + dy) if neighbor in v: sides += 1 total_sides = len(v) * 4 - sides result += (total_sides*len(v)) return result start_time = time.time() print('Part 1:',part1(), '\t', round((time.time() - start_time)*1000), 'ms') ######################################### # # # Part 2 # # # ######################################### def part2(): grid = toGrid(input_f) #print(grid) #nprint(grid) values = {} visited = [] total_plots = [] for r,row in enumerate(grid): for c,col in enumerate(row): pos = (r,c) plot = [] current = get_value_in_direction(grid,pos) if pos not in visited: x = get_neighbors(grid,pos,visited) plot += x if pos not in plot: plot.append(pos) if current not in values: values[current] = [] total_plots.append(plot) #pprint(total_plots) for pdx,p in enumerate(total_plots): total_plots[pdx] = sorted(p) #pprint(total_plots) #directions = [(0, 1), (0, -1), (1, 0), (-1, 0)] directions = [(0, 1), (1, 0)] #directions = [(1, 1), (1, -1), (-1, -1), (-1, 1),(0, 1), (0, -1), (1, 0), (-1, 0)] result = 0 def find_edge(r,c,p,visited): edge = True end = () for dr, dc in directions: neighbor = (r + dr, c + dc) if neighbor in p: if neighbor not in visited: #print((r,c),neighbor) visited.append((r,c)) find_edge((r + dr),(c + dc),p,visited) else: #if (r+0,c+1) not in p or (r+1,c+0) not in p: edge = False end = (r,c) #print(r,c,(dr,dc)) #input() if not edge: print(end) for p in total_plots: area = len(p) fences = 0 for r,c in p: visited = [] #print('@',(r,c),get_value_in_direction(grid,(r,c))) if get_value_in_direction(grid,(r,c),'up') != grid[r][c] and get_value_in_direction(grid,(r,c),'left') != grid[r][c]: #print('┌ corner - up+left') fences+=1 if get_value_in_direction(grid,(r,c),'up') == grid[r][c] and get_value_in_direction(grid,(r,c),'left') == grid[r][c] and get_value_in_direction(grid,(r,c),'up-left') != grid[r][c]: #print('└ corner - up+left+upleft') fences+=1 if get_value_in_direction(grid,(r,c),'left') != grid[r][c] and get_value_in_direction(grid,(r,c),'down') != grid[r][c]: #print('└ corner - left+down') fences+=1 if get_value_in_direction(grid,(r,c),'left') == grid[r][c] and get_value_in_direction(grid,(r,c),'down') == grid[r][c] and get_value_in_direction(grid,(r,c),'down-left') != grid[r][c]: #print('┐ corner - left+down+downleft') fences+=1 if get_value_in_direction(grid,(r,c),'down') != grid[r][c] and get_value_in_direction(grid,(r,c),'right') != grid[r][c]: #print('┘ corner - down+right') fences+=1 if get_value_in_direction(grid,(r,c),'down') == grid[r][c] and get_value_in_direction(grid,(r,c),'right') == grid[r][c] and get_value_in_direction(grid,(r,c),'down-right') != grid[r][c]: #print('┌ corner - down+right+downright') fences+=1 if get_value_in_direction(grid,(r,c),'right') != grid[r][c] and get_value_in_direction(grid,(r,c),'up') != grid[r][c]: #print('┐ corner - right+up') fences+=1 if get_value_in_direction(grid,(r,c),'right') == grid[r][c] and get_value_in_direction(grid,(r,c),'up') == grid[r][c] and get_value_in_direction(grid,(r,c),'up-right') != grid[r][c]: #print('└ corner - right+up+upright') fences+=1 #┌ ┐ #└ ┘ #input() result+=(area*fences) # for v in total_plots: # total_corners = 0 # corners = 0 # for x,y in v: # print('Checking',(x,y)) # keep = True # for dx, dy in directions: # neighbor = (x + dx, y + dy) # Instead of finding all the neighbors, check if # if neighbor in v: # keep = False # #corners += 1 # else: # corners += 1 # #if corners < 2: # # total_corners += 1 # print(corners) #input() #if corners == 3: # total_corners += 2 #print(v,total_corners) #result += (total_corners*len(v)) return result start_time = time.time() print('Part 2:',part2(), '\t\t', round((time.time() - start_time)*1000), 'ms')