第4講 残確定法によるさらなる高速化
第4話 プログラム解説その2

今日は
If g = 2 * n - 1 And n Mod 2 = 0 Then
  wa = 0
  For k = 0 To n - 2
    wa = wa + mah(k, n - 1 - k)
  Next
  hhh = 0
  sa = Int(n * (n * n + 1) / 2) - wa
  If sa < 1 Or sa > n * n Then GoTo owari1
  If tyouhukuhantei(sa - 1) = 1 Then GoTo owari1
  mah(i, j) = sa
  tyouhukuhantei(sa - 1) = 1
  hhh = 1
  sakusei (g + 1)
  GoTo owari1
End If

If g = 2 * n - 2 And n Mod 2 = 1 Then
  wa = 0
  For k = 0 To n - 2
    wa = wa + mah(k, n - 1 - k)
  Next
  hhh = 0
  sa = Int(n * (n * n + 1) / 2) - wa
  If sa < 1 Or sa > n * n Then GoTo owari1
  If tyouhukuhantei(sa - 1) = 1 Then GoTo owari1
  mah(i, j) = sa
  tyouhukuhantei(sa - 1) = 1
  hhh = 1
  sakusei (g + 1)
  GoTo owari1
End If

の部分を解説します。
前半は偶数の場合を担当し、
後半は奇数の場合を担当しています。
理由は番号の付け方にありました。

n = 4 のとき

 0  1  2  3
 0  8  9  4
10  1  5 12
11  6  2 14
  13 15  3

n = 5 のとき

 0  1  2  3  4
 0  9 10 11  5
12  1 15  6 16
13 17  2 19 20
14  7 21  3 23
 8 18 22 24  4

上の例を見ればおわかりのように、
逆対角線の最後の番号は偶数の場合と奇数の場合で異なります。
偶数のときはg = 2 * n - 1ですし、
奇数の場合はg = 2 * n - 2です。
ですから偶数の場合と奇数の場合を分けなければならないのです。
ずれてしまう訳は、奇数の場合は対角線が中央のところで交錯するため
番号が1つ減ってしまうことにあります。
さて、偶数の場合を例にとって説明しましょう。

 0  1  2  3
 1  ・  ・  4
 ・  6  7  ・
 ・  2 11  ・
   ・  ・ 16

g = 2 * n - 1はピンクの位置を表しました。上の表の場合、
  wa = 0
  For k = 0 To n - 2
    wa = wa + mah(k, n - 1 - k)
  Next
  hhh = 0
  sa = Int(n * (n * n + 1) / 2) - wa

の計算でsa=21になりますが、これは
If sa < 1 Or sa > n * n Then GoTo owari1
の部分をクリアできず一個手前の世界に戻り

 0  1  2  3
 1  ・  ・  4
 ・  6  7  ・
 ・  3 11  ・
   ・  ・ 16

となります。そして再び

 0  1  2  3
 1  ・  ・  4
 ・  6  7  ・
 ・  3 11  ・
   ・  ・ 16

となりますが前回と同様にクリアできず、
何回も前の世界に戻り

 0  1  2  3
 1  ・  ・  4
 ・  6  7  ・
 ・  8 11  ・
 ・  ・  ・ 16

のときに初めてsa=15となって、初めて
If sa < 1 Or sa > n * n Then GoTo owari1
をクリアし、sakusei (g + 1)によって

 0  1  2  3
 1  ・  ・  4
 ・  6  7  ・
 ・  8 11  ・
15  ・  ・ 16

g = 2 * n(つまり番号8)の世界に飛びます。

第4講第3話へ
 第4講第5話へ


VB入門講義応用編トップへ

VB入門講義トップへ