Shape Areas with Polymorphism

Problem

Each input line describes a shape: rect W H, square S or tri B H (a triangle with base B and height H). Print the area of each shape on its own line. The area is always a multiple of 0.5, so print it with one decimal digit (for example 12.0 or 7.5). Use an abstract parent class and child classes.

Constraints

  • 1 <= lines <= 10^4
  • 1 <= sizes <= 10^5

Examples

Input

rect 3 4
tri 3 5

Output

12.0
7.5

Solutions

Best approachTime O(n)Space O(n)

The loop does not care which child it has. It calls doubledArea() and each class gives its own answer. Using twice the area avoids decimal rounding differences between languages.

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

public class Main {
        // Step 1: An abstract class is a common parent. It says every shape must give its area.
        static abstract class Shape {
            // Step 2: We return twice the area, so the answer stays an exact whole number.
            abstract long doubledArea();
        }

        static class Rect extends Shape {
            private final long width;
            private final long height;

            Rect(long width, long height) {
                this.width = width;
                this.height = height;
            }

            @Override
            long doubledArea() {
                return 2 * width * height;
            }
        }

        static class Square extends Shape {
            private final long side;

            Square(long side) {
                this.side = side;
            }

            @Override
            long doubledArea() {
                return 2 * side * side;
            }
        }

        static class Triangle extends Shape {
            private final long base;
            private final long height;

            Triangle(long base, long height) {
                this.base = base;
                this.height = height;
            }

            @Override
            long doubledArea() {
                return base * height;
            }
        }

    // 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[] parts = lines[i].split(" ");

            // Step 3: Make the right child object. We store it in a variable of the parent type.
            Shape shape;
            if (parts[0].equals("rect")) {
                shape = new Rect(Long.parseLong(parts[1]), Long.parseLong(parts[2]));
            } else if (parts[0].equals("square")) {
                shape = new Square(Long.parseLong(parts[1]));
            } else {
                shape = new Triangle(Long.parseLong(parts[1]), Long.parseLong(parts[2]));
            }

            // Step 4: The same call works for every child. This is polymorphism.
            long doubled = shape.doubledArea();
            output[i] = (doubled / 2) + (doubled % 2 == 0 ? ".0" : ".5");
        }
        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. Why do we keep twice the area?