ANSI Common Lisp

と言う訳で、D10をX個振ったときの全パターンを返してくれる関数。など。

;;;; リストの加算を求める。+と一緒とか言うツッコミはナシ
(defun sum (lst)
  (if (null lst)
	  0
	(+ (car lst)
	   (sum (cdr lst)))))
;;;; リストの長さを求める。きっと標準にもあるんだろうけど。
(defun len (lst)
  (if (null lst)
	  0
	(+ 1
	   (len (cdr lst)))))
;;;; リストの加算平均を求める。きっと標準(ry
(defun avr (lst)
  (/ (sum lst) (len lst)))

;;;;なぜかinlineドキュメントになっている
(defun sum-list (lstlst)
  "listのlistを渡すと、中のlistの合計のlistを返してくれる"
  "'((0 0) (0 1) (1 0) (1 1))=>'(0 1 1 2)"
  (if (null lstlst)
	  nil
	(cons (sum (car lstlst))
		  (sum-list (cdr lstlst)))))

;;;; fun(関数を指定する)を初回の引数(argで指定される)でn回呼び出してくれる
;;;; funの返り値は二回目以降の引数になる。
(defun do-num (fun n arg)
;  (format t "fun:~A n:~A arg:~A ~%" fun n arg)
  (cond ((<= n 0) nil)
		((= n 1) (funcall fun arg))
		(t (funcall fun (do-num fun (- n 1) arg)))))

;;;; と言う訳で、D10をn個(実はn+1個)振ったときの全パターンを返す関数。
(defun dice10-list (n)
  (do-num
   (lambda (lstlst)
	 (dice-combo lstlst (dice-n-m 1 10)))
   n
   (listlist (dice-n-m 1 10)))
  )

ちなみにdice10-list、引数4だか5だかまでしか正常に動かない。
それ以上の引数を指定すると、stack over flowなどで壊れる。
まあ、メモリ上に何十メガバイト以上の領域が必要になっていそうなので、わからなくもない。


…と言うことは、全パターンを調べ尽くす以外の方法で考えなきゃいけないのは間違いないらしい。
まあ、そんな気はしてましたが、Common Lispに慣れるのが目的の半分位を占めていたので、まあいい感じ。