数独(再挑戦)② 確定マスの配列を編集する
昨日は数独について、構想新たに27×27の配列を準備してみた。
infoment.hatenablog.com
今日は、実際の出題を配列に反映させることに挑戦する。
クラスモジュール
Option Explicit ' 出題された9×9を格納する配列。 Public SourceArray As Variant ' 解答の過程で使用する27×27の配列。 Public TempArray As Variant ' 解答となる9×9を格納する配列。 Public AnswerArray As Variant ' 真っ新の27×27配列。 Private Property Get BaseArray() As Variant Dim r As Long Dim c As Long Dim arr(1 To 27, 1 To 27) As Variant For r = 1 To 27 For c = 1 To 27 arr(r, c) = ((r - 1) Mod 3) * 3 + (c - 1) Mod 3 + 1 Next Next BaseArray = arr End Property Private Sub Class_Initialize() ' TempArray初期化。 TempArray = BaseArray End Sub
TempArrayなどは本来、経過を格納する一時的なものであるため、Public変数である必要は無い。ただし今は、このクラスを整備しながら経過を確認するために、Public変数としている。
まず、一つのマスから3×3がどこにあるか知る必要がある。
↓の例で言えば、2行3列目のマスは、
4行7列目から始まっている。
そこで、この4行7列目の原点となるポイントを取得することにした。
↓図で言えば、3行6列目の「9」が、これにあたる。
' 原点 Dim r0 As Long Dim c0 As Long Enum OriginIndex OriginR OriginC End Enum
Private Function OriginPoint(r_index As Long, c_index As Long) As Variant ' 9×9で指定した1つのセルを構成する3×3の配列を抽出。 ' 例えば2行3列目が属する3×3配列の起点の一つ前は、 ' (2-1)×3=3 ' (3-1)×3=6 ' つまり(3,6)が原点(0,0)なる。 Dim arr(1) As Variant arr(OriginIndex.OriginR) = (r_index - 1) * 3 arr(OriginIndex.OriginC) = (c_index - 1) * 3 OriginPoint = arr End Function
この情報を利用して、9×9の範囲に於いて指定したセルを構成する3×3の配列について、指定値以外を0にして確定させる。
Private Sub FixedCell(r_index As Long, c_index As Long, fixed_number) ' 原点を取得。 r0 = OriginPoint(r_index, c_index)(OriginIndex.OriginR) c0 = OriginPoint(r_index, c_index)(OriginIndex.OriginC) Dim r As Long Dim c As Long For r = 1 To 3 For c = 1 To 3 If 3 * (r - 1) + c <> fixed_number Then TempArray(r0 + r, c0 + c) = 0 End If Next Next End Sub
以上のことから、出題内容を反映し、初期状態を作成する。
Public Sub InitArray() Dim r As Long Dim c As Long For r = 1 To 9 For c = 1 To 9 If IsEmpty(SourceArray(r, c)) = False Then FixedCell r, c, SourceArray(r, c) End If Next Next End Sub
それでは、↓の出題からTempArrayを作成してみよう。今回は確認のため、別シートに結果を張り付けている。
Sub test() Dim Sudoku As New Sudoku Sudoku.SourceArray = Sheet1.Range("A1:I9").Value Sudoku.InitArray ' 結果確認のため、仮で貼り付け。 Range("A1").Resize(27, 27) = Sudoku.TempArray End Sub
意図した結果を取得できた。
ただし、現時点では未だ不完全。例えば黄色の3が確定している時点で、緑色の3は全て0でなければならない。
これについては、次回に続きます。
参考まで。