Hatena::Groupcadr

わだばLisperになる このページをアンテナに追加 RSSフィード

2004 | 12 |
2005 | 01 | 02 | 07 | 10 | 11 |
2006 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2007 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2008 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2009 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2010 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2011 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 11 |

2008-11-12

メソッドコンビネーションでFizzBuzz (2.5)

| 00:24 | メソッドコンビネーションでFizzBuzz (2.5) - わだばLisperになる を含むブックマーク はてなブックマーク - メソッドコンビネーションでFizzBuzz (2.5) - わだばLisperになる

前回の例だと、メソッド修飾子での実行順番と、クラスの継承の順番が同じだったのでいまいちかなと思い、百個のクラスの継承関係をシャッフルしてみました。

これでも、1から順番に実行されます。

この場合、継承されている一連の集合体であることだけが必須で、実行の順番は修飾子で決定されクラス側が持つ優先順位ではないことが分かります。(継承は百個連続している必要あり)

(defgeneric fizzbuzz (cls)
  (:method-combination fizzbuzz))

;; 指定した範囲のランダムに混ざった数列のベクタを返す関数
(defun bingo (n)
  (loop :with nums := (make-array 0 :adjustable 'T :fill-pointer 'T)
        :for i :from 1 :to n :do (vector-push-extend i nums)
        :finally (return
                   (dotimes (j n nums)
                     (rotatef (aref nums j)
                              (aref nums (random n)))))))

;; クラスとメソッドを作成
(let ((nums (bingo 99)))
  (vector-push-extend 100 nums) ;; しっぽを100に
  (loop :for n :from 1
        :for b :across nums
        :and prev := (aref nums 99) :then b
        :do (eval
             `(progn
                (defclass ,#1=(make-roman-number-symbol b) 
                          ,(if (zerop (1- n)) () `(,(make-roman-number-symbol prev))) 
                          () )
                (defmethod fizzbuzz ,n ((cls ,#1#))
                  (format T ,@(typecase n
                                (fizzbuzz (list "Fizz Buzz~%"))
                                (buzz (list "Buzz~%"))
                                (fizz (list "Fizz~%"))
                                (otherwise (list "~A~%" n)))))))))

;; クラスの継承関係 (ランダムな一例)
;; The class is finalized; its class precedence list is:
  (|ONE HUNDRED| SEVENTY-SIX SIXTY-ONE NINETY-NINE EIGHT EIGHTY-NINE
   THIRTY-TWO FORTY-SEVEN FORTY-THREE FORTY-FIVE SIXTY-SIX NINETY-EIGHT
   FORTY-NINE EIGHTY TWENTY-FOUR SIXTY-NINE THIRTY-FOUR NINETY-FIVE SIXTY
   SIXTY-EIGHT FIFTY-SIX EIGHTY-SEVEN NINETY-SEVEN ONE NINETY-SIX
   FIFTY-FIVE FOURTEEN NINETY EIGHTEEN SIXTY-THREE TWENTY-SEVEN
   EIGHTY-FOUR FORTY-SIX THIRTY-ONE FIFTY-ONE FIFTY-FOUR NINETY-FOUR
   EIGHTY-EIGHT SIXTY-FIVE FORTY-FOUR SEVENTY-NINE SIXTY-FOUR FIFTY-SEVEN
   FORTY-EIGHT FIFTY-THREE EIGHTY-THREE THIRTY-EIGHT TWENTY-THREE
   THIRTY-THREE THIRTY-SEVEN FORTY FIFTY-EIGHT TEN FORTY-TWO EIGHTY-FIVE
   SEVENTY-SEVEN EIGHTY-TWO NINETY-THREE EIGHTY-ONE TWENTY-SIX
   SEVENTY-FIVE FIFTEEN TWENTY THREE NINETEEN FOUR TWO FIVE THIRTEEN NINE
   FIFTY-TWO SEVENTEEN THIRTY-NINE NINETY-ONE SIX FORTY-ONE SEVENTY-FOUR
   EIGHTY-SIX SIXTY-SEVEN SIXTY-TWO TWENTY-ONE SEVEN THIRTY-SIX
   SEVENTY-ONE ELEVEN SEVENTY THIRTY-FIVE THIRTY NINETY-TWO TWELVE
   SEVENTY-TWO TWENTY-TWO TWENTY-FIVE SEVENTY-THREE TWENTY-EIGHT SIXTEEN
   FIFTY-NINE SEVENTY-EIGHT FIFTY TWENTY-NINE STANDARD-OBJECT
   SB-PCL::SLOT-OBJECT T).

;; 実行
(fizzbuzz (make-instance '|ONE HUNDRED|))
;>>>
1
2
Fizz
4
Buzz
Fizz
7
8
Fizz
Buzz
11
Fizz
13
...