このディレクトリの索引

http://pc12.2ch.net/test/read.cgi/tech/1250204272/926
# 以前回答いただいた課題の発展課題です。よろしくお願いします。
# 以前の回答は>>841にあります。以前の問題文は>>770を参照してください。
# ただし>>770の分類には全角英数が抜けています。
# [1] 授業単元:プログラミング演習2
# [2] 問題文(含コード&リンク):
# 前回の課題の分類の結果「半角英数:XX字、半角カナ:XX字・・・」
# という結果が得られたとき、その結果のファイルを読み込み
# 各分類からその結果の比率に合わせてランダムに文字列を出力する
# プログラムを作成せよ。出力する文字数は解析に用いた文字の合計である。
# (例えば半角英数が全体の60%だった場合、出力される文字列の中にランダムに半角英数文字が60%の割合で含まれることになる)
# 分類は以下の通りとする。
# 1.半角英数
# 2.半角カナ
# 3.半角記号
# 4.全角英数
# 5.全角かな
# 6.全角記号
# 7.漢字

サンプルの文字分類('半角英数',9234).
サンプルの文字分類('全角漢字',1061).
サンプルの文字分類('全角記号',210).
サンプルの文字分類('全角カナ',687).
サンプルの文字分類('全角かな',705).

t778(_生成文字数,_発生文) :-
    findall([_分類,_文字数],サンプルの文字分類(_分類,_文字数),_文字分類ならび),
    t778_1(_文字分類ならび,_生成文字数,_発生文).

t778_1(_文字分類ならび,_生成文字数,_発生文) :-
    テキスト文字総数(_文字分類ならび,_テキスト総文字数),
    乗算合同法によってM個の正規分布ならびを得る(_生成文字数,_正規分布1),
    乗算合同法によってM個の正規分布ならびを得る(_生成文字数,_正規分布2),
    連続文字番号の割り当て(0,_文字分類ならび,_仮文字番号ならび),
    t778(_正規分布1,_正規分布2,_仮文字番号ならび,_発生文字コードならび),
    atom_codes(_発生文,_発生文字コードならび).

t778_2([],[],_,_,[]) :- !.
t778_2([V1|R1],[V2|R2],_テキスト総文字数,_仮文字番号ならび,[_生成文字コード|R3]) :-
    member([_分類,_仮文字番号下限,_仮文字番号上限],_仮文字番号ならび),
    _テキスト総文字数 * V1 >= _仮文字番号下限,
    _テキスト総文字数 * V1 =< _仮文字番号上限,
    一文字生成する(_分類,V2,_生成文字コード),
    t778_2(R1,R2,_テキスト総文字数,_仮文字番号ならび,R3).

一文字生成する(_分類,V,_生成文字コード) :-
    sub_atom(_分類,0,2,_,全角),
    eucコード分類(_分類,C1,C2),
    _生成文字コード is truncate((((C2 - C1 + 2) // 2) * V) * 2 + C1.
一文字生成する(_分類,V,_生成文字コード) :-
    sub_atom(_分類,0,2,_,半角),
    eucコード分類(_分類,C1,C2),
    _生成文字コード is truncate(((C2 - C1 + 1) * V) + C1.

テキスト文字総数(_文字分類ならび,_テキスト総文字数) :-
    findsum(_発生文字数,member([_,_発生文字数],_文字分類ならび),_テキスト総文字数).

連続文字番号の割り当て(_,[],[]) :- !.
連続文字番号の割り当て(N,[[_分類,S]|R1],[[分類,N,N1]|R2]) :-
    N2 is N + S,
    N1 is N + S - 1,
    連続文字番号の割り当て(N2,R1,R2).    

eucコード分類(半角英数,0x30,0x39).
eucコード分類(半角英数,0x51,0x5a).
eucコード分類(半角英数,0x61,0x6a).
eucコード分類(全角数字,0xa3b0,0xa3b9).
eucコード分類(半角カナ,0x8ea1,0x8ed6).
eucコード分類(全角カナ,0xa5a1,0xa5f6).
eucコード分類(全角かな,0xa4a1,0xa4f3).
eucコード分類(全角記号,0xa1a1,0xa2fe).
eucコード分類(全角漢字,0xb0a1,0xfcee).

乗算合同法によってM個の正規分布ならびを得る(M,L) :-
    _初期値 is random mod 29571,
    乗算合同法によってM個の正規分布ならびを得る(M,_初期値,L).

乗算合同法によってM個の正規分布ならびを得る(M,_初期値,L) :-
    乗算合同法による正規分布ならび(M,16087,_初期値,65535,L).

乗算合同法による正規分布ならび(0,A,N,_法,[]) :- !.
乗算合同法による正規分布ならび(M,A,N,_法,[X|R]) :-
    X is N / _法,
    乗算合同法演算(A,N,_法,N2),
    M1 is M - 1,
    乗算合同法による正規分布ならび(M1,A,N2,_法,R).

乗算合同法演算(A,N,_法,N2) :-
    N2 is (A * N) mod _法.