-
Notifications
You must be signed in to change notification settings - Fork 256
/
Copy pathrobot_simulator.rb
121 lines (100 loc) · 2.55 KB
/
robot_simulator.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
# Problem: https://exercism.org/tracks/ruby/exercises/robot-simulator
# Solution
class Robot
attr_accessor :bearing
DIRECTIONS = [:north,:east,:south,:west]
def orient(direction)
raise ArgumentError unless %i[east west north south].include?(direction)
@bearing = direction
end
def turn_right
@bearing = DIRECTIONS[(DIRECTIONS.index(@bearing)+1)%4]
end
def turn_left
@bearing = DIRECTIONS[(DIRECTIONS.index(@bearing)-1)%4]
end
def at(x,y)
@x = x
@y = y
end
def coordinates
[@x,@y]
end
def advance
case @bearing
when :north
@y+=1
when :south
@y-=1
when :east
@x+=1
when :west
@x-=1
else
raise ArgumentError
end
end
end
class Simulator
def instructions(instruction_str)
commands = []
instruction_str.chars.each do |instruction|
case instruction
when "R"
commands.push(:turn_right)
when "L"
commands.push(:turn_left)
when "A"
commands.push(:advance)
else
raise ArgumentError
end
end
commands
end
def place(robot,**kwargs)
robot.at(kwargs[:x],kwargs[:y])
robot.orient(kwargs[:direction])
end
def evaluate(robot,instruction_str)
commands = instructions(instruction_str)
commands.each do |command|
robot.send(command)
end
end
end
# Solution 2
class Robot
INCREMENTS = {north: [0,1], east: [1,0], south: [0,-1], west: [-1,0]}
VALID_BEARINGS = INCREMENTS.keys
attr_reader :bearing, :coordinates
def orient(direction)
raise ArgumentError unless VALID_BEARINGS.include? direction
@bearing = direction
end
def turn_right
@bearing = VALID_BEARINGS[VALID_BEARINGS.index(@bearing) + 1] || :north
end
def turn_left
@bearing = VALID_BEARINGS[VALID_BEARINGS.index(@bearing) - 1]
end
def at(*coordinates)
@coordinates = coordinates
end
def advance
@coordinates = @coordinates.zip(INCREMENTS[@bearing]).map { |a, b| a + b }
end
end
class Simulator
COMMANDS = { 'L' => :turn_left, 'R' => :turn_right, 'A' => :advance }
def instructions(command_str)
command_str.chars.map { |cmd| COMMANDS[cmd] }
end
def place(robot, x: 0, y: 0, direction: :north)
robot.at(x, y)
robot.orient(direction)
end
def evaluate(robot, command_str)
instructions(command_str).each { |cmd| robot.send(cmd) }
end
end