How to resolve the algorithm Continued fraction/Arithmetic/Construct from rational number step by step in the Scheme programming language

Published on 12 May 2024 09:40 PM

How to resolve the algorithm Continued fraction/Arithmetic/Construct from rational number step by step in the Scheme programming language

Table of Contents

Problem Statement

The purpose of this task is to write a function

r 2 c f

(

i n t

{\displaystyle {\mathit {r2cf}}(\mathrm {int} }

N

1

,

i n t

{\displaystyle N_{1},\mathrm {int} }

N

2

)

{\displaystyle N_{2})}

, or

r 2 c f

(

F r a c t i o n

{\displaystyle {\mathit {r2cf}}(\mathrm {Fraction} }

N )

{\displaystyle N)}

, which will output a continued fraction assuming: The function should output its results one digit at a time each time it is called, in a manner sometimes described as lazy evaluation. To achieve this it must determine: the integer part; and remainder part, of

N

1

{\displaystyle N_{1}}

divided by

N

2

{\displaystyle N_{2}}

. It then sets

N

1

{\displaystyle N_{1}}

to

N

2

{\displaystyle N_{2}}

and

N

2

{\displaystyle N_{2}}

to the determined remainder part. It then outputs the determined integer part. It does this until

a b s

(

N

2

)

{\displaystyle \mathrm {abs} (N_{2})}

is zero. Demonstrate the function by outputing the continued fraction for:

2

{\displaystyle {\sqrt {2}}}

should approach

[ 1 ; 2 , 2 , 2 , 2 , … ]

{\displaystyle [1;2,2,2,2,\ldots ]}

try ever closer rational approximations until boredom gets the better of you: Try : Observe how this rational number behaves differently to

2

{\displaystyle {\sqrt {2}}}

and convince yourself that, in the same way as

3.7

{\displaystyle 3.7}

may be represented as

3.70

{\displaystyle 3.70}

when an extra decimal place is required,

[ 3 ; 7 ]

{\displaystyle [3;7]}

may be represented as

[ 3 ; 7 , ∞ ]

{\displaystyle [3;7,\infty ]}

when an extra term is required.

Let's start with the solution:

Step by Step solution about How to resolve the algorithm Continued fraction/Arithmetic/Construct from rational number step by step in the Scheme programming language

Source code in the scheme programming language

; Create a terminating Continued Fraction generator for the given rational number.
; Returns one term per call; returns #f when no more terms remaining.
(define make-continued-fraction-gen
  (lambda (rat)
    (let ((num (numerator rat)) (den (denominator rat)))
      (lambda ()
        (if (= den 0)
          #f
          (let ((ret (quotient num den))
                (rem (modulo num den)))
            (set! num den)
            (set! den rem)
            ret))))))

; Return the continued fraction representation of a rational number as a string.
(define rat->cf-string
  (lambda (rat)
    (let* ((cf (make-continued-fraction-gen rat))
           (str (string-append "[" (format "~a" (cf))))
           (sep ";"))
      (let loop ((term (cf)))
        (when term
          (set! str (string-append str (format "~a ~a" sep term)))
          (set! sep ",")
          (loop (cf))))
      (string-append str "]"))))

