重要なお知らせ

「教えて! goo」は2025年9月17日(水)をもちまして、サービスを終了いたします。詳細はこちら>

【GOLF me!】初月無料お試し

 エクセルのVBAを使って、ナンバープレイス(数独?)の問題を創りたいのですが、どうすれば良いでしょう?

 一応、以下の条件で自分で組んでみました。

 ○各マス目で、「縦9マス」「横9マス」「3×3マス」中に有る数字を【1~9】内から消去し、残った数字内からランダムで挿入する数字を決定する。
 ○処理中に、どうしても決定できないマス目が発生した場合は、決定済みのマス目をある程度チャラにし(処理を戻って)やり直す。
 ○上記方法で、1~81までのマス目を埋めていく。
 ○最後に、適当な数のマス目の数字を消去する。

 一問作成するのに結構な時間がかかる上、時には完成しない(やり直し続ける)事態が発生します。

 何か良い方法(アルゴリズム?)が有ったらご教示願います。

 (…アルゴリズムを質問するのは、カテゴリー違いでしょうか?)

A 回答 (4件)

お察しのとおり、


関数は別シートから参照してもかまいませんし、セル(行または列)の非表示でもかまいません。
ワークシート関数の返値をVBA側で判断することは容易です。また、セルやシートが非表示でもVBA側では読み出せますので、問題ないですね。

別シートの場合は、シートを非表示にしてブック保護。
セルの非表示の場合は、シート保護で良いでしょう。
    • good
    • 1
この回答へのお礼

 たびたび回答ありがとうございました。

 参考にさせて頂きます。

お礼日時:2006/07/23 22:24

> ところで【B2】の判定後、次のセルを判定する際にはどうすれば



COUNTIF関数の論理積は、全てのマス(81マス)分に対応するセルに、あらかじめ、入力しておきます。VBAで入力する必要はありません。

もし、そのシートを問題用紙として使うのであれば、非表示か、文字色を白などにして見えなくしておけばOKです。

なお、81マス全てに成功した場合は、COUNTIF関数が入力された全てのセルは、 1 と表示されます。

補足
前記の「論理積」という言い方は正しくないかもしれませんが、念のため、
COUNTIF(B$2:B$10,B2) は列の重複検査
COUNTIF($B2:$J2,B2) は行の重複検査
COUNTIF($B$2:$D$4,B2) は9マスの重複検査
を行っています。
3つの関数は、重複があれば2以上、数値がなければ0を返しますので、すべてに重複しない数値になれば、自分自身の 1個しかないので、必ず 1 を返します。

このCOUNTIF関数群を使えば、マクロは10行程度で済みます。
    • good
    • 0
この回答へのお礼

 重ねての回答ありがとうございます。
 
 >COUNTIF関数の論理積は、全てのマス(81マス)分に対応するセルに、あらかじめ、入力しておきます。VBAで入力する必要はありません。

 勘違いしていたら申し訳ないのですが、(↑)と言うことは81マス全てに対応した「COUNTIF関数」を入力しておく必要が有るわけですね?(つまり、各マス目の判定範囲である「縦9マス」「横9マス」「3×3マス」を指定した、81マス分)
 又、この問題用紙(シートの事)を不特定多数の人間が使用すると仮定した時、「関数」を入力して有るセルを消される可能性がありますが、その点はどう処理すれば良いでしょうか?
 別のシートから、(例えば「シート1」に問題を創ろうとして、「シート1」【B2】の論理積を「シート3」のセルに入力した「関数」で判定する。)様な事が出来るでしょうか? それとも、『セルの保護』をするのでしょうか?

 申し訳ありませんが、重ねてお願い致します。

お礼日時:2006/07/22 12:38

(1) 数独マス範囲内の任意のセルに対し、重複検査するCOUNTIF関数を、別の隠しセルなどに入力しておきます。


例えば、数独マスがB2:J10の範囲で、B2の重複検査なら、
=COUNTIF(B$2:B$10,B2)*COUNTIF($B2:$J2,B2)*COUNTIF($B$2:$D$4,B2)
となります。

(2) 任意のセルにランダム関数で発生させた1~9の数値を入れます。

(3) (2)で入れた値に対し、(1)の論理積が1になるまで(2)をループします。→(注)参照

(4) (1)の論理積が1になったら次のセルで(2)を実行


(注)
(2)のループ数はカウントしておき、適当なカウント数になったら、マス全体をクリアして最初からやり直します。カウント数は50くらいでいいかと思います。50もループすれば1~9の何れかの数値が1度は出現するでしょう。

(1)~(4)の200回ループで試したところ、5回に1回程度は成功するようです。計算時間は、私の環境で2秒程度でした。

環境 WinXP + EXCEL2000 Pentium4 3G
    • good
    • 0
この回答へのお礼

 回答ありがとうございます。

 「COUNTIF」関数なんて、便利な物が有るんですね。知りませんでした。

 ところで【B2】の判定後、次のセルを判定する際にはどうすれば良いのでしょうか?隠しセル内の
 =COUNTIF(B$2:B$10,B2)… 
 の 「B2」部分を次のセルに指定する必要が有ると思うのですが、VBAプロシジャー上のコードにはどう書けば良いでしょうか?
 それとも、全てのマス目に対して同じように、隠しセルを設定するのでしょうか?

 セルに直接数式を設定した事が無いので、使い方がわかりません。
 よろしくお願い致します。

 

お礼日時:2006/07/21 18:04

直接の回答ではありませんが。


もし「問題を創る」ことが目的であれば、
1)(複数回答が存在する)ヒントの少ない問題を作る
2)下記プログラムで正解例を調べる
3)正解が1つになるようなヒントを再構成する
http://www.vector.co.jp/games/soft/winnt/game/se …
という手順はいかがでしょうか。

VBAのプログラミングが目的であれば、べつですが。
    • good
    • 0
この回答へのお礼

 早速回答ありがとうございます。

 申し訳ありませんが、「コンピュータ」に「自動」で問題を作成させたいのです。

 質問文内の方法で創り(空白が25~30程の時)、解析プログラム(ネット上に多数ある物)にかけると難易度「簡単」と解析されます。

 この際、問題の難易度は問いません(…とは言っても、ある程度の難易度が有った方が良いのですが)。
『自動』で、出来るだけ『速く』、『矛盾』の無い問題を創る方法を…。

お礼日時:2006/07/20 23:41

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!