Skip to main content

How to Find Consecutive Odd Integer Pairs Below a Limit with Sum Above a Threshold in Python

A common programming exercise involves finding pairs of consecutive odd positive integers that satisfy two conditions simultaneously: both numbers must be smaller than a given upper limit a, and their sum must be greater than a given threshold b. This type of problem appears in number theory exercises, competitive programming, and mathematical filtering tasks.

In this guide, you'll learn clear and efficient approaches to solve this problem in Python, with detailed explanations and edge case handling.

Understanding the Problem

Given two positive integers a and b, find all pairs (x, x+2) where:

  • Both x and x + 2 are odd positive integers
  • Both x and x + 2 are less than a
  • The sum x + (x + 2) is greater than b

Example: With a = 60 and b = 100:

PairSumLess than 60?Sum > 100?Valid?
(51, 53)104
(53, 55)108
(55, 57)112
(57, 59)116
(49, 51)100

Using an Optimized Loop with Range

The most efficient approach iterates only over odd numbers and starts from the minimum possible value instead of checking every odd number from 1.

Since the sum of a pair (x, x+2) is 2x + 2, the condition 2x + 2 > b means x > (b - 2) / 2. We can calculate the starting point directly:

def find_consecutive_odd_pairs(a, b):
"""Find consecutive odd integer pairs less than `a` with sum greater than `b`."""
pairs = []

# Calculate the minimum odd number where the sum could exceed b
min_start = max(1, (b // 2))
if min_start % 2 == 0:
min_start += 1 # Ensure we start on an odd number

for x in range(min_start, a - 1, 2): # Step by 2 to hit only odd numbers
if x + 2 < a and x + (x + 2) > b:
pairs.append((x, x + 2))

return pairs


# Example 1
a, b = 60, 100
pairs = find_consecutive_odd_pairs(a, b)

if pairs:
print(f"Pairs of consecutive odd integers less than {a} with sum > {b}:")
for x, y in pairs:
print(f" ({x}, {y}) → sum = {x + y}")
else:
print("No pairs found.")

Output:

Pairs of consecutive odd integers less than 60 with sum > 100:
(51, 53) → sum = 104
(53, 55) → sum = 108
(55, 57) → sum = 112
(57, 59) → sum = 116

How it works:

  1. The minimum starting value is calculated from b to skip numbers that can't possibly form valid pairs.
  2. range(min_start, a - 1, 2) iterates over odd numbers only (step of 2), avoiding unnecessary even-number checks.
  3. x + 2 < a ensures both numbers in the pair are below the limit.
  4. The sum check x + (x + 2) > b filters for pairs meeting the threshold.

Using List Comprehension

For a concise one-liner approach, list comprehension handles the same logic compactly:

def find_consecutive_odd_pairs(a, b):
"""Find consecutive odd pairs less than a with sum greater than b."""
return [
(x, x + 2)
for x in range(1, a - 1, 2)
if x + 2 < a and 2 * x + 2 > b
]


a, b = 60, 100
pairs = find_consecutive_odd_pairs(a, b)

for x, y in pairs:
print(f"{x} , {y}")

Output:

51 , 53
53 , 55
55 , 57
57 , 59
Performance note

The range(1, a - 1, 2) with step 2 ensures only odd numbers are iterated, cutting the number of iterations in half compared to checking every integer.

Handling Edge Cases

It's important to handle scenarios where no valid pairs exist or the inputs are invalid.

When No Pairs Exist

If b is too large relative to a, no pairs will satisfy both conditions:

def find_consecutive_odd_pairs(a, b):
"""Find consecutive odd pairs less than a with sum greater than b."""
return [
(x, x + 2)
for x in range(1, a - 1, 2)
if x + 2 < a and 2 * x + 2 > b
]

a, b = 20, 200
pairs = find_consecutive_odd_pairs(a, b)

if pairs:
for x, y in pairs:
print(f"{x} , {y}")
else:
print("No valid pairs found.")

Output:

No valid pairs found.

The largest possible pair with a = 20 is (17, 19) with sum 36, which is far below 200.

Input Validation

Always validate that inputs are positive integers before processing:

def find_consecutive_odd_pairs_safe(a, b):
"""Find consecutive odd pairs with input validation."""
if not isinstance(a, int) or not isinstance(b, int):
raise TypeError("Both a and b must be integers.")
if a <= 0 or b <= 0:
raise ValueError("Both a and b must be positive integers.")
if a < 4:
return [] # Need at least (1, 3) as a valid pair

return [
(x, x + 2)
for x in range(1, a - 1, 2)
if x + 2 < a and 2 * x + 2 > b
]


# Valid input
print(find_consecutive_odd_pairs_safe(60, 100))

# Edge case: a is too small
print(find_consecutive_odd_pairs_safe(3, 1))

Output:

[(51, 53), (53, 55), (55, 57), (57, 59)]
[]

Common Mistake: Including Even Numbers or Incorrect Boundaries

A frequent error is iterating through all integers without filtering for odd numbers, or using <= instead of < for the boundary check.

Wrong approach:

a, b = 60, 100
pairs = []

for x in range(1, a): # Iterates over ALL integers, not just odd ones
if x + (x + 2) > b:
pairs.append((x, x + 2))

print(pairs[:5]) # Show first 5

Output:

[(50, 52), (51, 53), (52, 54), (53, 55), (54, 56)]

This incorrectly includes even pairs like (50, 52) and (52, 54), and doesn't check that x + 2 < a.

Correct approach:

a, b = 60, 100
pairs = [
(x, x + 2)
for x in range(1, a - 1, 2) # Only odd numbers (step=2, starting at 1)
if x + 2 < a and 2 * x + 2 > b # Both bounds checked
]

print(pairs)

Output:

[(51, 53), (53, 55), (55, 57), (57, 59)]
Boundary condition: < vs <=

The problem states both numbers must be smaller than a, so use strict less-than (<). If the requirement were "smaller than or equal to," you'd adjust to x + 2 <= a.

Using a Generator for Memory Efficiency

For very large values of a, a generator avoids storing all pairs in memory at once:

def consecutive_odd_pairs_gen(a, b):
"""Yield consecutive odd pairs less than a with sum greater than b."""
for x in range(1, a - 1, 2):
if x + 2 < a and 2 * x + 2 > b:
yield (x, x + 2)


# Process pairs one at a time
a, b = 1000, 1900
for pair in consecutive_odd_pairs_gen(a, b):
print(f"{pair[0]} , {pair[1]}")

Output:

951 , 953
953 , 955
955 , 957
957 , 959
959 , 961
961 , 963
963 , 965
965 , 967
967 , 969
969 , 971
971 , 973
973 , 975
975 , 977
977 , 979
979 , 981
981 , 983
983 , 985
985 , 987
987 , 989
989 , 991
991 , 993
993 , 995
995 , 997
997 , 999

Conclusion

Finding consecutive odd integer pairs with constraints on both an upper limit and a minimum sum is straightforward in Python with the right approach:

  • Use range() with a step of 2 starting from 1 to iterate over only odd numbers, which halves the number of iterations.
  • Calculate the minimum starting point from the threshold b to skip numbers that can't possibly form valid pairs, improving efficiency further.
  • List comprehension provides a clean, readable one-liner for simple cases.
  • Generators are ideal when working with very large ranges to conserve memory.
  • Always validate inputs and handle edge cases where no valid pairs exist.

The time complexity is O(a) in the worst case and the space complexity is O(1) when using a generator or O(k) when storing results, where k is the number of valid pairs.