Skip to content

Instantly share code, notes, and snippets.

@pixeltrix
Created May 15, 2019 12:47
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save pixeltrix/db76b50e083b83bb6b2a3f381ad0f5e0 to your computer and use it in GitHub Desktop.
Save pixeltrix/db76b50e083b83bb6b2a3f381ad0f5e0 to your computer and use it in GitHub Desktop.
Ruby implementation of the common code exercise
require "matrix"
require "readline"
class ToyRobot
PROMPT = "> "
PLACE = /\APLACE\s+(\d+),(\d+),(NORTH|SOUTH|EAST|WEST)\z/
COMMAND = /\ALEFT|RIGHT|MOVE|REPORT\z/
QUIT = /\AQUIT\z/
LEFT = Matrix[[0, 1], [-1, 0]]
RIGHT = Matrix[[0, -1], [ 1, 0]]
FACING = {
"NORTH" => Matrix[[ 0, 1]], "SOUTH" => Matrix[[ 0, -1]],
"EAST" => Matrix[[ 1, 0]], "WEST" => Matrix[[-1, 0]]
}
class << self
def run
new.run
end
end
def initialize(width: 5, height: 5)
@width, @height = height, width
@position = @direction = nil
end
def run
begin
while (input = Readline.readline(PROMPT, true))
command(input)
end
rescue Interrupt
exit
end
end
private
def placed?
@position && @direction
end
def valid?(position = @position + @direction)
position[0, 0].between?(0, @width) && position[0, 1].between?(0, @height)
end
def place(position, direction)
if valid?(position)
@position, @direction = position, direction
end
end
def left
@direction *= LEFT
end
def right
@direction *= RIGHT
end
def move
@position += @direction if valid?
end
def report
puts "= #{@position[0, 0]},#{@position[0, 1]},#{FACING.key(@direction)}"
end
def command(input)
case input
when COMMAND
send input.downcase.to_sym if placed?
when PLACE
place Matrix[[$1.to_i, $2.to_i]], FACING[$3]
when QUIT
quit
end
end
def quit
exit
end
end
ToyRobot.run
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment