# Advent of Code 2016, Day 2: Bathroom Security

## Part A

On Day 2 we need to get access to the bathroom protected by a locked door with a keypad.

Our keypad is just 9-digit simple thing:

``````1 2 3
4 5 6
7 8 9
``````

We also have an input with instructions on which buttons to press:

``````ULL
RRDDD
LURDL
UUUUD
``````

Each line represents one digit to press. We start on digit 5 and then we follow the instructions. So for first line we have ULL, which means up, left and left. So we go from 5 to 2 then 1 and again left, but we have no way to go more, so we stay at 1.

For next lines we start at the last position and continue the same procedure.

Here is my solution:

``````data = File.readlines("2.txt").map(&:strip).map { |line| line.split("") }

buttons = {
[0, 0] => 1,
[1, 0] => 2,
[2, 0] => 3,
[0, 1] => 4,
[1, 1] => 5,
[2, 1] => 6,
[0, 2] => 7,
[1, 2] => 8,
[2, 2] => 9
}
position = [1, 1]

def valid?(position)
(0..2).include?(position[0]) && (0..2).include?(position[1])
end

buttons = data.map do |row|
row.each do |move|
case move
when "U"
new_position = [position[0], position[1] - 1]
when "D"
new_position = [position[0], position[1] + 1]
when "L"
new_position = [position[0] - 1, position[1]]
when "R"
new_position = [position[0] + 1, position[1]]
end

if valid?(new_position)
position = new_position
end
end

buttons[position]
end

puts buttons.join
``````

We have `buttons` hash mapping positions on the keypad to button values, we have `valid?` method checking if our position is within the keypad and we have starting position set to [1, 1] which is the button 5.

Then we just iterate through our input, we follow the instructions updating our position and checking if it is valid. After processing each line we store button value in the array. And finally we print it out.

## Part B

In second part we have more advanced keypad that looks like this:

``````    1
2 3 4
5 6 7 8 9
A B C
D
``````

We still start at button 5 and apply the same logic. We can use the previous code with just updated keypad mapping like this:

``````@buttons = {
[0, -2] => 1,
[-1, -1] => 2,
[0, -1] => 3,
[1, -1] => 4,
[-2, 0] => 5,
[-1, 0] => 6,
[0, 0] => 7,
[1, 0] => 8,
[2, 0] => 9,
[-1, 1] => "A",
[0, 1] => "B",
[1, 1] => "C",
[0, 2] => "D"
}
``````

And `valid?` method can just check if position is in the hash. If not, it is invalid position:

``````def valid?(position)
@buttons.key?(position)
end
``````

Here is the full solution:

``````data = File.readlines("2.txt").map(&:strip).map { |line| line.split("") }

@buttons = {
[0, -2] => 1,
[-1, -1] => 2,
[0, -1] => 3,
[1, -1] => 4,
[-2, 0] => 5,
[-1, 0] => 6,
[0, 0] => 7,
[1, 0] => 8,
[2, 0] => 9,
[-1, 1] => "A",
[0, 1] => "B",
[1, 1] => "C",
[0, 2] => "D"
}
position = [-2, 0]

def valid?(position)
@buttons.key?(position)
end

results = data.map do |row|
row.each do |move|
case move
when "U"
new_position = [position[0], position[1] - 1]
when "D"
new_position = [position[0], position[1] + 1]
when "L"
new_position = [position[0] - 1, position[1]]
when "R"
new_position = [position[0] + 1, position[1]]
end

if valid?(new_position)
position = new_position
end
end

@buttons[position]
end

puts results.join
``````