SchemeでFizzBuzz

まずは普通に。ちなみにこれは電車の中でPocket Schemeを使って書きました。

#!/usr/bin/gosh

(define (fizzbuzz)
  (let loop ((i 1) (r ()))
    (if (> i 100)
        (reverse! r)
        (loop (+ i 1)
              (cons (cond ((zero? (modulo i 15)) "FizzBuzz")
                          ((zero? (modulo i 3)) "Fizz")
                          ((zero? (modulo i 5)) "Buzz")
                          (else i))
                    r)))))

(for-each (lambda (s) (display s) (newline)) (fizzbuzz))

call/ccを使って無理矢理Schemeらしさを出してみる。

#!/usr/bin/gosh

(define (make-generator proc)
  (let ((next #f) (return #f))
    (lambda ()
      (call/cc (lambda (break)
                 (set! return break)
                 (if (not next)
                     (proc (lambda arg
                             (call/cc (lambda (cc)
                                        (set! next cc)
                                        (apply return arg)))))
                     (next)))))))

(define fizzbuzz
  (make-generator
   (lambda (yield)
     (let loop ((i 1))
       (yield (cond ((zero? (modulo i 15)) "FizzBuzz")
                    ((zero? (modulo i 3)) "Fizz")
                    ((zero? (modulo i 5)) "Buzz")
                    (else i)))
       (loop (+ i 1))))))

(let loop ((i 0))
  (if (< i 100)
      (begin (display (fizzbuzz))
             (newline)
             (loop (+ i 1)))))

make-generatorの実装はScheme:generatorとdoとwhileで公開されているものを使いました。

いろんな言語でFizzBuzz

Pythonで:

#!/usr/bin/python

def fizzbuzz():
  for i in range(1, 101):
      if i % 15 == 0:
          print "FizzBuzz"
      elif i % 3 == 0:
          print "Fizz"
      elif i % 5 == 0:
          print "Buzz"
      else:
          print i

fizzbuzz()

Pythonではforやifに対応する閉じ括弧がないのと行末のコロンが特徴的です。

Rubyで:

#!/usr/bin/ruby

def fizzbuzz
  (1..100).each do |i|
    if i % 15 == 0
      puts "FizzBuzz"
    elsif i % 3 == 0
      puts "Fizz"
    elsif i % 5 == 0
      puts "Buzz"
    else
      puts i
    end
  end
end

fizzbuzz()

Rubyでは関数定義の括弧は省略可能です。最後のend end endが実に存在感があります。

Emacs Lispで:

(defun fizzbuzz ()
  (let ((i 1))
    (while (<= i 100)
      (princ (cond ((= (% i 15) 0) "FizzBuzz")
                   ((= (% i 3) 0) "Fizz")
                   ((= (% i 5) 0) "Buzz")
                   (t (int-to-string i))))
      (princ "\n")
      (setq i (1+ i)))))

実行するには、emacs --batch -l fizzbuzz.el -f fizzbuzz のようにします。

JavaScriptで:

<html>
<head>
<script type="text/javascript">
function fizzbuzz() {
    for (var i = 1; i <= 100; i++) {
        if (i % 15 == 0) {
            document.write("FizzBuzz<br/>");
        }
        else if (i % 3 == 0) {
            document.write("Fizz<br/>");
        }
        else if (i % 5 == 0) {
            document.write("Buzz<br/>");
        }
        else {
            document.write(i + "<br/>")
        }
    }
}
</script>
</head>
<body>
<script type="text/javascript">
fizzbuzz()
</script>
</body>
</html>

あとはHaskellでもやりたかったけど時間切れでした。