このディレクトリの索引
http://pc12.2ch.net/test/read.cgi/tech/1255709298/949
#  [1] 授業単元: C言語演習  
#  [2] 問題文(含コード&リンク): http://ime.nu/kansai2channeler.hp.infoseek.co.jp/cgi-bin/joyful/img/10114.txt

# 以下のプログラムを作成せよ
# 
# 9個のマスがあり、1〜9の数字が一個だけ入るとする。
# このとき、符号なし整数1つでマスにまだ入れられていない数字を記録したい。
# そこで、下位ビットから9ビット目までで1〜9がマスに入っているかどうかを表すこととする。
# 空白のマスは0で表示する。
# 
# 例:132584090→下位9ビット:001100000
# この場合、6もしくは7がマスに入っていないため、6ビット目と7ビット目に1が立っていることとなる。
# 
# 課題プログラムを実行すると、in.txtから9個の文字データを読み込み、上記のような変換をして9ビットのデータのビット列を表示する。
# 例えば132584090とin.txtに記録されていた場合、下位9ビットは
# 001100000と表示される
#
# 手順
# 1..ビット列を記録する変数を宣言し、0で初期化する。
# 2..9個の数字を9個の変数に ファイルから読み込む
# 3..各変数には0〜9の数字が入っているが、0以外の場合に対応する桁に1を立てる
# 4..ビット列の 0と1を反転させる
# 5..下位9ビットをprintf関数で表示する
# 
# 6..in.txtの値をいろいろ変化させて、プログラムが正しいことを確認せよ
# 
# 発展課題:
# in.txtに9x9の以下のような数字列を入れておく.
# 縦と横に必ず1から9までの数字が並ぶとする。ここで各行、各列の空白(空白は0で表す)に入りうる数字をビット列で表せ。
# 
# 9行、9列なので、18個の整数データとなる。
# 
# 次に、空白があれば、どのように処理すれば、空白に入る数字を決めることができるか、考えよ。
# 
# 1 2 3 4 0 6 0 8 9
# 2 3 4 5 6 7 8 9 1
# 3 4 5 0 7 0 9 1 2
# 0 5 6 7 8 9 1 2 3
# 5 6 7 8 9 1 2 3 4
# 6 7 0 9 0 2 3 4 5
# 7 8 9 1 2 3 4 5 6
# 8 0 1 2 3 4 5 0 7
# 9 1 2 3 4 5 6 7 8
# 
# 1行目-> 001010000
# 5列目-> 000010001

c2_949 :-
    get_lines('in.txt',L),
    findall(L2,(member(A,L),split(A,[' '],L2)),L3),
    findall([N,L5],(member(L4,L3),欠落した番号ビット(L4,L5)),L6),
    c2_949_表示(L6).

欠落した番号ビット(L1,L2) :-
    length(L2,9),
    findall(N,(for(1,N,9),\+(member(N,L1)),L3),
    欠落した番号ビット(9,L3,L2).

欠落した番号ビット(N,_,[]) :- N < 1.
欠落した番号ビット(N,L,[0|R]) :-.
    \+(member(N,L)),
    N1 is N - 1,
    欠落した番号ビット(N1,L,R).
欠落した番号ビット(N,L,[1|R]) :-.
    member(N,L),
    N1 is N - 1,
    欠落した番号ビット(N1,L,R).

c2_949_表示([]) :- !.
c2_949_表示([[N,L]|R]) :-
    concat_atom(L,' ',S),
    write_formatted('%t 行目: %t\n',[S]),
    c2_949_表示(R).