Greedy algorithm for Egyptian fractions: Difference between revisions
Content added Content deleted
(Added Algol 68) |
|||
Line 42: | Line 42: | ||
* Wolfram MathWorld™ entry: [http://mathworld.wolfram.com/EgyptianFraction.html Egyptian fraction] |
* Wolfram MathWorld™ entry: [http://mathworld.wolfram.com/EgyptianFraction.html Egyptian fraction] |
||
<br><br> |
<br><br> |
||
=={{header|ALGOL 68}}== |
|||
{{works with|ALGOL 68G|Any - tested with release 2.8.3.win32}} |
|||
Based on the VB.NET sample.<br> |
|||
Uses Algol 68G's LONG LONG INT for large integers. |
|||
<lang algol68>BEGIN # compute some Egytian fractions # |
|||
PR precision 2000 PR # set the number of digits for LONG LOG INT # |
|||
PROC gcd = ( LONG LONG INT a, b )LONG LONG INT: |
|||
IF b = 0 THEN |
|||
IF a < 0 THEN |
|||
- a |
|||
ELSE |
|||
a |
|||
FI |
|||
ELSE |
|||
gcd( b, a MOD b ) |
|||
FI ; # gcd # |
|||
MODE RATIONAL = STRUCT( LONG LONG INT num, den ); |
|||
MODE LISTOFRATIONAL = STRUCT( RATIONAL element, REF LISTOFRATIONAL next ); |
|||
REF LISTOFRATIONAL nil list of rational = NIL; |
|||
OP TOSTRING = ( INT a )STRING: whole( a, 0 ); |
|||
OP TOSTRING = ( LONG INT a )STRING: whole( a, 0 ); |
|||
OP TOSTRING = ( LONG LONG INT a )STRING: whole( a, 0 ); |
|||
OP TOSTRING = ( RATIONAL a )STRING: |
|||
IF den OF a = 1 |
|||
THEN TOSTRING num OF a |
|||
ELSE TOSTRING num OF a + "/" + TOSTRING den OF a |
|||
FI ; # TOSTRING # |
|||
OP TOSTRING = ( REF LISTOFRATIONAL lr )STRING: |
|||
BEGIN |
|||
REF LISTOFRATIONAL p := lr; |
|||
STRING result := "["; |
|||
WHILE p ISNT nil list of rational DO |
|||
result +:= TOSTRING element OF p; |
|||
IF next OF p IS nil list of rational THEN |
|||
p := NIL |
|||
ELSE |
|||
p := next OF p; |
|||
result +:= " + " |
|||
FI |
|||
OD; |
|||
result + "]" |
|||
END ; # TOSTRING # |
|||
OP CEIL = ( LONG LONG REAL v )LONG LONG INT: |
|||
IF LONG LONG INT result := ENTIER v; |
|||
ABS v > ABS result |
|||
THEN result + 1 |
|||
ELSE result |
|||
FI ; # CEIL # |
|||
OP EGYPTIAN = ( RATIONAL rp )REF LISTOFRATIONAL: |
|||
IF RATIONAL r := rp; |
|||
num OF r = 0 OR num OF r = 1 |
|||
THEN HEAP LISTOFRATIONAL := ( r, nil list of rational ) |
|||
ELSE |
|||
REF LISTOFRATIONAL result := nil list of rational; |
|||
REF LISTOFRATIONAL end result := nil list of rational; |
|||
PROC add = ( RATIONAL r )VOID: |
|||
IF end result IS nil list of rational THEN |
|||
result := HEAP LISTOFRATIONAL := ( r, nil list of rational ); |
|||
end result := result |
|||
ELSE |
|||
next OF end result := HEAP LISTOFRATIONAL := ( r, nil list of rational ); |
|||
end result := next OF end result |
|||
FI ; # add # |
|||
IF num OF r > den OF r THEN |
|||
add( RATIONAL( num OF r OVER den OF r, 1 ) ); |
|||
r := ( num OF r MOD den OF r, den OF r ) |
|||
FI; |
|||
PROC mod func = ( LONG LONG INT m, n )LONG LONG INT: ( ( m MOD n ) + n ) MOD n; |
|||
WHILE num OF r /= 0 DO |
|||
LONG LONG INT q = CEIL( den OF r / num OF r ); |
|||
add( RATIONAL( 1, q ) ); |
|||
r := RATIONAL( mod func( - ( den OF r ), num OF r ), ( den OF r ) * q ) |
|||
OD; |
|||
result |
|||
FI ; # EGYPTIAN # |
|||
BEGIN # task test cases # |
|||
[]RATIONAL test cases = ( RATIONAL( 43, 48 ), RATIONAL( 5, 121 ), RATIONAL( 2014, 59 ) ); |
|||
FOR r pos FROM LWB test cases TO UPB test cases DO |
|||
print( ( TOSTRING test cases[ r pos ], " -> ", TOSTRING EGYPTIAN test cases[ r pos ], newline ) ) |
|||
OD; |
|||
# find the fractions with the most terms and the largest denominator # |
|||
print( ( "For rationals with numerator and denominator in 1..99:", newline ) ); |
|||
RATIONAL largest denominator := ( 0, 1 ); |
|||
REF LISTOFRATIONAL max denominator list := nil list of rational; |
|||
LONG LONG INT max denominator := 0; |
|||
RATIONAL most terms := ( 0, 1 ); |
|||
REF LISTOFRATIONAL most terms list := nil list of rational; |
|||
INT max terms := 0; |
|||
FOR num TO 99 DO |
|||
FOR den TO 99 DO |
|||
RATIONAL r = RATIONAL( num, den ); |
|||
REF LISTOFRATIONAL e := EGYPTIAN r; |
|||
REF LISTOFRATIONAL p := e; |
|||
INT terms := 0; |
|||
WHILE p ISNT nil list of rational DO |
|||
terms +:= 1; |
|||
IF den OF element OF p > max denominator THEN |
|||
largest denominator := r; |
|||
max denominator := den OF element OF p; |
|||
max denominator list := e |
|||
FI; |
|||
p := next OF p |
|||
OD; |
|||
IF terms > max terms THEN |
|||
most terms := r; |
|||
max terms := terms; |
|||
most terms list := e |
|||
FI |
|||
OD |
|||
OD; |
|||
print( ( " ", TOSTRING most terms, " has the most terms: ", TOSTRING max terms, newline |
|||
, " ", TOSTRING most terms list, newline |
|||
) |
|||
); |
|||
print( ( " ", TOSTRING largest denominator, " has the largest denominator:", newline |
|||
, " ", TOSTRING max denominator list, newline |
|||
) |
|||
) |
|||
END |
|||
END</lang> |
|||
{{out}} |
|||
<pre> |
|||
43/48 -> [1/2 + 1/3 + 1/16] |
|||
5/121 -> [1/25 + 1/757 + 1/763309 + 1/873960180913 + 1/1527612795642093418846225] |
|||
2014/59 -> [34 + 1/8 + 1/95 + 1/14947 + 1/670223480] |
|||
For rationals with numerator and denominator in 1..99: |
|||
97/53 has the most terms: 9 |
|||
[1 + 1/2 + 1/4 + 1/13 + 1/307 + 1/120871 + 1/20453597227 + 1/697249399186783218655 + 1/1458470173998990524806872692984177836808420] |
|||
8/97 has the largest denominator: |
|||
[1/13 + 1/181 + 1/38041 + 1/1736503177 + 1/3769304102927363485 + 1/18943537893793408504192074528154430149 + 1/538286441900380211365817285104907086347439746130226973253778132494225813153 + 1/579504587067542801713103191859918608251030291952195423583529357653899418686342360361798689053273749372615043661810228371898539583862011424993909789665] |
|||
</pre> |
|||
=={{header|C}}== |
=={{header|C}}== |