-
Notifications
You must be signed in to change notification settings - Fork 0
/
d16a.py
133 lines (113 loc) · 3.12 KB
/
d16a.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
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
#!/usr/bin/env python3
import pytest
import fileinput
from os.path import splitext, abspath
import re
F_NAME = re.match(r'.+/d\d+', splitext(abspath(__file__))[0])[0]
def printenergized(energized, h, w):
print('\033[2J\033[H')
for y in range(h):
for x in range(w):
if (x,y) in energized:
tile = '#'
else:
tile = '.'
print(tile, end='')
print()
print()
def answer(lines):
## cave [y][x]
cave = list(map(str.strip, lines))
def printcave():
print()
for line in cave:
print(line)
print()
energized = set()
energizeddir = set()
def movebeam(pos, dire, initial=False):
## pos (x,y)
if (pos, dire) in energizeddir:
return
energized.add(pos)
x, y = pos
if initial:
pass
else:
energizeddir.add((pos, dire))
if dire == 'r':
x += 1
elif dire == 'l':
x -= 1
elif dire == 'u':
y -= 1
elif dire == 'd':
y += 1
else:
1/0
if x < 0 or y < 0:
return
try:
tile = cave[y][x]
except IndexError:
return
if tile == '.':
pass
elif tile == '/':
if dire == 'r':
dire = 'u'
elif dire == 'l':
dire = 'd'
elif dire == 'u':
dire = 'r'
elif dire == 'd':
dire = 'l'
elif tile == '\\':
if dire == 'r':
dire = 'd'
elif dire == 'l':
dire = 'u'
elif dire == 'u':
dire = 'l'
elif dire == 'd':
dire = 'r'
elif tile == '|':
if dire == 'r':
dire = 'd'
movebeam((x,y), 'u')
elif dire == 'l':
dire = 'd'
movebeam((x,y), 'u')
elif tile == '-':
if dire == 'u':
dire = 'l'
movebeam((x,y), 'r')
elif dire == 'd':
dire = 'l'
movebeam((x,y), 'r')
if len(energized) % 1000 == 0:
printenergized(energized, len(cave), len(cave[0]))
movebeam((x,y), dire)
printcave()
pos = (0,0)
movebeam(pos, 'r', initial=True)
printenergized(energized, len(cave), len(cave[0]))
return len(energized)
@pytest.mark.parametrize('testfileno, expected', [
(1, 46),
])
def test_answer_testfiles(testfileno, expected):
print()
assert answer(fileinput.input(f"{F_NAME}.test.{testfileno}")) == expected
if __name__ == '__main__':
import sys
print(sys.getrecursionlimit())
sys.setrecursionlimit(10000)
import timeit
start = timeit.default_timer()
filename = fileinput.input(F_NAME + '.input')
ans = answer(filename)
assert ans != 18
print('Answer:', ans)
duration = timeit.default_timer()-start
print(f'Execution time: {duration:.3f} s')