-
Notifications
You must be signed in to change notification settings - Fork 0
/
day13.py
88 lines (73 loc) · 1.82 KB
/
day13.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
import functools
SAMPLE_INPUT = [
"6,10",
"0,14",
"9,10",
"0,3",
"10,4",
"4,11",
"6,0",
"6,12",
"4,1",
"0,13",
"10,12",
"3,4",
"3,0",
"8,4",
"1,10",
"2,14",
"8,10",
"9,0",
"",
"fold along y=7",
"fold along x=5",
]
def foldX(foldX, x, y):
return (foldX - abs(x - foldX), y)
def foldY(foldY, x, y):
return (x, foldY - abs(y - foldY))
def parse(lines):
it = iter(lines)
points = set()
for line in it:
if not line or line.isspace():
break
x, y = line.split(",", maxsplit=2)
points.add((int(x), int(y)))
folds = []
for line in it:
if line.startswith("fold along x="):
folds.append(functools.partial(foldX, int(line[13:].rstrip())))
elif line.startswith("fold along y="):
folds.append(functools.partial(foldY, int(line[13:].rstrip())))
else:
raise ValueError(f"bad input: {line}")
return points, folds
def part1(lines):
"""
>>> part1(SAMPLE_INPUT)
17
"""
points, folds = parse(lines)
fold, *_ = folds
points = set(fold(x, y) for x, y in points)
return len(points)
def part2(lines):
"""
>>> part2(SAMPLE_INPUT)
'▓▓▓▓▓\\n▓░░░▓\\n▓░░░▓\\n▓░░░▓\\n▓▓▓▓▓'
"""
points, folds = parse(lines)
def fold(point, fold):
x, y = point
return fold(x, y)
points = set(functools.reduce(fold, folds, point) for point in points)
x0 = min(x for x, _ in points)
y0 = min(y for _, y in points)
x1 = max(x for x, _ in points)
y1 = max(y for _, y in points)
return "\n".join(
"".join("\u2593" if (x, y) in points else "\u2591" for x in range(x0, x1 + 1))
for y in range(y0, y1 + 1)
)
parts = (part1, part2)