Robot name
This commit is contained in:
@@ -0,0 +1,142 @@
|
||||
import { Robot } from "./robot-name";
|
||||
|
||||
const areSequential = (name1: string, name2: string): boolean => {
|
||||
const alpha1 = name1.substr(0, 2);
|
||||
const alpha2 = name2.substr(0, 2);
|
||||
const num1 = Number(name1.substr(2, 3));
|
||||
const num2 = Number(name2.substr(2, 3));
|
||||
|
||||
const numDiff = num2 - num1;
|
||||
const alphaDiff =
|
||||
(alpha2.charCodeAt(0) - alpha1.charCodeAt(0)) * 26 +
|
||||
(alpha2.charCodeAt(1) - alpha1.charCodeAt(1));
|
||||
|
||||
const totalDiff = alphaDiff * 1000 + numDiff;
|
||||
|
||||
return Math.abs(totalDiff) <= 1;
|
||||
};
|
||||
|
||||
const NAME_RE = /^[A-Z]{2}\d{3}$/;
|
||||
const TOTAL_NUMBER_OF_NAMES =
|
||||
26 * // A-Z
|
||||
26 * // A-Z
|
||||
10 * // 0-9
|
||||
10 * // 0-9
|
||||
10; // 0-9
|
||||
|
||||
describe("Robot", () => {
|
||||
let robot: Robot;
|
||||
|
||||
beforeEach(() => {
|
||||
robot = new Robot();
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
Robot.releaseNames();
|
||||
});
|
||||
|
||||
it("has a name", () => {
|
||||
expect(robot.name).toMatch(NAME_RE);
|
||||
});
|
||||
|
||||
it("name is the same each time", () => {
|
||||
expect(robot.name).toEqual(robot.name);
|
||||
});
|
||||
|
||||
it("different robots have different names", () => {
|
||||
const differentRobot = new Robot();
|
||||
expect(differentRobot.name).not.toEqual(robot.name);
|
||||
});
|
||||
|
||||
it("is able to reset the name", () => {
|
||||
const originalName = robot.name;
|
||||
|
||||
robot.resetName();
|
||||
const newName = robot.name;
|
||||
|
||||
expect(newName).toMatch(NAME_RE);
|
||||
expect(originalName).not.toEqual(newName);
|
||||
});
|
||||
|
||||
it("should set a unique name after reset", () => {
|
||||
const NUMBER_OF_ROBOTS = 10000;
|
||||
const usedNames = new Set();
|
||||
|
||||
usedNames.add(robot.name);
|
||||
for (let i = 0; i < NUMBER_OF_ROBOTS; i++) {
|
||||
robot.resetName();
|
||||
usedNames.add(robot.name);
|
||||
}
|
||||
|
||||
expect(usedNames.size).toEqual(NUMBER_OF_ROBOTS + 1);
|
||||
});
|
||||
|
||||
it("new names should not be sequential", () => {
|
||||
const name1 = robot.name;
|
||||
const name2 = new Robot().name;
|
||||
const name3 = new Robot().name;
|
||||
expect(areSequential(name1, name1)).toBe(true);
|
||||
expect(areSequential(name1, name2)).toBe(false);
|
||||
expect(areSequential(name2, name3)).toBe(false);
|
||||
});
|
||||
|
||||
it("names from reset should not be sequential", () => {
|
||||
const name1 = robot.name;
|
||||
robot.resetName();
|
||||
const name2 = robot.name;
|
||||
robot.resetName();
|
||||
const name3 = robot.name;
|
||||
expect(areSequential(name1, name2)).toBe(false);
|
||||
expect(areSequential(name2, name3)).toBe(false);
|
||||
expect(areSequential(name3, name3)).toBe(true);
|
||||
});
|
||||
|
||||
it("uses all letters", () => {
|
||||
let letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
||||
|
||||
for (let i = 0; i < 1000 - 1; i += 1) {
|
||||
const newRobot = new Robot();
|
||||
const lettersInName = newRobot.name.slice(0, 2);
|
||||
letters = letters.replace(lettersInName[0], "");
|
||||
letters = letters.replace(lettersInName[1], "");
|
||||
|
||||
if (letters.length === 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
expect(letters).toEqual("");
|
||||
});
|
||||
|
||||
it("uses all numbers", () => {
|
||||
let numbers = "0123456789";
|
||||
|
||||
for (let i = 0; i < 1000 - 1; i += 1) {
|
||||
const newRobot = new Robot();
|
||||
const digitsInName = newRobot.name.slice(2, 5);
|
||||
numbers = numbers.replace(digitsInName[0], "");
|
||||
numbers = numbers.replace(digitsInName[1], "");
|
||||
numbers = numbers.replace(digitsInName[2], "");
|
||||
|
||||
if (numbers.length === 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
expect(numbers).toEqual("");
|
||||
});
|
||||
|
||||
// This test is optional.
|
||||
//
|
||||
// This test doesn't run on our online test runner because it will time-out
|
||||
// with most implementations. It's up to you to test your solution locally.
|
||||
it.skip("all the names can be generated", () => {
|
||||
const usedNames = new Set();
|
||||
usedNames.add(robot.name);
|
||||
|
||||
for (let i = 0; i < TOTAL_NUMBER_OF_NAMES - 1; i += 1) {
|
||||
const newRobot = new Robot();
|
||||
usedNames.add(newRobot.name);
|
||||
}
|
||||
|
||||
expect(usedNames.size).toEqual(TOTAL_NUMBER_OF_NAMES);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user