Robot Name

Manage robot factory settings.

When a robot comes off the factory floor, it has no name.

The first time you turn on a robot, 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 its name gets wiped. The next time you ask, that robot will respond with a new random name.

The names must be random: they should not follow a predictable sequence. Using random names means a risk of collisions. Your solution must ensure that every existing robot has a unique name.

The test suite only generates ~100 names by default. There are ~700k valid names, so it will only give a small chance of collisions. Consider testing your solution for collisions in some other way in addition to the test suite.

This exercise continues our exploration of Julia's type system, this time with mutable types, and introduces us to random number generation.

We will imagine that resetting the robot to the factory settings is like a surgery: it makes changes to the subject, but doesn't replace it. We could also have modeled the problem such that resetting a robot creates a new robot, but not every problem can be modeled solely with immutable data structures (even purely functional languages deal with mutability inside their runtimes!).

In Julia, functions that mutate their arguments have a suffix ! by convention. So our method for doing this will be called reset!.

This is only a convention, but almost all published Julia code follows it and you might come to agree that it's quite helpful!

Hints

You will need to define a method for generating unique names, a structure to describe robots, a method for resetting a robot, and a method for getting the name of a robot.

You might find it helpful to design your program first to just emit a random name for a robot (without worrying about collisions) and then later to think about and design a scheme that will avoid ever issuing duplicate names. In your design, be thoughtful about how the run time of name generation changes as names run out. What guarantees do you want to offer the caller?

Source

A debugging session with Paul Blackwell at gSchool. http://gschool.it

Version compatibility

This exercise has been tested on Julia versions >=1.0.

Submitting Incomplete Solutions

It's possible to submit an incomplete solution so you can see how others have completed the exercise.

Your solution


In [ ]:
# submit
mutable struct Robot

end

function reset!(instance::Robot)

end

function name(instance::Robot)

end

Test suite


In [ ]:
using Test

import Random

# include("robot-name.jl")

# Random names means a risk of collisions.
const history = Set{String}()

isname(x) = occursin(r"^[A-Z]{2}[0-9]{3}$", x)

@testset "one robot" begin
    global r1 = Robot()
    push!(history, name(r1))

    @testset "name of robot is valid" begin
        @test isname(name(r1))
    end

    @testset "names of robot instance are valid and unique in history" begin
        # @testset sets the same seed every time for reproducibility, but we're
        # undoing that deliberately with Random.seed!() to increase the chance
        # of seeing collisions.
        Random.seed!()
        for i in 1:100
            reset!(r1)
            @test isname(name(r1))
            @test !in(name(r1), history)
            push!(history, name(r1))
        end
    end
end

@testset "two robots" begin
    global r2 = Robot()
    global r3 = Robot()

    @testset "names of robots are valid" begin
        @test isname(name(r2))
        @test isname(name(r3))
    end
    
    @testset "names of robots are not equal" begin
        @test name(r2) != name(r3)
    end

    @testset "names of both robots are unique in history" begin
        @test !in(name(r2), history)
        @test !in(name(r3), history)
    end

    push!(history, name(r2))
    push!(history, name(r3))
end

@testset "many robots" begin
    Random.seed!()
    robots = Robot[]

    for i in 1:100
        push!(robots, Robot())

        @testset "name of robot is valid and unique in history" begin
            @test isname(name(robots[i]))
            @test !in(name(robots[i]), history)
        end

        push!(history, name(robots[i]))
    end

    @testset "fresh names of reset robots are valid and unique in history" begin
        Random.seed!()
        for r in robots
            reset!(r)
            @test isname(name(r))
            @test !in(name(r), history)
            push!(history, name(r))
        end
    end
end

Prepare submission

To submit your exercise, you need to save your solution in a file called robot-name.jl before using the CLI. You can either create it manually or use the following functions, which will automatically write every notebook cell that starts with # submit to the file robot-name.jl.


In [ ]:
# using Pkg; Pkg.add("Exercism")
# using Exercism
# Exercism.create_submission("robot-name")