A drawing canvas has shapes and renderers. A shape knows its geometry; a renderer knows how to put a primitive on screen. Adding a shape must not touch the renderers and adding a renderer must not touch the shapes.
Canvas is provided in the starter code. Implement only the bridge: the Renderer implementor contract with VectorRenderer and RasterRenderer, and the Shape abstraction with Circle and Square (IRenderer in C#, a Shape interface with Circle and Square structs in Go).
Renderer exposes renderCircle(radius) and renderSquare(side).VectorRenderer returns "Drawing a circle of radius 5 as lines" and "Drawing a square of side 4 as lines". RasterRenderer returns "Drawing pixels for a circle of radius 5" and "Drawing pixels for a square of side 4".Shape(renderer) exposes setRenderer(renderer), draw(), resize(factor) and describe().Circle(renderer, radius) draws through renderCircle, multiplies its radius on resize, and describes itself as "circle(5)". Square(renderer, side) does the same with renderSquare and "square(4)".The provided Canvas exposes this API:
Canvas() starts with a circle of radius 1 on the vector renderer.boolean setShape(String kind, int size) replaces the shape with a fresh "circle" or "square" of that size on the current renderer. Any other kind or a size below 1 returns false.boolean setRenderer(String kind) switches to "vector" or "raster" and re-points the current shape. Any other kind returns false.String draw() draws the current shape and counts one draw.boolean resize(int factor) resizes the current shape, or returns false for a factor below 1.String describe() and String pairing() report the current shape and "<shape> via <renderer>".int drawCount() returns how many draws have been counted.The tests call the provided Canvas; your work should be confined to the two hierarchies and the reference between them.
Input:
Output:
Explanation: The same circle draws through two renderers. Its radius did not change; only the renderer wording did.
Input:
Output:
Explanation: Resizing happens on the shape. A renderer swap in between does not touch the side, so the second resize builds on the first.
kind is a lower case word of at most 10 characters.-1 <= size, factor <= 20100 calls in total are made across all methods.Implement Renderer, VectorRenderer, RasterRenderer, Shape, Circle and Square. Canvas is complete and must not be modified.
Full marks when `Shape` holds a `Renderer` and `draw` delegates to the renderer method for that shape, so `VectorRenderer` and `RasterRenderer` differ only in wording while `Circle` and `Square` differ only in which primitive they call. Lose points heavily when a shape formats output itself or a renderer checks the shape's kind.
Full marks when the radius or side lives on the shape, `resize` changes it there, and the renderer receives the current value on every draw. Lose points when a renderer stores a size or a resize is lost on a renderer swap.
Full marks when `setRenderer` re-points the existing shape and a new shape adopts the current renderer. Lose points for printing to stdout.
Passing every test is not enough on its own. A submission is accepted only when the design also clears the bar.
| Call | Returns |
|---|---|
| new Canvas() | null |
| setShape("circle", 5) | true |
| draw() | "Drawing a circle of radius 5 as lines" |
| setRenderer("raster") | true |
| draw() | "Drawing pixels for a circle of radius 5" |
| pairing() | "circle via raster" |
| drawCount() | 2 |
The same circle draws through two renderers. Its radius did not change; only the renderer wording did.
Run checks these cases. Submit also runs a larger hidden set.

