このディレクトリの索引
http://hibari.2ch.net/test/read.cgi/tech/1308749241/257
#  [2]下記のプログラムにおいて,numcountは,値が0 〜M -1 の範囲の大きさN のint型の配列を引数として渡されると(ただし,M, N は正の整数),同じ値が複数ある時はそれを1 個とみなしてその配列中の数の 
#  個数を返す関数である.例えば,配列の値を7, 4, 8, 2, 4, 6, 1, 6, 4, 5 とすると,(ダブリを省くと) この中には,7, 4, 8,2, 6, 1, 5 の7 個があるので,関数numcountは7 を返す. 
#  これは,例えば,0 〜M -1 の範囲でどんな数が出てきたかをチェックしておき(ヒント: 大きさM のint型の配列を用い,最初はすべて0に初期化しておき,数iが現れたら,そのi番目を1にすればよい), 
#  最後に1度でも出てきたものを数えれば求めることができる.関数numcountを,下記のプログラムの/* INSERT HERE */の部分に挿入できるように書け.(提出はプログラム全体) 
#   
#  #include <stdio.h> 
#  #define M 10 /* 適当な正整数(数の範囲が0 〜M -1) */ 
#  #define N 10 /* 適当な正整数(入力する数の個数)*/ 
#  /* INSERT HERE */ 
#  intmain(void) 
#  { 
#  inti, a[N]; 
#  /* a[0]〜a[N-1] の値を入力する*/ 
#  for(i= 0; i< N; i++) { 
#  printf("a[%1d] = ? ", i); 
#  scanf("%d", &a[i]); 
#  } 
#  printf("numcount= %3d\n", numcount(a)); 
#  return 0; 
#  } 
#   
#  

'同じ値が複数ある時はそれを1 個とみなしてならびの数の個数を返す'(M,N,_ならび,_個数) :-
       ランダムに値を入力(M,N,_ならび),
       '同じ値が複数ある時はそれを1 個とみなしてならびの数の個数を返す'(M,_ならび,_個数).

'同じ値が複数ある時はそれを1 個とみなしてならびの数の個数を返す'(M,_ならび,_個数) :-
        length(L,M),
        出現検査(_ならび,L),
        値の存在する個数を調べる(L,_個数).

出現検査([],L) :- !.
出現検査([I|R],L) :-
        length(L0,I),
        append(L0,[V|_],L),
        V = 1,
        出現検査(R,L).

値の存在する個数を調べる(L,_個数) :-
        値の存在する個数を調べる(L,[],_個数).

値の存在する個数を調べる([],L,_個数),
        length(L,_個数),!.
値の存在する個数を調べる([V|R1],L,_個数) :-
        \+(var(V)),
        値の存在する個数を調べる(R1,[_|L],_個数).
値の存在する個数を調べる([V|R1],L,_個数) :-
        var(V),
        値の存在する個数を調べる(R1,L,_個数).

ランダムに値を入力(M,N,_ならび) :-
        length(_ならび,N),
        findall(V,(
                    append(_,[_|_],_ならび),
                    V is random(M)),
                _ならび).        

?- 'a##'. c150-290#
このディレクトリの索引
http://hibari.2ch.net/test/read.cgi/tech/1308749241/290
#  [1] 授業単元:C 
#  [2] 問題文(含コード&リンク): 
#    逆ポーランド記法の電卓を実装をする 
#    なお、電卓の条件は以下です 
#  条件及び動作例:http://www.dotup.org/uploda/www.dotup.org1758622.txt.html 
#  
#  条件
#  ・入力はコンソールでする
#  ・数式の終わりは;を入力
#  ・数式は後置記法で入力
#  ・数値計算はdouble型可能な範囲
#  ・演算は、四則演算及びsqr (2乗を求める関数)とする。
#  ・スタック、キュー、木構造のいずれか(または複数)を利用すること。
#   なお、これらのデータ構造の実装にはポインタを使うこと。
#  ・自由拡張
#   ・前置記法で書かれた数式(文字列)を後置記法に変換する関数を作成せよ。
#    また、この関数を用いて、前置記法で書かれた数式に対する電卓を実現
#   ・ユーザ入力ミスの対応と説明文の表示
#  
#  動作例
#  % ./a.out
#  5.1 3 + ;
#  8.10000
#  2 4 * ;
#  8.00000
#  8 sqr ;
#  64.00000
#  quit
#  % □


逆ポーランド記法の電卓を実装をする :-
        逆ポーランド記法の電卓を実装をする([]).

逆ポーランド記法の電卓を実装をする(_スタック_1) :-
        入力(_逆ポーランド式),
        \+(_逆ポーランド式=quit),
        sPLIT(_逆ポーランド式,[+,-,*,/,sqr],L),
        式をスタックにプッシュする(L,_スタック_1,_スタック_2),
        演算評価(_スタック2,_スタック3),
        _スタック_3 = [_答え|_],
        writef('%t\n',[_答え]),
        逆ポーランド記法の電卓を実装をする(_スタック_3).
逆ポーランド記法の電卓を実装をする(_スタック_1).

演算評価([],[]) :- !.
演算評価([-|R1],[C|R2]) :-
        演算評価(R1,[A,B|R2]),
        C is A - B,!.
演算評価([+|R1],[C|R2]) :-
        演算評価(R1,[A,B|R2]),
        C is A + B,!.
演算評価([*|R1],[C|R2]) :-
        演算評価(R1,[A,B|R2]),
        C is A * B,!.
演算評価([/|R1],[C|R2]) :-
        演算評価(R1,[A,B|R2]),
        C is A / B,!.
演算評価([sqr|R1],[C|R2]) :-
        演算評価(R1,[A|R2]),
        C is A * A,!.
演算評価([V|R1],[V|R2]) :-
        number(V),
        演算評価(R1,R2).

式をスタックにプッシュする([],_スタック,_スタック) :- !.
式をスタックにプッシュする([' '|R],_スタック_1,_スタック_2) :-
        式をスタックにプッシュする(R,_スタック_1,_スタック_2).
式をスタックにプッシュする([A|R],_スタック_1,_スタック_2) :-
        式をスタックにプッシュする(R,[A|_スタック_1],_スタック_2).