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

Best approachTime O(n)Space O(1)

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.

Same code works in Java810172125Basic features only, so nothing changes between versions.
/*
 * 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)
  1. Which commands need the running state?