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
|
from sys import stdin
import re
class Wrap:
def __init__(self, a, b):
# a - first element
# b - length
self.a = a
self.b = b
def constrain(self, n):
return self.a + (n - self.a) % self.b
def __repr__(self):
return f"|{self.a}+{self.b}"
@staticmethod
def from_a(a):
first = 0
while first < len(a) and a[first].isspace():
first += 1
l = 0
while first + l < len(a) and not a[first + l].isspace():
l += 1
return Wrap(first, l)
def rot(a):
target = max(map(len, a))
# pad
a = [list(r) + [' '] * (target - len(r)) for r in a]
return zip(*a)
data = stdin.readlines()
path = data[-1]
data = [list(line.strip('\n')) for line in data[:-2]]
rows = [Wrap.from_a(a) for a in data]
cols = [Wrap.from_a(a) for a in rot(data)]
def vis():
for line in data:
print(''.join(line))
def move(facing, dist, x, y):
fr = ">v<^"
dx, dy = [(1, 0), (0, 1), (-1, 0), (0, -1)][facing % 4]
if dx != 0:
for _ in range(dist):
data[y][x] = fr[facing]
nx = rows[y].constrain(x + dx)
if data[y][nx] == '#':
break
x = nx
elif dy != 0:
for _ in range(dist):
data[y][x] = fr[facing]
ny = cols[x].constrain(y + dy)
if data[ny][x] == '#':
break
y = ny
return x, y
def partOne():
x = rows[0].a
y = 0
facing = 0
for c in re.findall("\d+|[A-Z]", path):
if c == 'L': facing = (facing - 1) % 4
elif c == 'R': facing = (facing + 1) % 4
else:
x, y = move(facing, int(c), x, y)
return (y+1) * 1000 + (x+1) * 4 + facing
print(partOne())
|