Comment detail

分数を小数に展開 (Nested Flatten)
schemeですけど、gaucheでしか動かないと思います。エレガントではないので申し訳ないです。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
(use text.tree)

(define (div a b)
  (tree->string `("0." ,(div2 (* a 10) b (make-hash-table 'eqv?)))))

(define (div2 a b h)
  (cond ((hash-table-get h a #f)
         => (lambda (x)
              (set-car! x `("{" ,(car x)))
              `("}")))
        (else
          (call-with-values
            (cut quotient&remainder a b)
            (lambda (q r)
              (if (zero? r) `(,q)
                  (let1 p (cons q #f)
                    (hash-table-put! h a p)
                    (set-cdr! p (div2 (* r 10) b h))
                    p)))))))

(print (div 3 8))
(print (div 3 14))
2147483645 / 2147483647 でOut of Memoryが出ちゃいました。 スタックの事もあるし、考え直します。
副作用無し版。gaucheです。 検索が遅いので、桁が多いと遅くなります。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
(use text.tree)
(use srfi-1)
(use srfi-11)
(use gauche.sequence)

(define (div3 a b)
  (tree->string (cons "0."
    (let loop ((a (* 10 a)) (b b) (r ()) (l ()))
      (cond ((find-index (pa$ = a) l) =>
             (lambda (m)
               (reverse
                 (call-with-values (cut split-at r (+ m 1))
                                   (cut append '("}") <> '("{") <>)))))
            ((< a b) (loop (* a 10) b (cons 0 r) (cons a l)))
            (else (let-values (((quo rem) (quotient&remainder a b)))
                    (if (zero? rem)
                      (reverse (cons quo r))
                      (loop (* rem 10) b (cons quo r) (cons a l))))))))))

Index

Feed

Other

Link

Pathtraq

loading...