;;;お題
;;; 10進数n桁の自然数について
;;; 2からはじめてn番目の素数をpnとし
;;; 左端から数えてn番目の数字をdnとする時
;;; f(x)=p1^d1 * p2^d2 * p3^d3 ....* pn^dn
;;; とする.
;;; f(x)= xとなるxを求めよ
;;;解答例
;;;データ:10個の素数リスト
(define primes '(2 3 5 7 11 13 17 19 23 29))
;;;主関数
;;;(hoo s e) s:start e:end
;;;sからeまでの自然数を調べ該当する最初の数を得る
;(hoo 1 9999999999) -> 81312000
(define hoo
(lambda (s e)
(cond
((> s e) #f)
((= s (foo s)) s)
(else (hoo (1+ s) e)))))
;;;f(x)を求める
(define foo
(lambda (n)
(let ((l (number-order n)))
(foo-help
(left-list (car l) primes (lambda (x) x))
(second l)
(lambda (x) x)))))
(define foo-help
(lambda (ps ds col)
(cond
((null? ps) (col 1))
(else
(foo-help
(cdr ps) (cdr ds)
(lambda (x)
(col (* (expt (car ps) (car ds)) x))))))))
;;;補助関数
;;;整数の桁数と数字リストを得る
;;;(number-order 3892)
;;; -> (4 (3 8 9 2))
(define number-order
(lambda (n)
(cond
((zero? n) 1)
((> n 0)
(number-order-help
n (lambda (n lst)
(list n (reverse lst)))))
(else
(number-order-help
(- n) (lambda (n lst)
(list n (reverse lst))))))))
(define number-order-help
(lambda (n col)
(if (<= n 0) (col 0 '())
(number-order-help
(div n 10)
(lambda (x y)
(col (1+ x)
(cons (modulo n 10) y)))))))
;;;リストの先頭からn個のリストを得る
;;;(left-list 3 '(a b c d e) (lambda (x) x))
;;; -> (a b c)
(define left-list
(lambda (n l col)
(cond
((zero? n) (col '()))
(else
(left-list
(1- n)
(cdr l)
(lambda (x)
(col (cons (car l) x))))))))
;;;適用
;;;時間がかかりすぎる
;(hoo 1 999999999999)
(hoo 81300000 99999999999)
81312000