このディレクトリの索引
http://hibari.2ch.net/test/read.cgi/tech/1294061094/532
#  2] 問題文(含コード&リンク):「お菓子などのおまけを全種集めるためには平均して何個お菓子を購入すればよいか」を調べるプログラムを作りなさい。また処理概要の説明をしなさい。  
#  
#  たとえば、全部で10種類おまけがあったとして、すでに所持2種類ならば、非所持は8種類。
#  ⇒1から8の乱数を発生させて1から8が全部集まったら、集まるまでに何度乱数発生させたかを記憶。
#  ←これを1万回ほど繰り返して、平均して何度購入すればよいかを求める。
#  という流れで作ろうと思うのですが、この例で1から8まで集まったことをどうやって確認するのかわからず、
#  お手上げ状態です。どなたかお力添えいただければ幸いです。


おまけが出る確率(1,0.08).
おまけが出る確率(2,0.08).
おまけが出る確率(3,0.3).
おまけが出る確率(4,1.0).
おまけが出る確率(5,0.5).
おまけが出る確率(6,0.2).
おまけが出る確率(7,0.1).
おまけが出る確率(8,0.1).
おまけが出る確率(9,0.3).
おまけが出る確率(10,0.15).

おまけ乱数表の生成(LL) :-
        findall(L,(
                    for(1,_菓子番号,10),
                    おまけが出る確率(_菓子番号,_確率),
                    N is truncate(100 * _確率),
                    length(Ln,N),
                    'N個分の乱数を確保'(N,[],L)),
                LL).

'N個分の乱数を確保'(N,L,L) :-
        length(L,N),!.
'N個分の乱数を確保'(N,L1,L) :-
        X is random mod 100,
        \+(append(_,[X|_],L1)),
        'N個分の乱数を確保'(N,[X|L1],L),!.
'N個分の乱数を確保'(N,L1,L) :-
        'N個分の乱数を確保'(N,L1,L),!.

'お菓子などのおまけを全種集めるためには平均して何個お菓子を購入すればよいか」を調べる'(_すべての菓子のおまけが得られる平均回数) :-
        おまけ乱数表の生成(LL),
        findavg(Count,(
                    for(1,_,1000),
                    すべての菓子のおまけが得られるまで(LL,[],0,Count)),
                _すべての菓子のおまけが得られる平均回数).


すべての菓子のおまけが得られるまで(LL,L1,Count,Count) :-
        length(L1,10),!.
すべての菓子のおまけが得られるまで(LL,L1,Count1,Count) :-
        R is random mod 100,
        findall(N,(
                    for(1,N,10),
                    \+(append(_,[N|_],L1)),
                    list_nth(N,LL,L),
                    append(_,[R|_],L)),
                L2),
        append(L1,L2,L3),
        Count2 is Count1 + 1,
すべての菓子のおまけが得られるまで(LL,L3,Count2,Count).