Robot Name
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.
That was the instructions given to me. The only constraints is the tests. From my previous post I'm trying to improve on my naming conventions, DRY code, access modifiers, and keeping it readable. Any advice would help me a lot since I'm learning C# and teaching myself. Thank you for your help especially to those that follow my progress and help me.
using System;
using System.Collections.Generic;
using System.Linq;
public class Robot
{
private static Random _random;
private string _name;
private static readonly HashSet<string> _nameList = new HashSet<string>();
public string Name => _name;
public Robot()
{
_random = new Random();
_name = GenerateRandomName();
}
public void Reset()
{
_nameList.Remove(_name);
_name = GenerateRandomName();
}
private static string GenerateRandomLetters() => new string(Enumerable.Repeat("ABCDEFGHIJKLMNOPQRSTUVWXYZ", 2)
.Select(s => s[_random.Next(s.Length)]).ToArray());
private static string GenerateRandomName()
{
string name;
do
{
name = $"{GenerateRandomLetters()}{_random.Next(10)}{_random.Next(10)}{_random.Next(10)}";
}
while (_nameList.Contains(name));
_nameList.Add(name);
return name;
}
}
using System.Collections.Generic;
using Xunit;
public class RobotNameTests
{
private readonly Robot robot = new Robot();
[Fact]
public void Robot_has_a_name() => Assert.Matches(@"^[A-Z]{2}\d{3}$", robot.Name);
[Fact]
public void Name_is_the_same_each_time() => Assert.Equal(robot.Name, robot.Name);
[Fact]
public void Different_robots_have_different_names() => Assert.NotEqual(new Robot().Name, robot.Name);
[Fact]
public void Can_reset_the_name()
{
var originalName = robot.Name;
robot.Reset();
Assert.NotEqual(originalName, robot.Name);
}
[Fact]
public void After_reset_the_name_is_valid()
{
robot.Reset();
Assert.Matches(@"^[A-Z]{2}\d{3}$", robot.Name);
}
[Fact]
public void Robot_names_are_unique()
{
var names = new HashSet<string>();
for (int i = 0; i < 10_000; i++) {
var robot = new Robot();
Assert.True(names.Add(robot.Name));
}
}
}
The test are immutable. They cannot be altered at all. I did not write these test. I have to work within the test. I would be interested in learning on how to improve on them out of curiosity at best.
_nameList
, call it what would call it in real life:_names
(or rather_possibleNames
). Case in point: your_nameList
isn't even aList
, it's aHashset
, and thus the name does not correspond with its actual type. \$\endgroup\$