Created
October 21, 2024 09:26
-
-
Save Niall47/c275d6b46d321195a08f01463d603976 to your computer and use it in GitHub Desktop.
Robots.rb
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# frozen_string_literal: true | |
# Robot name | |
# 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. | |
module Name | |
LETTERS = ('A'..'Z').to_a | |
NUMBERS = (0..9).to_a | |
def generate | |
2.times.map { LETTERS.sample }.join + 3.times.map { NUMBERS.sample.to_s }.join | |
end | |
end | |
class RobotManager | |
include Name | |
attr_reader :robots | |
def initialize | |
@robots = [] | |
end | |
def boot_all | |
@robots.each(&:boot) | |
end | |
def reset_all | |
@robots.each(&:reset) | |
end | |
def create_robots(number) | |
number.times do | |
@robots << Robot.new { generate_name } | |
end | |
@robots | |
end | |
def create_robot | |
@robots << Robot.new { generate_name } | |
@robots.last | |
end | |
def generate_name | |
excluded_names = @robots.map do |robot| | |
robot.name(just_checking: true) | |
end | |
loop do | |
name = generate | |
return name unless excluded_names.include?(name) | |
end | |
end | |
end | |
class Robot | |
attr_accessor :status, :has_been_booted | |
DEFAULT_NAME = 'Unnamed' | |
def initialize(&block) | |
@status = :off | |
@has_been_booted = false | |
@name_generator = block | |
@name = DEFAULT_NAME | |
end | |
def name(just_checking: false) | |
if !@has_been_booted | |
@name | |
elsif @has_been_booted && @name == DEFAULT_NAME && !just_checking | |
# if this is true then we need a new name | |
@name = @name_generator.call | |
else | |
@name | |
end | |
end | |
def boot | |
@has_been_booted = true | |
@status = :on | |
end | |
def shutdown | |
@status = :off | |
end | |
def reset | |
@name = DEFAULT_NAME | |
@has_been_booted = false | |
@status = :off | |
end | |
end | |
# Create 10 robots which should have default names and status: off | |
puts 'Creating 10 robots...' | |
manager = RobotManager.new | |
manager.create_robots(10) | |
# Select the first robot | |
bot1 = manager.robots.first | |
puts "Robot 1 name is: #{bot1.name} and status: #{bot1.status}" | |
# We boot it up for the first time | |
puts 'Booting up robot 1...' | |
bot1.boot | |
# We ask the robot name again | |
puts "Robot 1 name is: #{bot1.name} and status: #{bot1.status}" | |
# Now lets boot all the robots and see who has names | |
puts 'Booting all robots...' | |
manager.boot_all | |
manager.robots.each_with_index do |robot, index| | |
puts "#{index + 1}. Robot name is: #{robot.name} and status: #{robot.status}" | |
end | |
# Now lets reset all the robots and see who has names | |
puts 'Resetting all robots...' | |
manager.reset_all | |
manager.robots.each_with_index do |robot, index| | |
puts "#{index + 1}. Robot name is: #{robot.name} and status: #{robot.status}" | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment