Check if item can be measured using a scale and some weights in Python

When you have weights like a0, a1, a2, ..., a100 and a weighing scale where weights can be placed on both sides, you need to determine if a particular item of weight W can be measured. This involves finding a combination where some weights are added and some are subtracted to equal the target weight.

For example, if a = 4 and W = 17, the weights are 1, 4, 16, 64, ... We can achieve 17 by using 16 + 1 = 17.

Algorithm

The solution uses recursive backtracking to try all possible combinations of weights:

  • For each weight, we have three choices: don't use it, add it to the left side, or add it to the right side
  • We generate weights as powers of 'a' up to a reasonable limit (107)
  • Special case: if a is 2 or 3, any weight can be measured (mathematical property)

Implementation

def can_measure_weight(a, W):
    # Special cases where any weight can be measured
    if a == 2 or a == 3:
        return True
    
    # Generate weights as powers of a
    weights = []
    power = 1
    while power <= 10**7:
        weights.append(power)
        power *= a
    
    def backtrack(idx, current_weight):
        # Base cases
        if current_weight == 0:
            return True
        if idx >= len(weights):
            return False
        
        # Three choices for each weight:
        # 1. Don't use this weight
        if backtrack(idx + 1, current_weight):
            return True
        
        # 2. Add weight to left side (subtract from target)
        if backtrack(idx + 1, current_weight - weights[idx]):
            return True
        
        # 3. Add weight to right side (add to target)
        if backtrack(idx + 1, current_weight + weights[idx]):
            return True
        
        return False
    
    return backtrack(0, W)

# Test the function
a = 4
W = 17
result = can_measure_weight(a, W)
print(f"Can measure weight {W} with base {a}: {result}")

# Another example
a = 3
W = 10
result = can_measure_weight(a, W)
print(f"Can measure weight {W} with base {a}: {result}")
Can measure weight 17 with base 4: True
Can measure weight 10 with base 3: True

How It Works

The algorithm works by exploring all possible combinations:

  • Weight generation: Creates powers of 'a' until they exceed 107
  • Recursive exploration: For each weight, tries three options − ignore, add to left, add to right
  • Base condition: Returns True when current_weight becomes 0 (balanced scale)

Example Walkthrough

For a = 4, W = 17:

  • Weights: [1, 4, 16, 64, ...]
  • Target: 17
  • Solution: Use weights 16 and 1 on the left side: 16 + 1 = 17

Optimized Version

Here's a more efficient version using memoization ?

def can_measure_optimized(a, W):
    if a == 2 or a == 3:
        return True
    
    weights = []
    power = 1
    while power <= 10**7:
        weights.append(power)
        power *= a
    
    memo = {}
    
    def backtrack(idx, target):
        if (idx, target) in memo:
            return memo[(idx, target)]
        
        if target == 0:
            return True
        if idx >= len(weights) or abs(target) > sum(weights[idx:]):
            return False
        
        # Try all three options
        result = (backtrack(idx + 1, target) or 
                 backtrack(idx + 1, target - weights[idx]) or 
                 backtrack(idx + 1, target + weights[idx]))
        
        memo[(idx, target)] = result
        return result
    
    return backtrack(0, W)

# Test optimized version
print(can_measure_optimized(4, 17))
print(can_measure_optimized(5, 23))
True
True

Conclusion

This solution uses recursive backtracking to determine if a weight can be measured using powers of a given base on a balance scale. The key insight is that we can place weights on both sides, effectively allowing addition and subtraction operations to reach the target weight.

Updated on: 2026-03-25T15:15:20+05:30

317 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements