Hone logo
Hone
Problems

Implementing Const Evaluation in Rust

Const evaluation allows computations to be performed at compile time rather than runtime, leading to significant performance improvements and enabling compile-time assertions. This challenge asks you to implement a simple constant expression evaluator that can perform basic arithmetic operations on integer constants. Successfully completing this challenge demonstrates understanding of Rust's const keyword, static items, and the limitations of compile-time evaluation.

Problem Description

You are tasked with creating a module named const_eval that provides a function calculate(a: &i32, b: &i32, operation: &str) -> i32. This function should perform a calculation based on the provided integer constants a and b and the operation string. The operation string will be either "add", "subtract", "multiply", or "divide". The function must perform the calculation at compile time if possible. If the calculation cannot be performed at compile time (e.g., due to runtime input), it should perform the calculation at runtime.

Key Requirements:

  • The calculate function must accept &i32 references as input.
  • The operation parameter must be a string slice (&str).
  • The function must return an i32.
  • The function must attempt to perform the calculation at compile time using const items and static items where appropriate.
  • If compile-time evaluation is not possible, the calculation should be performed at runtime.
  • Handle division by zero gracefully at runtime, returning 0 in that case.

Expected Behavior:

  • When a, b, and operation are known at compile time (e.g., passed as const values), the calculation should be performed at compile time.
  • When a or b or operation are not known at compile time, the calculation should be performed at runtime.
  • The code should be well-structured and readable.

Edge Cases to Consider:

  • Division by zero.
  • Invalid operation strings (anything other than "add", "subtract", "multiply", or "divide"). In this case, perform the addition at runtime.
  • Large integer values that might cause overflow during compile-time calculations. Runtime evaluation is acceptable in these cases.

Examples

Example 1:

Input: a = 5, b = 10, operation = "add" (all const)
Output: 15
Explanation: The addition can be performed at compile time, resulting in a compile-time constant.

Example 2:

Input: a = 5, b = 10, operation = "multiply" (all const)
Output: 50
Explanation: The multiplication can be performed at compile time.

Example 3:

Input: a = 5, b = 10, operation = "divide" (all const), b = 0
Output: 0
Explanation: Division by zero is handled at runtime, returning 0.

Example 4:

Input: a = 5, b = 10, operation = "subtract" (all const)
Output: -5
Explanation: The subtraction can be performed at compile time.

Example 5:

Input: a = 5, b = 10, operation = "invalid_op" (all const)
Output: 15
Explanation: Invalid operation string handled at runtime, defaulting to addition.

Constraints

  • a and b will be i32 integers.
  • operation will be a &str string.
  • The function must return an i32.
  • The code should be reasonably efficient, prioritizing compile-time evaluation where possible.
  • The solution must compile and run without errors.

Notes

  • Consider using const items to define constant values and expressions.
  • Explore the use of static items for compile-time data.
  • Rust's const evaluation has limitations; not all expressions can be evaluated at compile time. Be prepared to handle runtime evaluation when necessary.
  • Think about how to structure your code to maximize compile-time evaluation while gracefully handling runtime scenarios.
  • Use conditional compilation (cfg attributes) if needed to optimize for specific scenarios.
Loading editor...
rust