AlgoMaster Logo
AlgoMasterDesign a Shape Calculatormedium

Design a Shape Calculator

medium

Design a ShapeCalculator that stores different kinds of shapes and works with them through one shared abstraction. Circles and rectangles use different formulas, but the calculator should be able to ask either shape for its area, perimeter, and description without checking its concrete type.

The provided ShapeCalculator class supports these operations:

  • ShapeCalculator() creates a calculator holding no shapes.
  • int addCircle(double radius) adds a circle and returns the index it was stored at.
  • int addRectangle(double width, double height) adds a rectangle and returns the index it was stored at.
  • double area(int index) returns the area of the shape at index. Use pi * radius * radius for a circle and width * height for a rectangle.
  • double perimeter(int index) returns the perimeter of the shape at index. Use 2 * pi * radius for a circle and 2 * (width + height) for a rectangle.
  • String describe(int index) returns "Shape: <name>, Area: <area>, Perimeter: <perimeter>". The name is Circle or Rectangle, and both measurements must display exactly two decimal places.
  • double totalArea() returns the sum of every shape's full-precision area. Do not round individual areas before adding them.

Indices are assigned in insertion order starting at 0. Store shape objects rather than separate type labels and dimensions. Adding another shape type later must not require changing the existing describe or totalArea logic.

Your task is to implement the Shape abstraction and the concrete Circle and Rectangle classes it depends on. Do not modify the provided ShapeCalculator. Keep every geometry formula inside its corresponding shape.

Example 1:

Input:

Output:

Explanation: The circle is stored at index 0 and the rectangle at index 1. Their descriptions format area and perimeter to two decimal places. totalArea() adds the unrounded areas, so it returns 78.53981633974483 + 24 = 102.53981633974483.

Example 2:

Input:

Output:

Explanation: A 3 × 3 rectangle has an area of 9.0 and a perimeter of 12.0. Because it is the only stored shape, the total area is also 9.0.

Constraints:
  • 0 < radius, width, height <= 1000
  • index always refers to a shape that has been added.
  • At most 100 calls will be made across all methods.

How the design is graded

needs 7/10 to pass
  • Abstraction

    Full marks when there is a shape abstraction (abstract class or interface) declaring area and perimeter, with a concrete circle and rectangle implementing them. Lose points heavily when the calculator branches on a stored type tag or an if/switch over shape kind instead of delegating to the shape.

  • Shared behaviour placement

    Full marks when the describe sentence is written once on the abstraction and reused by every shape, rather than duplicated per shape or assembled inside the calculator. Lose points when adding a third shape would require editing existing describe logic.

  • Structure and naming

    Full marks for a calculator that stores shapes rather than raw dimensions, with descriptive names and no dead code. Lose points for parallel arrays of radii and widths, printing to stdout, or geometry constants duplicated across methods.

Passing every test is not enough on its own. A submission is accepted only when the design also clears the bar.

Hints

Loading...
CallReturns
new ShapeCalculator()null
addCircle(5)0
addRectangle(4, 6)1
describe(0)"Shape: Circle, Area: 78.54, Perimeter: 31.42"
describe(1)"Shape: Rectangle, Area: 24.00, Perimeter: 20.00"
totalArea()102.53981633974483

The circle and rectangle are stored at indices 0 and 1. describe formats their measurements to two decimal places, while totalArea sums their full-precision areas.

Run checks these cases. Submit also runs a larger hidden set.