2×2 のマス目の左上からスタートした場合, 引き返しなしで右下にいくルートは 6 つある.
では, 20×20 のマス目ではいくつのルートがあるか.
では, 20×20 のマス目ではいくつのルートがあるか.
よくある数え上げの問題で, 経路の数は40C20となります.
組合せの数を求める手続きがあると答えは求まります.
- 分母と分子に現れる数のリストを作る.
- それぞれの数を素因数分解する.
- 分母に現れる数から分子に現れる数を取り除く.
- 分母に残った数の積を求める.
組合せの数を求める手続きの定義は次のようになります.
(require srfi/1)
(define (square n) (* n n))
(define (divides? a b)
(= (remainder b a) 0))
(define (find-divisor n test-divisor)
(cond ((> (square test-divisor) n) n)
((divides? test-divisor n) test-divisor)
(else (find-divisor n (+ test-divisor 1)))))
(define (smallest-divisor n)
(find-divisor n 2))
(define (prime-factorization n)
(let ((a (smallest-divisor n)))
(if (= a n)
(list n)
(cons a (prime-factorization (/ n a))))))
(define (comb i j)
(define (pf items)
(sort (apply append (map prime-factorization items))
<))
(define (remove-one lst obj)
(cond ((null? lst) ())
((equal? (car lst) obj) (cdr lst))
(else (cons (car lst) (remove-one (cdr lst) obj)))))
(define (diff a b)
(cond ((null? b) a)
((member (car b) a) (diff (remove-one a (car b)) (cdr b)))
(else (error "diff"))))
(apply * (diff (pf (iota j i -1))
(pf (iota (- j 1) 2)))))
計算してみます.
ようこそ DrRacket, バージョン 5.3.3 [3m]. 言語: Pretty Big; memory limit: 512 MB. > (comb 40 20) 137846528820 >
0 件のコメント:
コメントを投稿