``````

In [1]:

#!/usr/bin/env python
from collections import deque

# Keypad is oriented 90 degrees to the left so 2d tuple follows basic X,Y coordinate order
# Find and start at "5" on the keypad always
for x, y, v in [(x, y, v)
for y, v in enumerate(row)]:
if str(v) == '5':
break
self.coords = [x,y]
# Movements dictionary to lookup the change in position on the keypad
self.movements = dict(R=(-1, 0), U=(0, -1), L=(1, 0), D=(0, 1))

def follow_directions(self, commands):
try:
for command in commands:
movement = self.movements[command]
self.x += movement[0]
self.y += movement[1]
except KeyError:
raise ValueError('Commanded to move in %r direction' % command)
return self.key

@property
def y(self):
return self.coords[1]

@y.setter
def y(self, value):
try:
if value >=0 and self.keypad[self.coords[0]][value] is not None:
self.coords[1] = value
except IndexError:
pass

@property
def x(self):
return self.coords[0]

@x.setter
def x(self, value):
try:
if value >=0 and self.keypad[value][self.coords[1]] is not None:
self.coords[0] = value
except IndexError:
pass

@property
def key(self):

def __str__(self):
return 'Keypad at (%i,%i), key %i' % (
self.x, self.y, self.key)

``````
``````

``````
``````

In [2]:

# Example, 1985 for puzzle 1, 5DB3 for puzzle 2
input_str = """ULL
RRDDD
LURDL
UUUUD"""

``````
``````

In [3]:

#input_str = """DUURRDRRURUUUDLRUDDLLLURULRRLDULDRDUULULLUUUDRDUDDURRULDRDDDUDDURLDLLDDRRURRUUUDDRUDDLLDDDURLRDDDULRDUDDRDRLRDUULDLDRDLUDDDLRDRLDLUUUDLRDLRUUUDDLUURRLLLUUUUDDLDRRDRDRLDRLUUDUDLDRUDDUDLLUUURUUDLULRDRULURURDLDLLDLLDUDLDRDULLDUDDURRDDLLRLLLLDLDRLDDUULRDRURUDRRRDDDUULRULDDLRLLLLRLLLLRLURRRLRLRDLULRRLDRULDRRLRURDDLDDRLRDLDRLULLRRUDUURRULLLRLRLRRUDLRDDLLRRUDUDUURRRDRDLDRUDLDRDLUUULDLRLLDRULRULLRLRDRRLRLULLRURUULRLLRRRDRLULUDDUUULDULDUDDDUDLRLLRDRDLUDLRLRRDDDURUUUDULDLDDLDRDDDLURLDRLDURUDRURDDDDDDULLDLDLU
#LURLRUURDDLDDDLDDLULRLUUUDRDUUDDUDLDLDDLLUDURDRDRULULLRLDDUDRRDRUDLRLDDDURDUURLUURRLLDRURDRLDURUDLRLLDDLLRDRRLURLRRUULLLDRLULURULRRDLLLDLDLRDRRURUUUDUDRUULDLUDLURLRDRRLDRUDRUDURLDLDDRUULDURDUURLLUDRUUUUUURRLRULUDRDUDRLLDUDUDUULURUURURULLUUURDRLDDRLUURDLRULDRRRRLRULRDLURRUULURDRRLDLRUURUDRRRDRURRLDDURLUDLDRRLDRLLLLRDUDLULUDRLLLDULUDUULLULLRLURURURDRRDRUURDULRDDLRULLLLLLDLLURLRLLRDLLRLUDLRUDDRLLLDDUDRLDLRLDUDU
#RRDDLDLRRUULRDLLURLRURDLUURLLLUUDDULLDRURDUDRLRDRDDUUUULDLUDDLRDULDDRDDDDDLRRDDDRUULDLUDUDRRLUUDDRUDLUUDUDLUDURDURDLLLLDUUUUURUUURDURUUUUDDURULLDDLDLDLULUDRULULULLLDRLRRLLDLURULRDLULRLDRRLDDLULDDRDDRURLDLUULULRDRDRDRRLLLURLLDUUUDRRUUURDLLLRUUDDDULRDRRUUDDUUUDLRRURUDDLUDDDUDLRUDRRDLLLURRRURDRLLULDUULLURRULDLURRUURURRLRDULRLULUDUULRRULLLDDDDURLRRRDUDULLRRDURUURUUULUDLDULLUURDRDRRDURDLUDLULRULRLLURULDRUURRRRDUDULLLLLRRLRUDDUDLLURLRDDLLDLLLDDUDDDDRDURRL
#LLRURUDUULRURRUDURRDLUUUDDDDURUUDLLDLRULRUUDUURRLRRUDLLUDLDURURRDDLLRUDDUDLDUUDDLUUULUUURRURDDLUDDLULRRRUURLDLURDULULRULRLDUDLLLLDLLLLRLDLRLDLUULLDDLDRRRURDDRRDURUURLRLRDUDLLURRLDUULDRURDRRURDDDDUUUDDRDLLDDUDURDLUUDRLRDUDLLDDDDDRRDRDUULDDLLDLRUDULLRRLLDUDRRLRURRRRLRDUDDRRDDUUUDLULLRRRDDRUUUDUUURUULUDURUDLDRDRLDLRLLRLRDRDRULRURLDDULRURLRLDUURLDDLUDRLRUDDURLUDLLULDLDDULDUDDDUDRLRDRUUURDUULLDULUUULLLDLRULDULUDLRRURDLULUDUDLDDRDRUUULDLRURLRUURDLULUDLULLRD
#UURUDRRDDLRRRLULLDDDRRLDUDLRRULUUDULLDUDURRDLDRRRDLRDUUUDRDRRLLDULRLUDUUULRULULRUDURDRDDLDRULULULLDURULDRUDDDURLLDUDUUUULRUULURDDDUUUURDLDUUURUDDLDRDLLUDDDDULRDLRUDRLRUDDURDLDRLLLLRLULRDDUDLLDRURDDUDRRLRRDLDDUDRRLDLUURLRLLRRRDRLRLLLLLLURULUURRDDRRLRLRUURDLULRUUDRRRLRLRULLLLUDRULLRDDRDDLDLDRRRURLURDDURRLUDDULRRDULRURRRURLUURDDDUDLDUURRRLUDUULULURLRDDRULDLRLLUULRLLRLUUURUUDUURULRRRUULUULRULDDURLDRRULLRDURRDDDLLUDLDRRRRUULDDD"""

``````
``````

In [4]:

# Solution for problem 1
(2,5,8),
(1,4,7)))
# Read in the input directions, appending to password to be joined later
for command in input_str.splitlines():
location = str(k.follow_directions(command))
#print location

``````
``````

1985

``````
``````

In [5]:

# Solution for problem 2, different kind of keypad
(None, 4,    8,  'C',  None),
(1,    3,    7,  'B',  'D'),
(None, 2,    6,  'A',  None),
(None, None, 5,  None, None)))
# Read in the input directions, appending to password to be joined later
for command in input_str.splitlines():

``````
``````

5DB3

``````