1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
|
from typing import List, Tuple
from math import gcd
from fractions import Fraction
class EgyptianFractionAlternative:
def __init__(self):
self.cache = {}
def egyptian_fraction_optimized(self, a: int, b: int) -> List[int]:
"""
Alternative approach that tries to find representations with smaller denominators.
"""
if (a, b) in self.cache:
return self.cache[(a, b)]
# Reduce to lowest terms
g = gcd(a, b)
a, b = a // g, b // g
if a == 1:
return [b]
# Try the greedy approach
greedy_result = self._greedy_approach(a, b)
# For small fractions, try to find better representations
if a <= 10 and b <= 100:
better_result = self._try_better_representation(a, b)
if better_result and len(better_result) <= len(greedy_result):
self.cache[(a, b)] = better_result
return better_result
self.cache[(a, b)] = greedy_result
return greedy_result
def _greedy_approach(self, a: int, b: int) -> List[int]:
"""Standard greedy algorithm."""
result = []
while a > 0:
unit_denom = (b + a - 1) // a
result.append(unit_denom)
a = a * unit_denom - b
b = b * unit_denom
if a != 0:
g = gcd(a, b)
a, b = a // g, b // g
return result
def _try_better_representation(self, a: int, b: int) -> List[int]:
"""
Try to find a representation with potentially smaller denominators.
This is a simplified heuristic approach.
"""
best_result = None
min_max_denom = float('inf')
# Try splitting the fraction in different ways
for i in range(2, min(b, 20)): # Limit search space
if b % i == 0:
# Try representing as sum of simpler fractions
try:
frac = Fraction(a, b)
unit_frac = Fraction(1, i)
if frac > unit_frac:
remainder = frac - unit_frac
if remainder.denominator <= 1000: # Avoid very large denominators
remainder_egyptian = self._greedy_approach(remainder.numerator, remainder.denominator)
candidate = [i] + remainder_egyptian
max_denom = max(candidate)
if max_denom < min_max_denom:
best_result = candidate
min_max_denom = max_denom
except:
continue
return best_result
# Test the alternative approach
def test_alternative_approach():
alt_solver = EgyptianFractionAlternative()
test_cases = [
(2, 3),
(4, 13),
(5, 6),
(7, 12),
(11, 12)
]
for a, b in test_cases:
greedy = alt_solver._greedy_approach(a, b)
optimized = alt_solver.egyptian_fraction_optimized(a, b)
print(f"{a}/{b}:")
print(f" Greedy: {' + '.join(f'1/{d}' for d in greedy)}")
print(f" Optimized: {' + '.join(f'1/{d}' for d in optimized)}")
print()
if __name__ == "__main__":
test_alternative_approach()
|