LISPUSER

LISPMEMOLisp isn't a language, it's a building material. -- Alan Kay

(top)  (memo)  (rss)

Prolog で FizzBuzz (おまけ: AllegroProlog)

http://www.aoky.net/articles/jeff_atwood/why_cant_programmers_program.htm

FizzBuzz 問題というのが流行していたらしい。プログラマなら一瞬でかけるはずー、と。 Lisp なら二分以内に…。

(defun fizzbuzz ()
   (loop for i from 1 to 100
         do (format t "~A~%"
              (cond ((= (mod i 15) 0) "FizzBuzz")
                    ((= (mod i 3) 0) "Fizz")
                    ((= (mod i 5) 0) "Buzz")
                    (t i)))))

format の t を忘れて結構ギリギリだった…。

choice(N, X) :- N mod 15 =:= 0, X = 'FizzBuzz', !.
choice(N, X) :- N mod 3 =:= 0, X = 'Fizz', !.
choice(N, X) :- N mod 5 =:= 0, X = 'Buzz', !.
choice(N, N).

fizzbuzz(a) :-
            between(1, 100, N),
            choice(N, X),
            write(X), nl,
            fail.

うーん。カットが見えないほうが好きなんだよなぁ。

fizzbuzz() :-
            between(1, 100, N),
            ( N mod 15 =:= 0 -> X = 'FizzBuzz';
              N mod 3 =:= 0  -> X = 'Fizz';
              N mod 5 =:= 0  -> X = 'Buzz';
              X = N ),
            write(X), nl,
            fail.

こうかなー。再帰させたらこうか。

fizzbuzz(N) :-
            N =< 100,
            ( N mod 15 =:= 0 -> X = 'FizzBuzz';
              N mod 3 =:= 0  -> X = 'Fizz';
              N mod 5 =:= 0  -> X = 'Buzz';
              X = N ),
            write(X), nl,
               M is N + 1,
            fizzbuzz(M).

で、なんで Prolog かというと、要するに Allegro Prolog のサンプルを示したかったからです。

以下 AllegroProlog の例。

(in-package :cl-user)
(use-package :prolog)

(<-- (between ?L ?H ?L) (lispp* (<= ?L ?H)))
(<-  (between ?L ?H ?V)
     (lispp* (< ?L ?H))
     (is ?L1 (+ ?L 1))
     (between ?L1 ?H ?V))

(<-- (choice ?N ?X) (lispp* (= (mod ?N 15) 0)) (is ?X "FizzBuzz") (!))
(<-  (choice ?N ?X) (lispp* (= (mod ?N 3) 0))  (is ?X "Fizz") (!))
(<-  (choice ?N ?X) (lispp* (= (mod ?N 5) 0))  (is ?X "Buzz") (!))
(<-  (choice ?N ?N))

(<-- (fizzbuzz ?N)
     (lispp* (<= ?N 100))
     (choice ?N ?X)
     (lisp* (format t "~A~%" ?X))
     (is ?M (+ ?N 1))
     (fizzbuzz ?M))

(<-- (fizzbuzz-2)
     (between 1 100 ?N)
     (choice ?N ?X)
     (lisp* (format t "~A~%" ?X))
     (fail))

(defun demo1 ()
  (?- (fizzbuzz 1)))

(defun demo2 ()
  (?- (fizzbuzz-2)))

(defun demo3 ()
  (loop for i from 1 to 100
        do (prolog
             (lisp ?N i)
             (choice ?N ?X)
             (lisp (format t "~A~%" ?X)))))

まぁ、つっても AllegroProlog は明かに Prolog とは違う路線を目指しているんですが。

posted: 2007/05/13 22:36 | permanent link to this entry | Tags: MISC

(top)  (memo)  (rss)