2007-06-05
■ [scheme] FizzBuzz一般化 (2)
動くまでに28分、リファクタリングに10分くらい。
「=」が数値の比較であることを忘れててだいぶはまった。(どの関数のエラーメッセージなのかも出してくれると嬉しいなぁ。)
[D:\proj]d:\prog\Gauche\bin\gosh ./fizzbuzzx.scm 1 100 3 Fizz 5 Buzz *** ERROR: real number required: #f Stack Trace: _______________________________________
回答はこんな感じで。
(use util.list) ;slices
(use srfi-1)    ;iota
(define (fizzbuzz from to mapping) ;mapping -> '((3 . "Fizz") (5 . "Buzz") ..)
  (define (integer->fizzbuzz i)
    (let1 mapped (map (lambda (pair) 
                        (let ((n   (car pair))
                              (str (cdr pair)))
                          (if (= (modulo i n) 0) str "")))
                      mapping)
          (if (every (cut string=? <> "") mapped)
            (number->string i)
            (apply string-append mapped))))
  (map integer->fizzbuzz (iota to from)))
(define (main args)
  (cond 
    ((< (length args) 2) 
     (print "usage: fizzbuzz.scm 1 100 3 Fizz 5 Buzz ..."))
    (else
      (let ((from    (string->number (cadr args)))
            (to      (string->number (caddr args)))
            (mapping (map (lambda (ls)
                            (cons (string->number (car ls)) (cadr ls)))
                          (slices (cdddr args) 2))))
        (for-each print (fizzbuzz from to mapping))))))
[ツッコミを入れる]