From 0549ff028e4b976ee539d03f5fca5358ca682a38 Mon Sep 17 00:00:00 2001 From: FrederikBaerentsen Date: Thu, 28 Nov 2024 18:47:06 +0100 Subject: [PATCH] Working on 2017/21 part 1 --- 2017/21/21.md | 116 +++++++++++++++++++++++++ 2017/21/solution.py | 145 +++++++++++++++++++++++++++++++ __pycache__/fred.cpython-311.pyc | Bin 3496 -> 4828 bytes fred.py | 20 ++++- 4 files changed, 280 insertions(+), 1 deletion(-) create mode 100644 2017/21/21.md create mode 100644 2017/21/solution.py diff --git a/2017/21/21.md b/2017/21/21.md new file mode 100644 index 0000000..bd15a1c --- /dev/null +++ b/2017/21/21.md @@ -0,0 +1,116 @@ +## \-\-- Day 21: Fractal Art \-\-- + +You find a program trying to generate some art. It uses a strange +process that involves [repeatedly +enhancing]{title="This technique is also often used on TV."} the detail +of an image through a set of rules. + +The image consists of a two-dimensional square grid of pixels that are +either on (`#`) or off (`.`). The program always begins with this +pattern: + + .#. + ..# + ### + +Because the pattern is both `3` pixels wide and `3` pixels tall, it is +said to have a *size* of `3`. + +Then, the program repeats the following process: + +- If the size is evenly divisible by `2`, break the pixels up into + `2x2` squares, and convert each `2x2` square into a `3x3` square by + following the corresponding *enhancement rule*. +- Otherwise, the size is evenly divisible by `3`; break the pixels up + into `3x3` squares, and convert each `3x3` square into a `4x4` + square by following the corresponding *enhancement rule*. + +Because each square of pixels is replaced by a larger one, the image +gains pixels and so its *size* increases. + +The artist\'s book of enhancement rules is nearby (your puzzle input); +however, it seems to be missing rules. The artist explains that +sometimes, one must *rotate* or *flip* the input pattern to find a +match. (Never rotate or flip the output pattern, though.) Each pattern +is written concisely: rows are listed as single units, ordered top-down, +and separated by slashes. For example, the following rules correspond to +the adjacent patterns: + + ../.# = .. + .# + + .#. + .#./..#/### = ..# + ### + + #..# + #..#/..../#..#/.##. = .... + #..# + .##. + +When searching for a rule to use, rotate and flip the pattern as +necessary. For example, all of the following patterns match the same +rule: + + .#. .#. #.. ### + ..# #.. #.# ..# + ### ### ##. .#. + +Suppose the book contained the following two rules: + + ../.# => ##./#../... + .#./..#/### => #..#/..../..../#..# + +As before, the program begins with this pattern: + + .#. + ..# + ### + +The size of the grid (`3`) is not divisible by `2`, but it is divisible +by `3`. It divides evenly into a single square; the square matches the +second rule, which produces: + + #..# + .... + .... + #..# + +The size of this enhanced grid (`4`) is evenly divisible by `2`, so that +rule is used. It divides evenly into four squares: + + #.|.# + ..|.. + --+-- + ..|.. + #.|.# + +Each of these squares matches the same rule (`../.# => ##./#../...`), +three of which require some flipping and rotation to line up with the +rule. The output for the rule is the same in all four cases: + + ##.|##. + #..|#.. + ...|... + ---+--- + ##.|##. + #..|#.. + ...|... + +Finally, the squares are joined into a new grid: + + ##.##. + #..#.. + ...... + ##.##. + #..#.. + ...... + +Thus, after `2` iterations, the grid contains `12` pixels that are *on*. + +*How many pixels stay on* after `5` iterations? + +To begin, [get your puzzle input](21/input). + +Answer: + diff --git a/2017/21/solution.py b/2017/21/solution.py new file mode 100644 index 0000000..d743db3 --- /dev/null +++ b/2017/21/solution.py @@ -0,0 +1,145 @@ +#!/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 = 'test' + +part = 1 +######################################### +# # +# Part 1 # +# # +######################################### + +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): + size = len(grid) + block_size = 0 + if size % 2 == 0: + block_size = 2 + elif size % 3 == 0: + block_size = 3 + 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 findInst(grid,instructions): + found = False + new_grid = [] + grid = grid + while not found: + try: + new_grid = instructions[grid2line(grid)] + found = True + except: + grid = rotate90(grid) + return new_grid + +def transform_grid(input_grid): + result = [] + + for half in [input_grid[:2], input_grid[2:]]: + for i in range(3): # Each subgrid has 3 rows + # Merge the rows from the two subgrids in the current half + row = ''.join([''.join(subgrid[i]) for subgrid in half]) + result.append(row) + + return result + +if part == 1: + instructions = toSet(input_f,r"^(.*) => (.*)$") + + print(instructions) + blocks = [] + mixed_grid = [[]] + for i in range(0,5): + size = len(grid) + 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) + #print(len(blocks)) + #print(blocks) + print(blocks) + input() + mixed_grid = [] + + + for i in range(0,len(blocks)): + x = line2grid(findInst(blocks[i],instructions)) + + mixed_grid.append(x) + grid = transform_grid(mixed_grid) + #nprint(grid) + #input() + + else: + print('Something is wrong with the grid size of ', size) + #input() +######################################### +# # +# Part 2 # +# # +######################################### +if part == 2: + exit() diff --git a/__pycache__/fred.cpython-311.pyc b/__pycache__/fred.cpython-311.pyc index 55e6bb02d6aa7feda8d98c1fe52fe093f4eae229..1265de687d6437b1f7621fac27518b21c222f6ef 100644 GIT binary patch delta 1553 zcmb7E&2Jk;6rb6dwY~nT0}YtkBx#cfZ>*XmwOdiqqBN$hh#Dc<1GR}l=x(houD#4U zG(nE+LnIQ^gUv>*%ZEr2Y6(47;>MvpA|WM`4`xOF0B%MFDdNPN^;dv$U}pTAH*em& z_nY@-{cY%%QU86P&yApc{_*+DNq5yBES-kcZKNOtXHlv(;}lk0im-}Pfp62uw%zj2DfMYM%yWops9uI4Pqf)0~n zxw4v3nACCw%fXBS({x$1L@lQ;fpMwMJ0NC&f7_UKs%BbP-m6HvpuZf&ubl2Bc8C_4`OgE7rC2Gk= zFx*7gm$0Ei8-atjJ)e5MJimGAe){Y5-MMe(cEZQ%;bS|2cs&r`wnvlj1Ed5FY%eza z#{K=yp{IMAw70kSRP`S&(oSHk9vIuU2j>)R z5TMqK;A%k#u$cFZk(J7kw+mqHRybF1amxo^uU>M@_3w{ zi8~*kz<{Ph__4G_W-TORi$ICD1WQtLi`P}QP*5#VXHaZeWFGKm5lvaLux62Ke7@GL z>k#wvZAZ?wW+7PcavB+cGTQAsREt*!HwK%Chyfec#Wk`vwc9^X`=I*HhWRED$7INu zB(J}|HeJEH-oDC6#n_N*(;KnPx3;~J9dD%Wjer2dERlZk3Ajep)Vm_1T=?O|fX#t9 zVP!+V8Nx#X3!A6#(%=Ya4gR{|5w^Kz)WSSd*-M}dnspq*VUq|yO|w4k;2;28`Y@ND z=Md!Z0*6BY|GcKD6)v*F zCiWzb*yVYSU-`p@?4mla<>q@P)8J|3;oF|?a4F1V@r24Q#$S*{jAg_AH0`3cvddG( z_)Qrv; zEs!E94z=G+%W68!Dloe-HSR^uKcZH=gW(W`k|9J<1OZ0vb!4>$68bRl)E_UQb=9o> zT#Z>vlbC8IGZ8yFklFsOgpEpSUI2Q>9DLKyQgNVZs@b-Q+a-T8f3dF>g)N6c)L*H{ zFKGSl+`r(jYbc