Manage robot factory settings.
When robots come off the factory floor, they have no name.
The first time you boot them up, a random name is generated in the format of two uppercase letters followed by three digits, such as RX837 or BC811.
Every once in a while we need to reset a robot to its factory settings, which means that their name gets wiped. The next time you ask, it will respond with a new random name.
The names must be random: they should not follow a predictable sequence. Random names means a risk of collisions. Your solution must ensure that every existing robot has a unique name.
In order to make this easier to test, your solution will need to implement a
Robot.forget
method that clears any shared state that might exist to track
duplicate robot names.
Bonus points if this method does not need to do anything for your solution.
For installation and learning resources, refer to the exercism help page.
For running the tests provided, you will need the Minitest gem. Open a terminal window and run the following command to install minitest:
gem install minitest
If you would like color output, you can require 'minitest/pride'
in
the test file, or note the alternative instruction, below, for running
the test file.
Run the tests from the exercise directory using the following command:
ruby robot_name_test.rb
To include color from the command line:
ruby -r minitest/pride robot_name_test.rb
A debugging session with Paul Blackwell at gSchool. http://gschool.it
It's possible to submit an incomplete solution so you can see how others have completed the exercise.
require 'minitest/autorun'
require_relative 'robot_name'
class RobotTest < Minitest::Test
NAME_REGEXP = /^[A-Z]{2}\d{3}$/
def setup
Robot.forget
end
def test_can_create_a_robot
skip
refute_nil Robot.new
end
def test_has_name
skip
assert_match NAME_REGEXP, Robot.new.name
end
def test_name_sticks
skip
robot = Robot.new
original_name = robot.name
assert_equal original_name, robot.name
end
def test_reset_changes_name
skip
robot = Robot.new
original_name = robot.name
robot.reset
refute_equal original_name, robot.name
end
def test_reset_before_name_called_does_not_cause_an_error
skip
robot = Robot.new
robot.reset
assert_match NAME_REGEXP, Robot.new.name
end
def test_reset_multiple_times
skip
robot = Robot.new
names = []
5.times do
robot.reset
names << robot.name
end
# This will probably be 5, but name uniqueness is only a requirement
# accross multiple robots and consecutive calls to reset.
assert names.uniq.size > 1
end
def test_different_robots_have_different_names
skip
refute_equal Robot.new.name, Robot.new.name
end
# This test assumes you're using Kernel.rand as a source of randomness
def test_different_name_when_chosen_name_is_taken
skip
same_seed = 1234
Kernel.srand same_seed
robot_1 = Robot.new
name_1 = robot_1.name
Kernel.srand same_seed
robot_2 = Robot.new
name_2 = robot_2.name
refute_equal name_1, name_2
end
def test_generate_all_robots
skip
all_names_count = 26 * 26 * 1000
time_limit = Time.now + 60 # seconds
seen_names = Hash.new(0)
robots = []
while seen_names.size < all_names_count && Time.now < time_limit
robot = Robot.new
seen_names[robot.name] += 1
robots << robot
end
timeout_message = "Timed out trying to generate all possible robots"
assert_equal all_names_count, robots.size, timeout_message
assert seen_names.values.all? { |count| count == 1 }, "Some names used more than once"
assert seen_names.keys.all? { |name| name.match(NAME_REGEXP) }, "Not all names match #{NAME_REGEXP}"
end
def test_version
assert_equal 3, BookKeeping::VERSION
end
end
class Robot
def self.used_names
@used_names ||= []
end
attr_reader :name
def initialize
generate_name
end
def reset
generate_name
end
private
def generate_name
loop do
@name = Array.new(2) { [*"A".."Z"].sample }.join + rand(100..999).to_s
break unless Robot.used_names.include?(@name)
end
Robot.used_names << @name
end
end
module BookKeeping
VERSION = 2
end
A huge amount can be learned from reading other people’s code. This is why we wanted to give exercism users the option of making their solutions public.
Here are some questions to help you reflect on this solution and learn the most from it.
Level up your programming skills with 3,450 exercises across 52 languages, and insightful discussion with our volunteer team of welcoming mentors. Exercism is 100% free forever.
Sign up Learn More
Community comments