Problem:
Write a program that manages 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, 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
should not allow the use of the same name twice when avoidable. In
some exercism language tracks there are tests to ensure that the same
name is never used twice.
Code:
import java.util.Random;
import java.util.Set;
import java.util.HashSet;
public class Robot {
private static final String ALPHABETS = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
private static final Set<String> generatedNames = new HashSet<>();
private String name;
public String getName() {
while (name == null) {
name = generateName();
if (generatedNames.contains(name)) name = null;
}
generatedNames.add(name);
return name;
}
public void reset() {
name = null;
}
private String generateName() {
StringBuilder builder = new StringBuilder();
int i;
for (i = 0; i < 2; i++) {
builder.append(ALPHABETS.charAt(generateRandomInRange(0, 25)));
}
for (i = 0; i < 3; i++) {
builder.append(generateRandomInRange(0, 9));
}
return builder.toString();
}
private int generateRandomInRange(int min, int max) {
return new Random().nextInt((max - min) + 1) + min;
}
}
Test Suite:
import org.junit.Test;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.core.Is.is;
import static org.hamcrest.core.IsNot.not;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertEquals;
public class RobotTest {
private static final String EXPECTED_ROBOT_NAME_PATTERN = "[A-Z]{2}\\d{3}";
private final Robot robot = new Robot();
@Test
public void hasName() {
assertIsValidName(robot.getName());
}
@Test
public void differentRobotsHaveDifferentNames() {
assertThat(robot.getName(), not(equalTo(new Robot().getName())));
}
@Test
public void resetName() {
final String name = robot.getName();
robot.reset();
final String name2 = robot.getName();
assertThat(name, not(equalTo(name2)));
assertIsValidName(name2);
}
private static void assertIsValidName(String name) {
assertThat(name.matches(EXPECTED_ROBOT_NAME_PATTERN), is(true));
}
}
Reference: Exercism