diff --git a/exercises/split-second-stopwatch/canonical-data.json b/exercises/split-second-stopwatch/canonical-data.json new file mode 100644 index 000000000..aa9cef89f --- /dev/null +++ b/exercises/split-second-stopwatch/canonical-data.json @@ -0,0 +1,818 @@ +{ + "exercise": "split-second-stopwatch", + "comments": [ + "All times are formatted in '::' format.", + "Hours, minutes, and seconds are formatted using two digits.", + "Thus 4 hours, 23 minutes, and 6 seconds is represented as '04:23:06'.", + "Tracks are free to convert these times into a format that is the most", + "appropriate for their language.", + "", + "The advanceTime command is used to simulate the passage of time.", + "Some tracks might be able to mock the system time, others might need", + "to provide some time-representing value, while others might need to", + "pass the current time as an argument to the other commands." + ], + "cases": [ + { + "uuid": "ddb238ea-99d4-4eaa-a81d-3c917a525a23", + "description": "new stopwatch starts in ready state", + "property": "time", + "input": { + "commands": [ + { + "command": "new" + }, + { + "command": "state", + "expected": "ready" + } + ] + }, + "expected": {} + }, + { + "uuid": "b19635d4-08ad-4ac3-b87f-aca10e844071", + "description": "new stopwatch's current lap has no elapsed time", + "property": "time", + "input": { + "commands": [ + { + "command": "new" + }, + { + "command": "currentLap", + "expected": "00:00:00" + } + ] + }, + "expected": {} + }, + { + "uuid": "492eb532-268d-43ea-8a19-2a032067d335", + "description": "new stopwatch's total has no elapsed time", + "property": "time", + "input": { + "commands": [ + { + "command": "new" + }, + { + "command": "total", + "expected": "00:00:00" + } + ] + }, + "expected": {} + }, + { + "uuid": "8a892c1e-9ef7-4690-894e-e155a1fe4484", + "description": "new stopwatch does not have previous laps", + "property": "time", + "input": { + "commands": [ + { + "command": "new" + }, + { + "command": "previousLaps", + "expected": [] + } + ] + }, + "expected": {} + }, + { + "uuid": "5b2705b6-a584-4042-ba3a-4ab8d0ab0281", + "description": "start from ready state changes state to running", + "property": "time", + "input": { + "commands": [ + { + "command": "new" + }, + { + "command": "start" + }, + { + "command": "state", + "expected": "running" + } + ] + }, + "expected": {} + }, + { + "uuid": "748235ce-1109-440b-9898-0a431ea179b6", + "description": "start does not change previous laps", + "property": "time", + "input": { + "commands": [ + { + "command": "new" + }, + { + "command": "start" + }, + { + "command": "previousLaps", + "expected": [] + } + ] + }, + "expected": {} + }, + { + "uuid": "491487b1-593d-423e-a075-aa78d449ff1f", + "description": "start initiates time tracking for current lap", + "property": "time", + "input": { + "commands": [ + { + "command": "new" + }, + { + "command": "start" + }, + { + "command": "advanceTime", + "by": "00:00:05" + }, + { + "command": "currentLap", + "expected": "00:00:05" + } + ] + }, + "expected": {} + }, + { + "uuid": "a0a7ba2c-8db6-412c-b1b6-cb890e9b72ed", + "description": "start initiates time tracking for total", + "property": "time", + "input": { + "commands": [ + { + "command": "new" + }, + { + "command": "start" + }, + { + "command": "advanceTime", + "by": "00:00:23" + }, + { + "command": "total", + "expected": "00:00:23" + } + ] + }, + "expected": {} + }, + { + "uuid": "7f558a17-ef6d-4a5b-803a-f313af7c41d3", + "description": "start cannot be called from running state", + "property": "time", + "input": { + "commands": [ + { + "command": "new" + }, + { + "command": "start" + }, + { + "command": "start", + "expected": { + "error": "cannot start an already running stopwatch" + } + } + ] + }, + "expected": {} + }, + { + "uuid": "32466eef-b2be-4d60-a927-e24fce52dab9", + "description": "stop from running state changes state to stopped", + "property": "time", + "input": { + "commands": [ + { + "command": "new" + }, + { + "command": "start" + }, + { + "command": "stop" + }, + { + "command": "state", + "expected": "stopped" + } + ] + }, + "expected": {} + }, + { + "uuid": "621eac4c-8f43-4d99-919c-4cad776d93df", + "description": "stop pauses time tracking for current lap", + "property": "time", + "input": { + "commands": [ + { + "command": "new" + }, + { + "command": "start" + }, + { + "command": "advanceTime", + "by": "00:00:05" + }, + { + "command": "stop" + }, + { + "command": "advanceTime", + "by": "00:00:08" + }, + { + "command": "currentLap", + "expected": "00:00:05" + } + ] + }, + "expected": {} + }, + { + "uuid": "465bcc82-7643-41f2-97ff-5e817cef8db4", + "description": "stop pauses time tracking for total", + "property": "time", + "input": { + "commands": [ + { + "command": "new" + }, + { + "command": "start" + }, + { + "command": "advanceTime", + "by": "00:00:13" + }, + { + "command": "stop" + }, + { + "command": "advanceTime", + "by": "00:00:44" + }, + { + "command": "total", + "expected": "00:00:13" + } + ] + }, + "expected": {} + }, + { + "uuid": "b1ba7454-d627-41ee-a078-891b2ed266fc", + "description": "stop cannot be called from ready state", + "property": "time", + "input": { + "commands": [ + { + "command": "new" + }, + { + "command": "stop", + "expected": { + "error": "cannot stop a stopwatch that is not running" + } + } + ] + }, + "expected": {} + }, + { + "uuid": "5c041078-0898-44dc-9d5b-8ebb5352626c", + "description": "stop cannot be called from stopped state", + "property": "time", + "input": { + "commands": [ + { + "command": "new" + }, + { + "command": "start" + }, + { + "command": "stop" + }, + { + "command": "stop", + "expected": { + "error": "cannot stop a stopwatch that is not running" + } + } + ] + }, + "expected": {} + }, + { + "uuid": "3f32171d-8fbf-46b6-bc2b-0810e1ec53b7", + "description": "start from stopped state changes state to running", + "property": "time", + "input": { + "commands": [ + { + "command": "new" + }, + { + "command": "start" + }, + { + "command": "stop" + }, + { + "command": "start" + }, + { + "command": "state", + "expected": "running" + } + ] + }, + "expected": {} + }, + { + "uuid": "626997cb-78d5-4fe8-b501-29fdef804799", + "description": "start from stopped state resumes time tracking for current lap", + "property": "time", + "input": { + "commands": [ + { + "command": "new" + }, + { + "command": "start" + }, + { + "command": "advanceTime", + "by": "00:01:20" + }, + { + "command": "stop" + }, + { + "command": "advanceTime", + "by": "00:00:20" + }, + { + "command": "start" + }, + { + "command": "advanceTime", + "by": "00:00:08" + }, + { + "command": "currentLap", + "expected": "00:01:28" + } + ] + }, + "expected": {} + }, + { + "uuid": "58487c53-ab26-471c-a171-807ef6363319", + "description": "start from stopped state resumes time tracking for total", + "property": "time", + "input": { + "commands": [ + { + "command": "new" + }, + { + "command": "start" + }, + { + "command": "advanceTime", + "by": "00:00:23" + }, + { + "command": "stop" + }, + { + "command": "advanceTime", + "by": "00:00:44" + }, + { + "command": "start" + }, + { + "command": "advanceTime", + "by": "00:00:09" + }, + { + "command": "total", + "expected": "00:00:32" + } + ] + }, + "expected": {} + }, + { + "uuid": "091966e3-ed25-4397-908b-8bb0330118f8", + "description": "lap adds current lap to previous laps", + "property": "time", + "input": { + "commands": [ + { + "command": "new" + }, + { + "command": "start" + }, + { + "command": "advanceTime", + "by": "00:01:38" + }, + { + "command": "lap" + }, + { + "command": "previousLaps", + "expected": ["00:01:38"] + }, + { + "command": "advanceTime", + "by": "00:00:44" + }, + { + "command": "lap" + }, + { + "command": "previousLaps", + "expected": ["00:01:38", "00:00:44"] + } + ] + }, + "expected": {} + }, + { + "uuid": "1aa4c5ee-a7d5-4d59-9679-419deef3c88f", + "description": "lap resets current lap and resumes time tracking", + "property": "time", + "input": { + "commands": [ + { + "command": "new" + }, + { + "command": "start" + }, + { + "command": "advanceTime", + "by": "00:08:22" + }, + { + "command": "lap" + }, + { + "command": "currentLap", + "expected": "00:00:00" + }, + { + "command": "advanceTime", + "by": "00:00:15" + }, + { + "command": "currentLap", + "expected": "00:00:15" + } + ] + }, + "expected": {} + }, + { + "uuid": "4b46b92e-1b3f-46f6-97d2-0082caf56e80", + "description": "lap continues time tracking for total", + "property": "time", + "input": { + "commands": [ + { + "command": "new" + }, + { + "command": "start" + }, + { + "command": "advanceTime", + "by": "00:00:22" + }, + { + "command": "lap" + }, + { + "command": "advanceTime", + "by": "00:00:33" + }, + { + "command": "total", + "expected": "00:00:55" + } + ] + }, + "expected": {} + }, + { + "uuid": "ea75d36e-63eb-4f34-97ce-8c70e620bdba", + "description": "lap cannot be called from ready state", + "property": "time", + "input": { + "commands": [ + { + "command": "new" + }, + { + "command": "lap", + "expected": { + "error": "cannot lap a stopwatch that is not running" + } + } + ] + }, + "expected": {} + }, + { + "uuid": "63731154-a23a-412d-a13f-c562f208eb1e", + "description": "lap cannot be called from stopped state", + "property": "time", + "input": { + "commands": [ + { + "command": "new" + }, + { + "command": "start" + }, + { + "command": "stop" + }, + { + "command": "lap", + "expected": { + "error": "cannot lap a stopwatch that is not running" + } + } + ] + }, + "expected": {} + }, + { + "uuid": "e585ee15-3b3f-4785-976b-dd96e7cc978b", + "description": "stop does not change previous laps", + "property": "time", + "input": { + "commands": [ + { + "command": "new" + }, + { + "command": "start" + }, + { + "command": "advanceTime", + "by": "00:11:22" + }, + { + "command": "lap" + }, + { + "command": "previousLaps", + "expected": ["00:11:22"] + }, + { + "command": "stop" + }, + { + "command": "previousLaps", + "expected": ["00:11:22"] + } + ] + }, + "expected": {} + }, + { + "uuid": "fc3645e2-86cf-4d11-97c6-489f031103f6", + "description": "reset from stopped state changes state to ready", + "property": "time", + "input": { + "commands": [ + { + "command": "new" + }, + { + "command": "start" + }, + { + "command": "stop" + }, + { + "command": "reset" + }, + { + "command": "state", + "expected": "ready" + } + ] + }, + "expected": {} + }, + { + "uuid": "20fbfbf7-68ad-4310-975a-f5f132886c4e", + "description": "reset resets current lap", + "property": "time", + "input": { + "commands": [ + { + "command": "new" + }, + { + "command": "start" + }, + { + "command": "advanceTime", + "by": "00:00:10" + }, + { + "command": "stop" + }, + { + "command": "reset" + }, + { + "command": "currentLap", + "expected": "00:00:00" + } + ] + }, + "expected": {} + }, + { + "uuid": "00a8f7bb-dd5c-43e5-8705-3ef124007662", + "description": "reset clears previous laps", + "property": "time", + "input": { + "commands": [ + { + "command": "new" + }, + { + "command": "start" + }, + { + "command": "advanceTime", + "by": "00:00:10" + }, + { + "command": "lap" + }, + { + "command": "advanceTime", + "by": "00:00:20" + }, + { + "command": "lap" + }, + { + "command": "previousLaps", + "expected": ["00:00:10", "00:00:20"] + }, + { + "command": "stop" + }, + { + "command": "reset" + }, + { + "command": "previousLaps", + "expected": [] + } + ] + }, + "expected": {} + }, + { + "uuid": "76cea936-6214-4e95-b6d1-4d4edcf90499", + "description": "reset cannot be called from ready state", + "property": "time", + "input": { + "commands": [ + { + "command": "new" + }, + { + "command": "reset", + "expected": { + "error": "cannot reset a stopwatch that is not stopped" + } + } + ] + }, + "expected": {} + }, + { + "uuid": "ba4d8e69-f200-4721-b59e-90d8cf615153", + "description": "reset cannot be called from running state", + "property": "time", + "input": { + "commands": [ + { + "command": "new" + }, + { + "command": "start" + }, + { + "command": "reset", + "expected": { + "error": "cannot reset a stopwatch that is not stopped" + } + } + ] + }, + "expected": {} + }, + { + "uuid": "0b01751a-cb57-493f-bb86-409de6e84306", + "description": "supports very long laps", + "property": "time", + "input": { + "commands": [ + { + "command": "new" + }, + { + "command": "start" + }, + { + "command": "advanceTime", + "by": "01:23:45" + }, + { + "command": "currentLap", + "expected": "01:23:45" + }, + { + "command": "lap" + }, + { + "command": "previousLaps", + "expected": ["01:23:45"] + }, + { + "command": "advanceTime", + "by": "04:01:40" + }, + { + "command": "currentLap", + "expected": "04:01:40" + }, + { + "command": "total", + "expected": "05:25:25" + }, + { + "command": "lap" + }, + { + "command": "previousLaps", + "expected": ["01:23:45", "04:01:40"] + }, + { + "command": "advanceTime", + "by": "08:43:05" + }, + { + "command": "currentLap", + "expected": "08:43:05" + }, + { + "command": "total", + "expected": "14:08:30" + }, + { + "command": "lap" + }, + { + "command": "previousLaps", + "expected": ["01:23:45", "04:01:40", "08:43:05"] + } + ] + }, + "expected": {} + } + ] +} diff --git a/exercises/split-second-stopwatch/instructions.md b/exercises/split-second-stopwatch/instructions.md new file mode 100644 index 000000000..30bdc988d --- /dev/null +++ b/exercises/split-second-stopwatch/instructions.md @@ -0,0 +1,22 @@ +# Instructions + +Your task is to build a stopwatch to keep precise track of lap times. + +The stopwatch uses four commands (start, stop, lap, and reset) to keep track of: + +1. The current lap's tracked time +2. Previously recorded lap times + +What commands can be used depends on which state the stopwatch is in: + +1. Ready: initial state +2. Running: tracking time +3. Stopped: not tracking time + +| Command | Begin state | End state | Effect | +| ------- | ----------- | --------- | -------------------------------------------------------- | +| Start | Ready | Running | Start tracking time | +| Start | Stopped | Running | Resume tracking time | +| Stop | Running | Stopped | Stop tracking time | +| Lap | Running | Running | Add current lap to previous laps, then reset current lap | +| Reset | Stopped | Ready | Reset current lap and clear previous laps | diff --git a/exercises/split-second-stopwatch/introduction.md b/exercises/split-second-stopwatch/introduction.md new file mode 100644 index 000000000..a84322477 --- /dev/null +++ b/exercises/split-second-stopwatch/introduction.md @@ -0,0 +1,6 @@ +# Introduction + +You've always run for the thrill of it — no schedules, no timers, just the sound of your feet on the pavement. +But now that you've joined a competitive running crew, things are getting serious. +Training sessions are timed to the second, and every split second counts. +To keep pace, you've picked up the _Split-Second Stopwatch_ — a sleek, high-tech gadget that's about to become your new best friend. diff --git a/exercises/split-second-stopwatch/metadata.toml b/exercises/split-second-stopwatch/metadata.toml new file mode 100644 index 000000000..1116f03ee --- /dev/null +++ b/exercises/split-second-stopwatch/metadata.toml @@ -0,0 +1,4 @@ +title = "Split-Second Stopwatch" +blurb = "Keep track of time through a digital stopwatch." +source = "Erik Schierboom" +source_url = "https://github.com/exercism/problem-specifications/pull/2547"