Code for the Advent of Code event
aoc
advent-of-code
1#!/usr/bin/env ruby
2# frozen_string_literal: true
3
4class Keypad
5 MOVEMENT = {
6 u: -> { [0, -1] },
7 d: -> { [0, 1] },
8 l: -> { [-1, 0] },
9 r: -> { [1, 0] }
10 }.freeze
11
12 attr_reader :x, :y
13
14 def initialize(layout)
15 @layout = layout
16
17 @y = @layout.index { |row| row.include? 5 }
18 @x = @layout[@y].index 5
19 end
20
21 def x=(val)
22 @x = val if val >= 0 && val < @layout[@y].size
23 end
24
25 def y=(val)
26 return unless val >= 0 && val < @layout.size
27 new_x = translate_x val
28 return unless new_x >= 0 && new_x < @layout[val].size
29 @y = val
30 @x = new_x
31 end
32
33 def move(direction)
34 dx, dy = MOVEMENT[direction].call
35
36 # X and Y never change at the same time
37 self.x += dx
38 self.y += dy
39 end
40
41 def current
42 @layout[@y][@x]
43 end
44
45 private
46
47 def translate_x(y)
48 return @x if @layout[@y].size == @layout[y].size
49 @x - ((@layout[@y].size - @layout[y].size) / 2)
50 end
51end
52
53input = $stdin.readlines.map { |l| l.strip.chars.map { |d| d.downcase.to_sym } }
54
55pad = Keypad.new [
56 [1, 2, 3],
57 [4, 5, 6],
58 [7, 8, 9]
59]
60
61code = []
62
63input.each do |row|
64 row.map { |dir| pad.move dir }
65 code << pad.current
66end
67
68puts "(1) #{code.map { |d| d.to_s(16) }.join}"
69
70# rubocop:disable Layout/FirstArrayElementIndentation, Layout/ArrayAlignment
71pad = Keypad.new [
72 [0x1],
73 [0x2, 0x3, 0x4],
74 [0x5, 0x6, 0x7, 0x8, 0x9],
75 [0xA, 0xB, 0xC],
76 [0xD]
77]
78# rubocop:enable Layout/FirstArrayElementIndentation, Layout/ArrayAlignment
79
80code = []
81
82input.each do |row|
83 row.map { |dir| pad.move dir }
84 code << pad.current
85end
86
87puts "(2) #{code.map { |d| d.to_s(16).upcase }.join}"