2011/04/06

カプレカ数

ザックリしてますが。
;; 1. 2乗して前の部分と後ろの部分に分けて和を取ったとき、元の値に等しくなるもの
;; 2. 桁を並べ替えて最大にしたものから最小にしたものの差を取ったとき、元の値に等しくなるもの

(define (Kaprekar1? num)
  (let* ((dbl (expt num 2))
         (str (number->string dbl))
         (len (string-length str))
         (prelen (div len 2)))
    (let* ((pre (string->number (substring str 0 prelen)))
           (suf (string->number (substring str prelen len))))
      (rlet1 r (= num (+ pre suf))
             (format #t "base: ~a, double: ~a, exp: ~a + ~a = ~a -> ~a\n"
                     num dbl pre suf (+ pre suf) r)))))


(map Kaprekar1? '(9 45 55 99 297 703 999 2223 2728 4950 5050 7272 7777 9999 17344 22222 38962
                    77778 82656 95121 99999 142857 148149 181819 187110 208495 318682 329967
                    351352 356643 390313 461539 466830 499500))
;; -> (#t #t #t #t #t #t #t #t #t #t #t #t #t #t #t #t #f #t #t #t #t #t #t #t #t #t #t #t #t #t #t #t #t #t)



(define (Kaprekar2? num)
  (let* ((ls (string->list (x->string num)))
         (min (string->number (list->string (sort ls char<?))))
         (max (string->number (list->string (sort ls char>?)))))
    (rlet1 r (cons (- max min)
                   (= num (- max min)))
           ;; (format #t "base: ~a, exp: ~a - ~a = ~a -> ~a\n"
           ;;         num min max (- max min) r)
           )))

(use srfi-1 :only (iota filter))
(filter (pa$ cdr)
        (map Kaprekar2? (iota 10000)))
;; -> ((0 . #t) (495 . #t) (6174 . #t) (549945 . #t) (631764 . #t))

Scheme手習い

0 件のコメント:

コメントを投稿