Hone logo
Hone
Problems

Implement a Flexible createCounter Function

Modern user interfaces frequently require managing simple numerical states, like quantities in a shopping cart, progress indicators, or interactive scores. A dedicated createCounter function (analogous to a React hook) abstracts away the complexity of managing these count values, providing a clean API for common operations.

Problem Description

Your task is to implement a createCounter function that manages a single numeric counter. This function should initialize the counter and provide methods to manipulate its value, respecting optional bounds.

The createCounter function should accept an optional initialValue and an optional options object. The options object can contain:

  • min: The minimum allowed value for the counter.
  • max: The maximum allowed value for the counter.

The createCounter function should return an object with the following properties:

  • currentValue: The current numerical value of the counter.
  • increment(step = 1): A function that increases currentValue by step. If max is defined, currentValue should not exceed it.
  • decrement(step = 1): A function that decreases currentValue by step. If min is defined, currentValue should not go below it.
  • reset(): A function that sets currentValue back to its initialValue. If initialValue was not provided, it resets to 0.

Key Requirements:

  1. Initialization: If no initialValue is provided, the counter should start at 0.
  2. Default Step: If no step is provided to increment or decrement, it should default to 1.
  3. Bounds Enforcement:
    • When incrementing, the counter must not exceed the max value if specified.
    • When decrementing, the counter must not go below the min value if specified.
  4. Reset Behavior: The reset function must restore the counter to its initial configured state (the initialValue passed during createCounter invocation, or 0 if none was passed).
  5. Edge Cases:
    • If min is greater than max in the options, treat min as 0 and max as Infinity for practical clamping purposes.
    • Operations should not throw errors due to reaching bounds; they should simply clamp the value at the respective min or max.

Examples

Example 1: Basic Counter

// Initialize a basic counter
counter1 = createCounter()

// Access initial value
print(counter1.currentValue) // Output: 0

// Increment by default step (1)
counter1.increment()
print(counter1.currentValue) // Output: 1

// Decrement by default step (1)
counter1.decrement()
print(counter1.currentValue) // Output: 0

// Reset
counter1.reset()
print(counter1.currentValue) // Output: 0

Explanation: The counter starts at 0, increments to 1, decrements back to 0, and resets to 0.

Example 2: Counter with Initial Value and Custom Steps

// Initialize counter starting at 10
counter2 = createCounter(10)

// Access initial value
print(counter2.currentValue) // Output: 10

// Increment by 5
counter2.increment(5)
print(counter2.currentValue) // Output: 15

// Decrement by 3
counter2.decrement(3)
print(counter2.currentValue) // Output: 12

// Reset
counter2.reset()
print(counter2.currentValue) // Output: 10

Explanation: The counter starts at 10, increments by 5 to 15, decrements by 3 to 12, and resets to 10.

Example 3: Counter with Bounds and Reset

// Initialize counter with value 5, min 0, max 10
counter3 = createCounter(5, { min: 0, max: 10 })

// Access initial value
print(counter3.currentValue) // Output: 5

// Attempt to increment past max
counter3.increment(7) // 5 + 7 = 12, but max is 10. Clamps at 10.
print(counter3.currentValue) // Output: 10

// Attempt to decrement past min
counter3.decrement(15) // 10 - 15 = -5, but min is 0. Clamps at 0.
print(counter3.currentValue) // Output: 0

// Increment by a valid step within bounds
counter3.increment(3)
print(counter3.currentValue) // Output: 3

// Reset
counter3.reset()
print(counter3.currentValue) // Output: 5

Explanation: The counter starts at 5, respects the max bound of 10 when incrementing, respects the min bound of 0 when decrementing, and resets to its initial value of 5.

Constraints

  • initialValue, step, min, max will be integers.
  • step will be a positive integer (greater than 0).
  • min and max are optional; if provided, they will be integers.
  • The createCounter function and its returned methods should operate in O(1) time complexity.
  • The implementation should not rely on external UI framework-specific state management libraries for its core logic (e.g., React's useState). It should be a self-contained state management implementation.

Notes

Think about how you would encapsulate state within the createCounter function. In many languages, this might involve closures or class-like structures to maintain currentValue and initialValue across calls to the returned methods. The problem focuses on the logic of state management and operations, not UI rendering. Remember to consistently apply the min and max bounds after every operation (increment, decrement).

Loading editor...
plaintext