Skip to content

Instantly share code, notes, and snippets.

@Niall47
Created October 21, 2024 09:26
Show Gist options
  • Save Niall47/c275d6b46d321195a08f01463d603976 to your computer and use it in GitHub Desktop.
Save Niall47/c275d6b46d321195a08f01463d603976 to your computer and use it in GitHub Desktop.
Robots.rb
# 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