Stopwatch with Laps
Problem
A stopwatch has two states: stopped and running. Every command has a time T (in seconds, never going back). start T: if it is stopped, begin and print started, otherwise print already running. lap T (only when running): print lap K: D, where K counts the laps since the start (1, 2, ...) and D is the time since the start or the previous lap. stop T (only when running): print stopped: total=X, where X is T minus the start time. A lap or a stop while stopped prints not running.
Constraints
- 1 <= commands <= 100
- T is non-decreasing
Examples
Input
start 0 lap 15 lap 40 stop 50
Output
started lap 1: 15 lap 2: 25 stopped: total=50
Solutions
The class has a state (running or not) and each command is allowed or not in that state. Putting the state and the rules in one class means the main loop is only a translator from text to method calls.
/*
* Problem : Run the stopwatch.
* Input : Command lines.
* Output : Answer lines.
* Approach: State machine class
* Time : O(n)
* Space : O(1)
* Java : 8 or newer.
*/
import java.util.Scanner;
public class Main {
// Step 1: The Stopwatch is a small state machine. Its state: running or not, the start time, the last lap time and the lap count.
static class Stopwatch {
private boolean running;
private int startTime;
private int lastMark;
private int laps;
String start(int time) {
if (running) {
return "already running";
}
running = true;
startTime = time;
lastMark = time;
laps = 0;
return "started";
}
// Step 2: Lap and stop work only in the running state.
String lap(int time) {
if (!running) {
return "not running";
}
laps++;
String text = "lap " + laps + ": " + (time - lastMark);
lastMark = time;
return text;
}
String stop(int time) {
if (!running) {
return "not running";
}
running = false;
return "stopped: total=" + (time - startTime);
}
}
// This method solves the task. It receives the input and returns the answer.
static String[] solve(String[] lines) {
Stopwatch watch = new Stopwatch();
String[] out = new String[lines.length];
for (int i = 0; i < lines.length; i++) {
String[] part = lines[i].split(" ");
int time = Integer.parseInt(part[1]);
if (part[0].equals("start")) {
out[i] = watch.start(time);
} else if (part[0].equals("lap")) {
out[i] = watch.lap(time);
} else {
out[i] = watch.stop(time);
}
}
return out;
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
java.util.List<String> all = new java.util.ArrayList<>();
while (scanner.hasNextLine()) {
String line = scanner.nextLine().trim();
if (!line.isEmpty()) {
all.add(line);
}
}
String[] lines = all.toArray(new String[0]);
System.out.println(String.join("\n", solve(lines)));
}
}
Hints (1)
- Which commands need the running state?