Continued fraction/Arithmetic/Construct from rational number: Difference between revisions

Content added Content deleted
m (→‎{{header|Haskell}}: add stub section for Go)
(→‎{{header|Go}}: Add Go solution)
Line 568: Line 568:


=={{header|Go}}==
=={{header|Go}}==
<lang Go>package main

import (
"fmt"
"math"
"strings"
)

type NextFn func() (term int64, more bool)
type ContinuedFraction func() NextFn

func (cf ContinuedFraction) String() string {
var buf strings.Builder
next := cf()
t, more := next()
fmt.Fprintf(&buf, "[%d", t)
sep := "; "
const maxTerms = 20
for n := 0; more; n++ {
if n > maxTerms {
fmt.Fprint(&buf, ", ...")
break
}
t, more = next()
fmt.Fprintf(&buf, "%s%d", sep, t)
sep = ", "
}
fmt.Fprint(&buf, "]")
return buf.String()
}

type Rat struct {
N, D int64
}

func (r Rat) String() string {
return fmt.Sprintf("%d/%d", r.N, r.D)
}

func (r Rat) AsContinuedFraction() ContinuedFraction { return r.CFTerms }
func (r Rat) CFTerms() NextFn {
n, d := r.N, r.D
return func() (int64, bool) {
q := n / d
n, d = d, n-q*d
return q, d != 0
}
}

func Phi() NextFn {
return func() (int64, bool) { return 1, true }
}

func Sqrt2() NextFn {
first := true
return func() (int64, bool) {
if first {
first = false
return 1, true
}
return 2, true
}
}

// Rosetta Code task explicitly asked for this function.
// We'll just use the types above instead.
func r2cf(n1, n2 int64) ContinuedFraction { return Rat{n1, n2}.CFTerms }

func main() {
cases := [...]Rat{
{1, 2},
{3, 1},
{23, 8},
{13, 11},
{22, 7},
{-151, 77},
}
for _, r := range cases {
fmt.Printf("%7s = %s\n", r, r.AsContinuedFraction())
}

for _, tc := range [...]struct {
name string
approx float64
cf ContinuedFraction
}{
{"√2", math.Sqrt2, Sqrt2},
{"π", math.Pi, nil},
{"ϕ", math.Phi, Phi},
} {
fmt.Printf("\nApproximating %s ≅ %v:\n", tc.name, tc.approx)
for d := int64(10); d < 1e12; d *= 10 {
n := int64(math.Floor(tc.approx * float64(d)))
r := Rat{n, d}
fmt.Println(r, "=", r.AsContinuedFraction())
}
if tc.cf != nil {
fmt.Println("Actual:", tc.cf)
}
}
}</lang>
{{out}}
<pre>
1/2 = [0; 2]
3/1 = [3]
23/8 = [2; 1, 7]
13/11 = [1; 5, 2]
22/7 = [3; 7]
-151/77 = [-1; -1, -24, -1, -2]

Approximating √2 ≅ 1.4142135623730951:
14/10 = [1; 2, 2]
141/100 = [1; 2, 2, 3, 1, 1, 2]
1414/1000 = [1; 2, 2, 2, 2, 5, 3]
14142/10000 = [1; 2, 2, 2, 2, 2, 1, 1, 29]
141421/100000 = [1; 2, 2, 2, 2, 2, 2, 3, 1, 1, 3, 1, 7, 2]
1414213/1000000 = [1; 2, 2, 2, 2, 2, 2, 2, 1, 1, 4, 1, 1, 1, 1, 1, 2, 1, 6]
14142135/10000000 = [1; 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 594]
141421356/100000000 = [1; 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 4, 1, 1, 2, 6, 8]
1414213562/1000000000 = [1; 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 14, 1, 238, 1, 3]
14142135623/10000000000 = [1; 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 1, 3, 8, 9, 1, 20, 1, ...]
141421356237/100000000000 = [1; 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 1, 4, 1, 2, 1, 63, ...]
Actual: [1; 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, ...]

Approximating π ≅ 3.141592653589793:
31/10 = [3; 10]
314/100 = [3; 7, 7]
3141/1000 = [3; 7, 10, 1, 5, 2]
31415/10000 = [3; 7, 14, 1, 8, 2]
314159/100000 = [3; 7, 15, 1, 25, 1, 7, 4]
3141592/1000000 = [3; 7, 15, 1, 84, 6, 2]
31415926/10000000 = [3; 7, 15, 1, 243, 1, 1, 9, 1, 1, 4]
314159265/100000000 = [3; 7, 15, 1, 288, 1, 2, 1, 3, 1, 7, 4]
3141592653/1000000000 = [3; 7, 15, 1, 291, 1, 75, 1, 2, 9, 1, 3, 3]
31415926535/10000000000 = [3; 7, 15, 1, 292, 1, 1, 6, 2, 13, 3, 1, 12, 3]
314159265358/100000000000 = [3; 7, 15, 1, 292, 1, 1, 1, 1, 1, 12, 1, 1, 4, 1, 1, 4, 1, 9, 1, 11]

Approximating ϕ ≅ 1.618033988749895:
16/10 = [1; 1, 1, 2]
161/100 = [1; 1, 1, 1, 1, 3, 2, 2]
1618/1000 = [1; 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 5]
16180/10000 = [1; 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 5]
161803/100000 = [1; 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 2, 1, 1, 6, 2]
1618033/1000000 = [1; 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 11, 1, 129]
16180339/10000000 = [1; 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 10, 15, 1, ...]
161803398/100000000 = [1; 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 3, ...]
1618033988/1000000000 = [1; 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, ...]
16180339887/10000000000 = [1; 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, ...]
161803398874/100000000000 = [1; 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, ...]
Actual: [1; 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, ...]
</pre>


=={{header|Haskell}}==
=={{header|Haskell}}==