最終講 卒業研究と卒業試験
第4話 課題3 9次ラテン方陣にブロックの条件を加える
解答例
Public Class Form1
'変数の宣言と初期化
Dim a(9, 9) As Integer, x(81) As Integer, y(81) As Integer, s As Integer
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Button1.Click
Dim hj, ow As DateTime, sa As TimeSpan
hj = Now
s = 0
DataGridView1.Rows.Clear()
h()
f(0)
DataGridView1.Rows.Add() '1行追加
DataGridView1(7, 10 * s).Value() = "順"
DataGridView1(8, 10 * s).Value() = "列"
DataGridView1(9, 10 * s).Value() = "方"
DataGridView1(10, 10 * s).Value() = "陣"
DataGridView1(11, 10 * s).Value() = "総"
DataGridView1(12, 10 * s).Value() = "数"
DataGridView1(13, 10 * s).Value() = s '総数表示
ow = Now
sa = ow - hj
DataGridView1.Rows.Add() '1行追加
DataGridView1(9, 10 * s + 1).Value() = "計"
DataGridView1(10, 10 * s + 1).Value() = "測"
DataGridView1(11, 10 * s + 1).Value() = "時"
DataGridView1(12, 10 * s + 1).Value() = "間"
DataGridView1(13, 10 * s + 1).Value() = sa.TotalSeconds '計測時間表示
End Sub
Sub h()
For i = 0 To 80
x(i) = i Mod 9
y(i) = Int(i / 9)
Next
End Sub
Sub f(ByVal g As Integer)
If s = 100 Then Exit Sub
Dim h, xs, ys As Integer
For i = 0 To 8
a(y(g), x(g)) = i + 1
h = 1
If x(g) > 0 Then
For j = 0 To x(g) - 1
If a(y(g), x(g)) = a(y(g), j) Then
h = 0
Exit For
End If
Next
End If
If h = 1 Then
If y(g) > 0 Then
For j = 0 To y(g) - 1
If a(y(g), x(g)) = a(j, x(g)) Then
h = 0
Exit For
End If
Next
End If
End If
If h = 1 Then
If g > 0 Then
xs = Int(x(g) / 3)
ys = Int(y(g) / 3)
For j = 0 To y(g) - 3 * ys
For k = 0 To 2
If y(g) = j Then If x(g) = k Then Exit For
If y(g) <> 3 * ys + j And x(g) <> 3 * xs + k
Then
If a(y(g), x(g)) = a(3 * ys + j, 3 * xs + k) Then
h = 0
Exit For
End If
End If
Next
If h = 0 Then Exit For
Next
End If
End If
If h = 1 Then
If g + 1 < 81 Then
f(g + 1)
Else
For j = 0 To 8
DataGridView1.Rows.Add() '1行追加
For k = 0 To 8
DataGridView1(k, j + 10 * s).Value = a(j, k)
Next
Next
DataGridView1.Rows.Add() '1行追加
s = s + 1
If s = 100 Then Exit Sub
End If
End If
Next
End Sub
End Class
実行例
解説
If h = 1 Then
If g > 0 Then
xs = Int(x(g) / 3)
ys = Int(y(g) / 3)
For j = 0 To y(g) - 3 * ys
For k = 0 To 2
If y(g) = j Then If x(g) = k Then Exit For
If y(g) <> 3 * ys + j And x(g) <> 3 * xs + k
Then
If a(y(g), x(g)) = a(3 * ys + j, 3 * xs + k) Then
h = 0
Exit For
End If
End If
Next
If h = 0 Then Exit For
Next
End If
End If
が加えた部分です。
xs = Int(x(g) / 3)
ys = Int(y(g) / 3)
では何をしているんでしょうか。実はブロック番号を計算しています。
1 | 2 | 3 | |||||||
0 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | |
18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | |
1 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 |
36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | |
45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | |
2 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 |
63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | |
72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 |
例えば、セル番号49は、ブロック番号(0,2)に対応します。
セル番号の49とき、
For j = 0 To y(g) - 3 * ys
For k = 0 To 2
If y(g) = j Then If x(g) = k Then Exit For
If y(g) <> 3 * ys + j And x(g) <> 3 * xs + k
Then
If a(y(g), x(g)) = a(3 * ys + j, 3 * xs + k) Then
h = 0
Exit For
End If
End If
Next
If h = 0 Then Exit For
Next
では、セル番号49とセル番号30,32,39,41の内容が比較されます。
セル番号31,40,48は
For i = 0 To 8
a(y(g), x(g)) = i + 1
h = 1
If x(g) > 0 Then
For j = 0 To x(g) - 1
If a(y(g), x(g)) = a(y(g), j) Then
h = 0
Exit For
End If
Next
End If
If h = 1 Then
If y(g) > 0 Then
For j = 0 To y(g) - 1
If a(y(g), x(g)) = a(j, x(g)) Then
h = 0
Exit For
End If
Next
End If
End If
において重複チェックが済んでいまし、セル番号0から順に入れてきてセル番号49までしか数字が入っていませんから、
セル番号50にはまだ数字が入っていないので比較の必要がないわけです。
30 | 31 | 32 |
39 | 40 | 41 |
48 | 49 | 50 |
If y(g) = j Then If x(g) = k Then Exit Forはセル番号50を検査対象から外すためにあります。
セル番号49に達したら検査を終了するようになっています。
y(g) <> 3 * ys + j And x(g) <> 3 * xs + kは、同行と同列を検査対象から外すためにあります。
31,40,48は一度検査されているのでテストの必要はないわけです。
では、For j = 0 To y(g) - 3 * ysのj = 0 To y(g) - 3 * ysの意味は何でしょうか。
例えば、セル番号39なら
30 | 31 | 32 |
39 | 40 | 41 |
48 | 49 | 50 |
最後の行は検査する必要はありません。
セル番号39までしか数字が入っていないからです。
では皆さん、
課題4
課題3で完成させたソフトに
ブロックの区切り*入れましょう。
課題5
課題4にさらにランダムを入れて自然な数独にしましょう。
に挑戦して、卒業研究課題は終了です。
後は、卒業試験を残すのみとなります。
VC++講義第1部へ
vb講義へ
VB講義基礎へ
初心者のための世界で一番わかりやすいVisual C++入門基礎講座
数学研究室に戻る