You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
66 lines
1.7 KiB
66 lines
1.7 KiB
from PIL.ImageFilter import GaussianBlur
|
|
import aocd
|
|
|
|
import functools
|
|
|
|
try:
|
|
import pytesseract
|
|
ocr = True
|
|
|
|
from PIL import Image, ImageFilter
|
|
except ImportError:
|
|
ocr = False
|
|
|
|
def perform_fold(dots, fold):
|
|
def new_dot(dot, dir, coord):
|
|
x, y = dot
|
|
|
|
if dir == 'x':
|
|
return (abs(x - coord) * -1 + coord, y)
|
|
|
|
if dir == 'y':
|
|
return (x, abs(y - coord) * -1 + coord)
|
|
|
|
dir, coord = fold
|
|
return set(map(functools.partial(new_dot, dir=dir, coord=coord), dots))
|
|
|
|
|
|
def solve(data):
|
|
dots, folds = data
|
|
|
|
for fold in folds:
|
|
dots = perform_fold(dots, fold)
|
|
|
|
width = max((dot[0] for dot in dots)) + 1
|
|
height = max((dot[1] for dot in dots)) + 1
|
|
|
|
if ocr:
|
|
# copy the dots into an image
|
|
image = Image.new('L', (width + 2, height + 2), 'white')
|
|
|
|
for dot in dots:
|
|
image.putpixel((dot[0] + 1, dot[1] + 1), 0)
|
|
|
|
# thin out the strokes so tesseract can handle it
|
|
image = image.resize((d*25 for d in image.size))
|
|
image = image.point(lambda p: int(p * 1.5))
|
|
|
|
return pytesseract.image_to_string(image).strip()
|
|
else:
|
|
return '\n'.join((
|
|
''.join((
|
|
'##' if (x, y) in dots else ' ' for x in range(width)
|
|
)) for y in range(height)
|
|
))
|
|
|
|
if __name__ == '__main__':
|
|
dots, folds = aocd.get_data(year=2021, day=13).split('\n\n')
|
|
dots = set((tuple((int(i) for i in point.split(','))) for point in dots.split('\n')))
|
|
folds = [(fold.split("=")[0][-1], int(fold.split("=")[1])) for fold in folds.split('\n')]
|
|
|
|
solution = solve((dots, folds))
|
|
|
|
print(solution)
|
|
|
|
if ocr:
|
|
aocd.submit(solution, part='b', year=2021, day=13) |