Engel expansion: Difference between revisions

Created Nim solution.
(→‎{{header|Quackery}}: Meets stretch requirements now.)
(Created Nim solution.)
Line 156:
Engel expansion: [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 4, 33, 33, 35, 58, 62, 521, 3125] (34 components)
Back to rational: 25.628906
</pre>
 
=={{header|Nim}}==
We use the module “rationals” from the standard library which is limited to <code>int64</code> numerators and denominators. We had to define a conversion function from string to Rational as using the provided conversion function from float to Rational gave inaccurate results.
<syntaxhighlight lang="Nim">import std/[math, rationals, strutils]
 
type Fract = Rational[int64]
 
func engel(x: Fract): seq[Natural] =
## Return the Engel expansion of rational "x".
var u = x
while u.num != 0:
let a = ceil(u.den.float / u.num.float).toInt
result.add a
u = u * a - 1
 
func toRational(s: string): Fract =
## Convert the string representation of a real to a rational
## without using an intermediate float representation.
var num = 0i64
var den = 1i64
var i = 0
var c = s[0]
while c != '.':
num = 10 * num + ord(c) - ord('0')
inc i
c = s[i]
inc i
while i < s.len:
num = 10 * num + ord(s[i]) - ord('0')
den *= 10
inc i
result = num // den
 
 
for val in ["3.14159265358979", "2.71828182845904", "1.414213562373095"]:
let e = engel(val.toRational)
echo "Value: ", val
echo "Engel expansion: ", e.join(" ")
echo()
</syntaxhighlight>
 
{{out}}
<pre>Value: 3.14159265358979
Engel expansion: 1 1 1 8 8 17 19 300 1991 2768 4442 4830 10560 37132 107315 244141 651042 1953125
 
Value: 2.71828182845904
Engel expansion: 1 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 17 82 144 321 2289 9041 21083 474060 887785 976563 1953125
 
Value: 1.414213562373095
Engel expansion: 1 3 5 5 16 18 78 102 120 144 260 968 18531 46065 63005 65105 78125
</pre>
 
256

edits