; Return the continued fraction representation of a rational number as a list of terms.
(define rat->cf-list
  (lambda (rat)
    (let ((cf (make-continued-fraction-gen rat))
          (lst '()))
      (let loop ((term (cf)))
        (when term
          (set! lst (append lst (list term)))
          (loop (cf))))
      lst)))


(printf "~%Basic examples:~%")
(for-each
  (lambda (rat)
    (printf "~a = ~a~%" rat (rat->cf-string rat))
    (printf "~a : ~a~%" rat (rat->cf-list rat)))
  '(1/2 3 23/8 13/11 22/7 -151/77 0))

(printf "~%Root2 approximations:~%")
(for-each
  (lambda (rat)
    (printf "~a = ~a~%" rat (rat->cf-string rat))
    (printf "~a : ~a~%" rat (rat->cf-list rat)))
  '(14142/10000 141421/100000 1414214/1000000 14142136/10000000 141421356237/100000000000))

(printf "~%Pi approximations:~%")
(for-each
  (lambda (rat)
    (printf "~a = ~a~%" rat (rat->cf-string rat))
    (printf "~a : ~a~%" rat (rat->cf-list rat)))
  '(31/10 314/100 3142/1000 31428/10000 314285/100000 3142857/1000000
    31428571/10000000 314285714/100000000 31415926535898/10000000000000))


(cond-expand
  (r7rs)
  (chicken (import (r7rs))))

(import (scheme base))
(import (scheme case-lambda))
(import (scheme write))
(import (srfi 41))

;;;-------------------------------------------------------------------

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; The entirety of r2cf, two different ways ;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;; r2cf-VERSION1 works with integers. (Any floating-point number is
;; first converted to exact rational.)
(define (r2cf-VERSION1 fraction)
  (define-stream (recurs n d)
    (if (zero? d)
        stream-null
        (let-values (((q r) (floor/ n d)))
          (stream-cons q (recurs d r)))))
  (let ((fraction (exact fraction)))
    (recurs (numerator fraction) (denominator fraction))))

;; r2cf-VERSION2 works directly with fractions. (Any floating-point
;; number is first converted to exact rational.)
(define (r2cf-VERSION2 fraction)
  (define-stream (recurs fraction)
    (let* ((quotient (floor fraction))
           (remainder (- fraction quotient)))
      (stream-cons quotient (if (zero? remainder)
                                stream-null
                                (recurs (/ remainder))))))
  (recurs (exact fraction)))

;;(define r2cf r2cf-VERSION1)
(define r2cf r2cf-VERSION2)

;;;-------------------------------------------------------------------

(define *max-terms* (make-parameter 20))

(define cf2string
  (case-lambda
    ((cf) (cf2string cf (*max-terms*)))
    ((cf max-terms)
     (let loop ((i 0)
                (s "[")
                (strm cf))
       (if (stream-null? strm)
           (string-append s "]")
           (let ((term (stream-car strm))
                 (tail (stream-cdr strm)))
             (if (= i max-terms)
                 (string-append s ",...]")
                 (let ((separator (case i
                                    ((0) "")
                                    ((1) ";")
                                    (else ",")))
                       (term-str (number->string term)))
                   (loop (+ i 1)
                         (string-append s separator term-str)
                         tail)))))))))

(define (show fraction)
  (parameterize ((*max-terms* 1000))
    (display fraction)
    (display " => ")
    (display (cf2string (r2cf fraction)))
    (newline)))

(show 1/2)
(show 3)
(show 23/8)
(show 13/11)
(show 22/11)
(show -151/77)
(show 14142/10000)
(show 141421/100000)
(show 1414214/1000000)
(show 14142136/10000000)
(show 1414213562373095049/1000000000000000000)

;; Decimal expansion of sqrt(2): see https://oeis.org/A002193
(show 141421356237309504880168872420969807856967187537694807317667973799073247846210703885038753432764157/100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000)

(show 31/10)
(show 314/100)
(show 3142/1000)
(show 31428/10000)
(show 314285/100000)
(show 3142857/1000000)
(show 31428571/10000000)
(show 314285714/100000000)
(show 3142857142857143/1000000000000000)

;; Decimal expansion of pi: see https://oeis.org/A000796
(show 314159265358979323846264338327950288419716939937510582097494459230781640628620899862803482534211706798214/100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000)


(cond-expand
  (r7rs)
  (chicken (import (r7rs))))

(import (scheme base))
(import (scheme write))

;;;-------------------------------------------------------------------

(define (r2cf fraction consumer)
  (let* ((fraction (exact fraction)))
    (let loop ((n (numerator fraction))
               (d (denominator fraction))
               (consumer consumer))
      (if (zero? d)
          (call-with-current-continuation
           (lambda (kont) (consumer #f kont)))
          (let-values (((q r) (floor/ n d)))
            (loop d r (call-with-current-continuation
                       (lambda (kont) (consumer q kont)))))))))

(define (display-cf term producer)
  (display "[")
  (let loop ((term term)
             (producer producer)
             (separator ""))
    (if term
        (begin
          (display separator)
          (display term)
          (let-values (((term producer)
                        (call-with-current-continuation producer)))
            (loop term producer
                  (if (string=? separator "") ";" ","))))
        (begin
          (display "]")
          (call-with-current-continuation producer)))))

;;;-------------------------------------------------------------------

(define (show fraction)
  (display fraction)
  (display " => ")
  (r2cf fraction display-cf)
  (newline))

(show 1/2)
(show 3)
(show 23/8)
(show 13/11)
(show 22/11)
(show -151/77)
(show 14142/10000)
(show 141421/100000)
(show 1414214/1000000)
(show 14142136/10000000)
(show 1414213562373095049/1000000000000000000)

;; Decimal expansion of sqrt(2): see https://oeis.org/A002193
(show 141421356237309504880168872420969807856967187537694807317667973799073247846210703885038753432764157/100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000)

(show 31/10)
(show 314/100)
(show 3142/1000)
(show 31428/10000)
(show 314285/100000)
(show 3142857/1000000)
(show 31428571/10000000)
(show 314285714/100000000)
(show 3142857142857143/1000000000000000)

;; Decimal expansion of pi: see https://oeis.org/A000796
(show 314159265358979323846264338327950288419716939937510582097494459230781640628620899862803482534211706798214/100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000)


  

You may also check:How to resolve the algorithm Character codes step by step in the R programming language
You may also check:How to resolve the algorithm Read a file character by character/UTF8 step by step in the Raku programming language
You may also check:How to resolve the algorithm Text processing/2 step by step in the REXX programming language
You may also check:How to resolve the algorithm Rename a file step by step in the NewLISP programming language
You may also check:How to resolve the algorithm XML/Input step by step in the Python programming language