|
| 1 | +parts = [{ |
| 2 | + keypad: [ |
| 3 | + [1, 2, 3], |
| 4 | + [4, 5, 6], |
| 5 | + [7, 8, 9], |
| 6 | + ].map(&:freeze).freeze, |
| 7 | + admit: ->(row, col) { [row, col].all? { |c| 0 <= c && c <= 2 } } |
| 8 | +}, { |
| 9 | + keypad: [ |
| 10 | + [nil, nil, 1, nil, nil], |
| 11 | + [nil, 2, 3, 4, nil], |
| 12 | + [ 5, 6, 7, 8, 9], |
| 13 | + [nil, :A, :B, :C, nil], |
| 14 | + [nil, nil, :D, nil, nil], |
| 15 | + ].map(&:freeze).freeze, |
| 16 | + admit: ->(row, col) { (col - 2).abs + (row - 2).abs <= 2 } |
| 17 | +}].map(&:freeze).freeze |
| 18 | + |
| 19 | +START_AT = 5 |
| 20 | + |
| 21 | +input = ARGF.readlines.map(&:freeze).freeze |
| 22 | + |
| 23 | +puts parts.map { |part| |
| 24 | + keypad = part[:keypad].map(&:freeze).freeze |
| 25 | + admit = part[:admit] |
| 26 | + |
| 27 | + row = keypad.index { |x| x.include?(START_AT) } |
| 28 | + pos = [row, keypad[row].index(START_AT)] |
| 29 | + |
| 30 | + try = ->(coord:, dir:) { |
| 31 | + pos[coord] += dir |
| 32 | + pos[coord] -= dir unless admit[*pos] |
| 33 | + } |
| 34 | + |
| 35 | + input.map { |l| |
| 36 | + l.chomp.each_char { |c| |
| 37 | + case c |
| 38 | + when ?L; try[coord: 1, dir: -1] |
| 39 | + when ?R; try[coord: 1, dir: 1] |
| 40 | + when ?U; try[coord: 0, dir: -1] |
| 41 | + when ?D; try[coord: 0, dir: 1] |
| 42 | + else raise "bad char #{c}" |
| 43 | + end |
| 44 | + } |
| 45 | + keypad[pos[0]][pos[1]] |
| 46 | + }.join |
| 47 | +} |
0 commit comments