title: Categorize Box According to Criteria
slug: categorize-box-according-to-criteria
difficulty: easy
leetcode_id: 2525
leetcode_url: https://leetcode.com/problems/categorize-box-according-to-criteria/
categories:
  - math
patterns:
  - greedy

description: |
  Given four integers `length`, `width`, `height`, and `mass`, representing the dimensions and mass of a box, respectively, return *a string representing the **category** of the box*.

  The box is `"Bulky"` if:
  - **Any** of the dimensions of the box is greater or equal to `10^4`.
  - Or, the **volume** of the box is greater or equal to `10^9`.

  If the mass of the box is greater or equal to `100`, it is `"Heavy"`.

  If the box is both `"Bulky"` and `"Heavy"`, then its category is `"Both"`.

  If the box is neither `"Bulky"` nor `"Heavy"`, then its category is `"Neither"`.

  If the box is `"Bulky"` but not `"Heavy"`, then its category is `"Bulky"`.

  If the box is `"Heavy"` but not `"Bulky"`, then its category is `"Heavy"`.

  **Note** that the volume of the box is the product of its length, width, and height.

constraints: |
  - `1 <= length, width, height <= 10^5`
  - `1 <= mass <= 10^3`

examples:
  - input: "length = 1000, width = 35, height = 700, mass = 300"
    output: '"Heavy"'
    explanation: "None of the dimensions is >= 10^4. Volume = 24,500,000 < 10^9, so not Bulky. But mass = 300 >= 100, so Heavy. Since not Bulky but Heavy, return \"Heavy\"."
  - input: "length = 200, width = 50, height = 800, mass = 50"
    output: '"Neither"'
    explanation: "None of the dimensions is >= 10^4. Volume = 8,000,000 < 10^9, so not Bulky. Mass = 50 < 100, so not Heavy. Since neither Bulky nor Heavy, return \"Neither\"."

explanation:
  intuition: |
    Think of this problem like a sorting machine at a shipping warehouse. Packages arrive on a conveyor belt, and the machine needs to route them to different areas based on two independent checks:

    1. **Size check**: Is the box physically large enough to be considered "Bulky"?
    2. **Weight check**: Is the box heavy enough to be considered "Heavy"?

    These two properties are completely independent of each other. A tiny box of lead could be Heavy but not Bulky. A massive box of feathers could be Bulky but not Heavy. A giant crate of iron could be Both. An ordinary shoebox could be Neither.

    The key insight is that we don't need any complex logic — we simply evaluate both conditions separately, then combine the results to determine which of the four categories applies.

  approach: |
    We solve this using a **Direct Condition Evaluation** approach:

    **Step 1: Define the threshold constants**

    - `DIMENSION_THRESHOLD`: `10^4` (10,000) — any single dimension at or above this makes the box Bulky
    - `VOLUME_THRESHOLD`: `10^9` (1,000,000,000) — volume at or above this makes the box Bulky
    - `MASS_THRESHOLD`: `100` — mass at or above this makes the box Heavy

    &nbsp;

    **Step 2: Check if the box is Bulky**

    - Calculate the volume: `length * width * height`
    - Check if any dimension >= `10^4` OR if volume >= `10^9`
    - Store result in a boolean `is_bulky`

    &nbsp;

    **Step 3: Check if the box is Heavy**

    - Check if mass >= `100`
    - Store result in a boolean `is_heavy`

    &nbsp;

    **Step 4: Return the appropriate category**

    - If both `is_bulky` and `is_heavy`: return `"Both"`
    - If `is_bulky` but not `is_heavy`: return `"Bulky"`
    - If `is_heavy` but not `is_bulky`: return `"Heavy"`
    - If neither: return `"Neither"`

  common_pitfalls:
    - title: Integer Overflow When Calculating Volume
      description: |
        The volume calculation `length * width * height` can produce very large numbers. With maximum dimensions of `10^5` each, the maximum volume is `10^15`.

        In languages with fixed-size integers (like 32-bit int in C++/Java), this will overflow since `2^31 - 1 ≈ 2.1 * 10^9`. Python handles arbitrary precision integers automatically, but in other languages you must use 64-bit integers (long) or check dimensions first before calculating volume.
      wrong_approach: "Using 32-bit integers for volume calculation"
      correct_approach: "Use 64-bit integers or check dimensions before volume"

    - title: Misreading the Thresholds
      description: |
        The problem uses scientific notation: `10^4` for dimensions and `10^9` for volume. It's easy to misread these or add/remove zeros.

        - Dimension threshold: 10,000 (ten thousand)
        - Volume threshold: 1,000,000,000 (one billion)

        Double-check your constants match these values exactly.
      wrong_approach: "Using 1000 instead of 10000 for dimension threshold"
      correct_approach: "Carefully verify thresholds: 10^4 = 10000, 10^9 = 1000000000"

    - title: Overcomplicating the Logic
      description: |
        With four possible outputs, it's tempting to write complex nested if-else chains. But since `is_bulky` and `is_heavy` are independent booleans, the logic is actually a simple 2x2 truth table.

        You can even simplify using string arrays or tuple lookups, but straightforward if-else works fine for this easy problem.
      wrong_approach: "Deeply nested conditionals checking all cases redundantly"
      correct_approach: "Evaluate both conditions independently, then combine"

  key_takeaways:
    - "**Decompose into independent checks**: When multiple conditions contribute to a result, evaluate each separately before combining"
    - "**Watch for overflow**: Volume and area calculations with large inputs can exceed 32-bit integer limits"
    - "**Truth table thinking**: With two boolean conditions and four outcomes, visualise as a 2x2 grid to ensure you cover all cases"
    - "**Constants over magic numbers**: Define thresholds as named constants for clarity and maintainability"

  time_complexity: "O(1). We perform a fixed number of comparisons and one multiplication, regardless of input values."
  space_complexity: "O(1). We only use a few boolean variables and store no data proportional to input."

