-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathu02.py
135 lines (112 loc) · 2.99 KB
/
u02.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
133
134
135
#!/usr/bin/env python
__motd__ = '--- Day 2: Bathroom Security ---'
__url__ = 'http://adventofcode.com/2016/day/2'
verbose = 0
class Keypad:
# sentinel char
snt = '-'
def __init__(self, layout, start_key='5'):
self.key = start_key
self.track = [start_key]
self.layout = layout
def locate(self, key):
for r,row in enumerate(self.layout):
if key in row:
return r, row.index(key)
def key_at(self, row, col):
return self.layout[row][col]
def next_key(self, dir):
row,col = self.locate(self.key)
if dir == 'U': return self.key_at(row-1, col)
if dir == 'D': return self.key_at(row+1, col)
if dir == 'L': return self.key_at(row, col-1)
if dir == 'R': return self.key_at(row, col+1)
# ignore unknown direction, so stay at current key
return self.key
def outside_limits(self, key):
" we are outside limits if we are at sentinel key "
return key == self.snt
def ignore(self):
" ignore movement outside keypad - we might sound an alarm here "
pass
def finger_move(self, dir):
# next key
key = self.next_key(dir)
# track
self.track.append(key)
# check limits
if self.outside_limits(key):
self.ignore()
return
# valid move
self.key = key
def finger_sequence(self, seq):
for m in seq:
self.finger_move(m)
return self.key
def pin(self, rows):
digit = []
for row in rows:
digit.append(self.finger_sequence(row))
return ''.join(digit)
def testcase(input, result, layout):
" testcase verifies if input returns result "
print "TestCase",
print "for input:",input,"\t expected result:",result,
keys = Keypad(layout=layout)
r = keys.pin(input)
print 'got:',r,'\t','OK' if r == result else 'ERR'
if verbose: print "Trace:",keys.track
print
# ========
# Task A
# ========
# use sentinel char around keypad
#
layoutA = [
'-----',
'-123-',
'-456-',
'-789-',
'-----'
]
# test cases
testcase(['ULL','RRDDD','LURDL','UUUUD'], '1985', layoutA)
data = __file__.replace('.py', '.input')
keys = Keypad(layout=layoutA)
with open(data) as f:
rows = []
for line in f:
if not line: continue
rows.append(line)
pin = keys.pin(rows)
# 18843
print 'Task A input file:',data,'Result:',pin
if verbose: print "Trace:",keys.track
print
# ========
# Task B
# ========
# use sentinel char around keypad
#
layoutB = [
'-------',
'---1---',
'--234--',
'-56789-',
'--ABC--',
'---D---',
'-------'
]
# test cases
testcase(['ULL','RRDDD','LURDL','UUUUD'], '5DB3', layoutB)
keys = Keypad(layout=layoutB)
with open(data) as f:
rows = []
for line in f:
if not line: continue
rows.append(line)
pin = keys.pin(rows)
# 67BB9
print 'Task B input file:',data,'Result:',pin
if verbose: print "Trace:",keys.track