#!/bin/python3 import sys,re, math from copy import deepcopy import numpy as np from pprint import pprint sys.path.insert(0, '../../') from fred import list2int, toGrid, nprint,get_re input_f = 'input' part = 1 ######################################### # # # Part 1+2 # # # ######################################### instructions = {} grid = [ ['.','#','.'], ['.','.','#'], ['#','#','#'] ] def toSet(input,regex): set = {} with open(input) as file: for line in file: r = get_re(regex, line.rstrip()) set[r.group(1).replace('/','')] = r.group(2).replace('/','') return set def need2split(grid): if len(grid) > 3: return True else: return False def grid2line(grid): line = '' for i in grid: line += ''.join(i) return line def line2grid(line): grid = [] size = int(math.sqrt(len(line))) for i in range(size): grid.append(list(line[i*size:size*(1+i)])) return grid def rotate90(grid): rotatedGrid = np.array(deepcopy(grid)) return np.rot90(rotatedGrid) def splitGrid(grid): #print('Splitting') #nprint(grid) size = len(grid) block_size = 0 if size % 2 == 0: block_size = 2 else: block_size = 3 #print('Size:',size,' Block_size:',block_size) #else: # print('Grind is wrong at splitGrid()') blocks = [] for i in range(0, size, block_size): for j in range(0, size, block_size): block = [row[j:j+block_size] for row in grid[i:i+block_size]] #print(block) for bdx,b in enumerate(block): block[bdx] = list(b) #print(block) #input() blocks.append(block) return blocks def get_all_transformations(grid): grid = np.array(grid) transformations = set() for k in range(4): rotated = np.rot90(grid, k) # Add original rotation if tuple(map(tuple, rotated)) not in transformations: transformations.add(tuple(map(tuple, rotated))) yield rotated # Add horizontal flip of rotation h_flip = np.flipud(rotated) if tuple(map(tuple, h_flip)) not in transformations: transformations.add(tuple(map(tuple, h_flip))) yield h_flip # Add vertical flip of rotation v_flip = np.fliplr(rotated) if tuple(map(tuple, v_flip)) not in transformations: transformations.add(tuple(map(tuple, v_flip))) yield v_flip def findInst(grid,instructions): found = False new_grid = [] grid = grid while not found: for transformed_grid in get_all_transformations(grid): #print(grid2line(transformed_grid)) #input() try: new_grid = instructions[grid2line(transformed_grid)] found = True break except: continue return new_grid def transform_grid(input_grid): # Determine the dimensions of the grid num_subgrids = len(input_grid) subgrid_rows = len(input_grid[0]) # Rows in each subgrid subgrid_cols = len(input_grid[0][0]) # Columns in each subgrid # Calculate the number of subgrids per row and column subgrids_per_row = int(num_subgrids ** 0.5) # Initialize the result result = [] # Process each row of subgrids for subgrid_row_idx in range(subgrids_per_row): # Merge corresponding rows from subgrids in the current "row of subgrids" for row_idx in range(subgrid_rows): row = ''.join( ''.join(input_grid[subgrid_row_idx * subgrids_per_row + col_idx][row_idx]) for col_idx in range(subgrids_per_row) ) result.append(row) return result rr = 0 if part == 1: rr = 5 if part == 2: rr = 18 instructions = toSet(input_f,r"^(.*) => (.*)$") #print(instructions) blocks = [] mixed_grid = [[]] for i in range(0,rr): size = len(grid) print('i:',i) #nprint(grid) #print() if size % 3 == 0 or size % 2 == 0: if not need2split(grid): new_grid = findInst(grid,instructions) grid = line2grid(new_grid) #print(grid) else: blocks = splitGrid(grid) #print(blocks) #pprint(blocks) #print(len(blocks)) #print(blocks) #print(blocks) #input() mixed_grid = [] for i in range(0,len(blocks)): #print(findInst(blocks[i],instructions)) x = line2grid(findInst(blocks[i],instructions)) #print(x) #input() mixed_grid.append(x) #print(mixed_grid) grid = transform_grid(mixed_grid) #nprint(grid) #input() else: print('Something is wrong with the grid size of ', size) #input() count = 0 for i in grid: count += i.count('#') print(count)