Toll Calculator (Polymorphism)

Problem

Write an abstract class Vehicle with an abstract method toll(distance). A Car pays 2 per km. A Truck pays a flat 50 plus 5 per km. A Bike pays 1 per km but at least 10. Every input line is: kind distance (kind is car, truck or bike). Print the toll of each line. The main loop must not use a switch on the kind after the objects are created; it just calls toll() on the object.

Constraints

  • 1 <= lines <= 10^4
  • 0 <= distance <= 10^6

Examples

Input

car 10
truck 10
bike 3

Output

20
100
10

Solutions

Best approachTime O(n)Space O(n)

Polymorphism means that the same call (toll) does different things for different objects. The decision about the kind is made once, in the factory. When a new vehicle type arrives, we add a class and one line in the factory; the other code does not change.

Same code works in Java810172125Basic features only, so nothing changes between versions.
/*
 * Problem : Process lines.
 * Input   : Several lines.
 * Output  : One toll per line.
 * Approach: Abstract class with subclasses.
 * Time    : O(n)
 * Space   : O(n)
 * Java    : 8 or newer.
 */
import java.util.Scanner;

public class Main {
        // Step 1: The abstract class says that every vehicle can calculate a toll, but not how.
        static abstract class Vehicle {
            abstract long toll(long distance);
        }

        // Step 2: Every subclass gives its own rule for toll().
        static class Car extends Vehicle {
            @Override
            long toll(long distance) {
                return 2 * distance;
            }
        }

        static class Truck extends Vehicle {
            @Override
            long toll(long distance) {
                return 50 + 5 * distance;
            }
        }

        static class Bike extends Vehicle {
            @Override
            long toll(long distance) {
                return Math.max(10, distance);
            }
        }

        // Step 3: A factory method creates the right object once. After that the caller only uses the Vehicle type.
        static Vehicle create(String kind) {
            if (kind.equals("car")) {
                return new Car();
            }
            return kind.equals("truck") ? new Truck() : new Bike();
        }

    // This method solves the task. It receives the input and returns the answer.
    static String[] solve(String[] lines) {
        String[] output = new String[lines.length];
        for (int i = 0; i < lines.length; i++) {
            String[] part = lines[i].split(" ");
            Vehicle vehicle = create(part[0]);
            output[i] = String.valueOf(vehicle.toll(Long.parseLong(part[1])));
        }
        return output;
    }

    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. What is abstract about the method toll in Vehicle?