Working on 2017/21 part 1
This commit is contained in:
parent
99982f4fb9
commit
0549ff028e
116
2017/21/21.md
Normal file
116
2017/21/21.md
Normal file
@ -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:
|
||||||
|
|
145
2017/21/solution.py
Normal file
145
2017/21/solution.py
Normal file
@ -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()
|
Binary file not shown.
20
fred.py
20
fred.py
@ -1,4 +1,22 @@
|
|||||||
import re
|
import re,sys
|
||||||
|
|
||||||
|
def toGrid(input,parser=None):
|
||||||
|
grid = []
|
||||||
|
if parser:
|
||||||
|
with open(input) as file:
|
||||||
|
for line in file:
|
||||||
|
grid.append(list2int(line.rstrip()))
|
||||||
|
else:
|
||||||
|
with open(input) as file:
|
||||||
|
for line in file:
|
||||||
|
grid.append(line.rstrip())
|
||||||
|
return grid
|
||||||
|
|
||||||
|
def nprint(grid):
|
||||||
|
for idx,i in enumerate(grid):
|
||||||
|
for jdx,j in enumerate(i):
|
||||||
|
print(grid[idx][jdx],end='')
|
||||||
|
print()
|
||||||
|
|
||||||
def list2int(x):
|
def list2int(x):
|
||||||
return list(map(int, x))
|
return list(map(int, x))
|
||||||
|
Loading…
Reference in New Issue
Block a user