solutions:
  - approach_name: Direct Condition Evaluation
    is_optimal: true
    code: |
      def categorize_box(length: int, width: int, height: int, mass: int) -> str:
          # Define thresholds for classification
          DIMENSION_THRESHOLD = 10**4  # 10,000
          VOLUME_THRESHOLD = 10**9     # 1,000,000,000
          MASS_THRESHOLD = 100

          # Calculate volume (Python handles large integers natively)
          volume = length * width * height

          # Check if box is Bulky: any dimension >= 10^4 OR volume >= 10^9
          is_bulky = (
              length >= DIMENSION_THRESHOLD or
              width >= DIMENSION_THRESHOLD or
              height >= DIMENSION_THRESHOLD or
              volume >= VOLUME_THRESHOLD
          )

          # Check if box is Heavy: mass >= 100
          is_heavy = mass >= MASS_THRESHOLD

          # Return category based on combination of conditions
          if is_bulky and is_heavy:
              return "Both"
          elif is_bulky:
              return "Bulky"
          elif is_heavy:
              return "Heavy"
          else:
              return "Neither"
    explanation: |
      **Time Complexity:** O(1) — Fixed number of operations regardless of input size.

      **Space Complexity:** O(1) — Only boolean variables and constants used.

      We evaluate the Bulky and Heavy conditions independently, then use simple conditionals to return the correct category. This approach is clean, readable, and efficient.

  - approach_name: Tuple Lookup
    is_optimal: false
    code: |
      def categorize_box(length: int, width: int, height: int, mass: int) -> str:
          # Calculate volume
          volume = length * width * height

          # Determine boolean flags
          is_bulky = (
              length >= 10000 or
              width >= 10000 or
              height >= 10000 or
              volume >= 10**9
          )
          is_heavy = mass >= 100

          # Use tuple as key to lookup result
          # (is_bulky, is_heavy) -> category
          categories = {
              (True, True): "Both",
              (True, False): "Bulky",
              (False, True): "Heavy",
              (False, False): "Neither"
          }

          return categories[(is_bulky, is_heavy)]
    explanation: |
      **Time Complexity:** O(1) — Dictionary lookup is constant time.

      **Space Complexity:** O(1) — Fixed-size dictionary with 4 entries.

      This approach uses a dictionary with tuple keys to map all four combinations directly to their results. While slightly more Pythonic and eliminates if-else chains, it's marginally less efficient due to dictionary lookup overhead. For this simple problem, the direct approach is preferred.
