[topic] 分数の発見

schemeにはrationalizeという手続きがありますが、これは結果を一つしか返しません。そして、複数の結果が欲しい場合も稀にあります。

そこで、非負の実数aが一つ与えられたときに、以下の条件を満たす分数b/cをaに近い順に全て表示する手続きを考えてみてください。条件は、 1. 分数b/cよりaに近い分数d/cは存在しない 2. 分数b/cは既約 3. cは1桁の整数 です。

例をいくつかあげます(あってると思うけど...)。

a = 1.732051 12/7 7/4 16/9 5/3 9/5 3/2 2/1

a = 3.141593 22/7 25/8 19/6 28/9 16/5 13/4 3/1

a = 1920 / 1080 16/9 9/5 7/4 11/6 12/7 5/3 2/1

Posted feedbacks - Scheme

分数が組み込みなので簡単。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
(use srfi-1)

(define (sort-by xs cmp-fn key-fn)
  (map car (sort (map (lambda (x) (cons x (key-fn x))) xs)
                 (lambda (a b) (cmp-fn (cdr a) (cdr b))))))

(define (main args)
  (let ((n (string->number (cadr args))))
    (for-each
     print
     (sort-by (delete-duplicates
               (map (lambda (m)
                      (/ (inexact->exact (round (* m n))) m))
                    (iota 9 1)))
              <
              (lambda (x) (abs (- x n)))))))

Index

Feed

Other

Link

Pathtraq

loading...