Hone logo
Hone
Problems

Generic Geometric Shapes with Trait Bounds

Rust's powerful generics and trait system allow you to write flexible and reusable code. This challenge focuses on leveraging trait bounds to define a common interface for different geometric shapes, enabling generic functions to operate on them uniformly.

Problem Description

You are tasked with creating a system that can calculate the area and perimeter of various geometric shapes. To achieve this, you need to define a common trait that all shapes will implement. This trait should specify methods for calculating both the area and perimeter. Subsequently, you will create a generic function that can accept any type implementing this trait and perform these calculations.

What needs to be achieved:

  1. Define a Shape trait with methods area() and perimeter().
  2. Implement this Shape trait for at least two distinct geometric shapes (e.g., Circle, Rectangle).
  3. Create a generic function print_shape_info that takes any type T as an argument, where T must implement the Shape trait. This function should call the area() and perimeter() methods and print the results in a user-friendly format.

Key requirements:

  • The Shape trait should have two methods:
    • area(): Returns a f64 representing the area.
    • perimeter(): Returns a f64 representing the perimeter.
  • The print_shape_info function should be generic over a type T that satisfies the Shape trait bound.
  • The output of print_shape_info should clearly indicate the shape type (if possible through introspection or by passing a name) and its calculated area and perimeter.

Expected behavior:

When print_shape_info is called with an instance of Circle, it should correctly calculate and print its area and perimeter. The same should happen for Rectangle and any other shapes you choose to implement.

Important edge cases to consider:

  • The values of dimensions (e.g., radius, width, height) can be floating-point numbers.
  • Consider the mathematical formulas for area and perimeter for each shape.

Examples

Example 1: Circle

Input:
let circle = Circle { radius: 5.0 };
print_shape_info(&circle);
Output:
Shape Info:
  Type: Circle
  Area: 78.53981633974483
  Perimeter: 31.41592653589793
Explanation: The area of a circle is π * r^2, and the perimeter is 2 * π * r.

Example 2: Rectangle

Input:
let rectangle = Rectangle { width: 4.0, height: 6.0 };
print_shape_info(&rectangle);
Output:
Shape Info:
  Type: Rectangle
  Area: 24.0
  Perimeter: 20.0
Explanation: The area of a rectangle is width * height, and the perimeter is 2 * (width + height).

Constraints

  • All calculations involving area and perimeter should use f64 for precision.
  • The input dimensions for shapes can be any non-negative f64 values.
  • The generic function print_shape_info should not make assumptions about the specific concrete type, only that it implements the Shape trait.

Notes

  • You'll need to import std::f64::consts::PI for circle calculations.
  • To display the "Type" in the output, you might need to add a method to the Shape trait or pass a string name to print_shape_info. Consider how to best achieve this.
  • Think about how to define the Shape trait and implement it for your chosen shapes.
  • The core of the challenge is correctly defining the generic function with the Shape trait bound.
Loading editor...
rust