自分で何かのプログラムを作成してみましょう.
数当てや,おみくじのような簡単なゲームのようなものでも,より本格的で実用的なものでも各自の興味に応じて考えてください.
課題は新しいExcelブックに作成し,ファイル名は「各自の学籍番号-vba-kadai.xlsm」として今までと同様にして提出してください.
セルに精度を入力し,方程式\(x^3 + x^2 - 2x - 1 = 0\)の解をニュートン法を使用して求めるプログラムを作りましょう.結果は精度を入力したセルの下のセルに表示するようにし,使用するセルはこのプログラムを登録するボタンの下に来る位置のセルにしてください.
方程式 \(f(x) = 0\) の解は関数 \(y = f(x)\) のグラフが \(x\)軸を横切るときの \(x\) の値です.これをコンピューター上で実現するには,「任意の初期値 \(x\) における関数の接線を考え,その接線が \(x\) 軸を横切る \(x\) での接線を求め,さらにこの新しい接線が \(x\)軸を横切る \(x\) を求める」という作業を繰り返すことによって関数が \(x\)軸を横切るときの \(x\) の値に近づくことができるため,繰り返しの回数を増やすことによって任意の制度で解を求めることができます.
函数\(y = f(x)\)の\(x_i\)における接線の傾きは,その点における微分係数で与えられる.導関数を \(f'(x)\) とし,\(y_i = f(x_i)\),この点における接線が \(x\)軸を横切る位置を \(x_{i+1}\) とすると, \[ f'(x_i) = \frac{y_i}{x_i - x_{i+1}} \] より,\(x_{i+1}\)は\(x_i\)から次のようにして求めることができる. \[ x_{i+1} = x_i - \frac{y_i}{f'(x_i)} = x_i - \frac{f(x_i)}{f'(x_i)} \] この手続きを繰り返した極限値が方程式 \(f(x) = 0\) の解となる.実際には無限回繰り返すことはできないので, \(\delta\) を精度として,\(|x_{i} - x_{i-1}| < \delta\) となった \(x_i\) を答えとする.
また,導関数が得られていない場合は十分小さな \(\varepsilon < \delta\) を用いて次のように考える. \[ f'(x) \sim \frac{f(x+\frac{\varepsilon}{2}) - f(x-\frac{\varepsilon}{2})}{\varepsilon} \]
以上のことから,プログラムでは,初期値と精度を設定して上記の演算を精度の条件を満たすまで繰り返し実行し,結果として方程式の解の近似値を求める.
Excelのセルをあるパターンで色分けして自動的に迷路を作るプログラムを作ってみる.
セルの幅と高さを調整すると見栄えが良くなります.
以下のプログラムは,領域内の任意の位置からランダムな方向に通路を作り,表示します.これを繰り返し使用すると迷路を作れます.
Sub gen_road()
'領域の大きさを設定
Const MSize As Integer = 10
Const Size As Integer = 2 * MSize
'領域の各場所の状態を記憶する配列
Dim site(Size, Size) As Integer
Dim i As Integer, j As Integer
'領域の初期状態(外周は道路にしておく)
For i = 0 To Size Step 1
For j = 0 To Size Step 1
If i = 0 Or j = 0 Or i = Size Or j = Size Then
site(i, j) = 1
Else
site(i, j) = 0
End If
Next j
Next i
'初期位置の設定
Dim startx As Integer, starty As Integer
startx = Int(MSize * Rnd() + 1) * 2
starty = Int(MSize * Rnd() + 1) * 2
site(startx, starty) = 1
'道路を作る
Dim n As Integer, m As Integer, s As Integer
Dim f As Boolean
f = False
n = startx
m = starty
Do
If site(n + 2, m) = 1 And site(n, m + 2) = 1 And site(n - 2, m) = 1 And site(n, m - 2) = 1 Then
f = True
Else
s = Int(4 * Rnd())
If s = 0 And site(n + 2, m) = 0 Then
site(n + 1, m) = 1
site(n + 2, m) = 1
n = n + 2
ElseIf s = 1 And site(n, m + 2) = 0 Then
site(n, m + 1) = 1
site(n, m + 2) = 1
m = m + 2
ElseIf s = 2 And site(n - 2, m) = 0 Then
site(n - 1, m) = 1
site(n - 2, m) = 1
n = n - 2
ElseIf site(n, m - 2) = 0 Then
site(n, m - 1) = 1
site(n, m - 2) = 1
m = m - 2
End If
End If
Loop While f = False
'領域と道路を表示するサブプロシージャを呼ぶ
Call rep_road(Size, site())
End Sub
Sub rep_road(site_size As Integer, site() As Integer)
Dim i As Integer, j As Integer
'セルの高さと幅、初期状態の背景色を設定
For i = 0 To site_size Step 1
For j = 0 To site_size Step 1
Cells(i + 3, j + 3).RowHeight = 10
Cells(i + 3, j + 3).ColumnWidth = 1
Cells(i + 3, j + 3).Interior.Color = RGB(0, 0, 0)
Next j
Next i
'領域の状態に合わせてセルの背景色を変更
For i = 0 To site_size Step 1
For j = 0 To site_size Step 1
If site(i, j) = 0 Then
Cells(i + 3, j + 3).Interior.Color = RGB(0, 0, 0)
Else
Cells(i + 3, j + 3).Interior.Color = RGB(255, 255, 255)
End If
Next j
Next i
End Sub
Excelのセルに入力された数値を順番に並べ替えるプログラムを作ってみる.
3x3または4x4の魔方陣を作るプログラムを作ってみる.
セルの幅と高さを調整すると見栄えが良くなります.
ハノイの塔を解くプログラムを作ってみる.Excelブックの1列を1つの塔とし行数を円盤の位置,セルに入力された数値を円盤の半径と考える.