先日、久しぶりに電車に乗っていたら、"3,4,7,8から10を作れ"と書いてある広告を見かけました。
昔は切符に4つの数字が書いてあったのでよくやったものです。ICカードになってからは全然やらないですが。
さておき。パズルを解く気分で少し解いてみました。プログラミングの勉強には比較的良い題材だと思います。
やることは4つの数字から2つ選んで四則演算。それを繰り返して10を作るだけです。
- 1回目の計算:順番を考慮して4つから2つ選ぶ方法は12通り
- 2回目の計算:1回目の計算結果と残りの2つから2つを選ぶ方法は6通り
- 3回目の計算:残っている数字を選ぶ方法は2通り
- 四則演算:4通り
よって、すべての組み合わせは、12 * 4 * 6 * 4 * 2 * 4 = 9216通りです。たかだか1万通りくらいです。Excel VBAでリストアップしてみましょう。
ソースコードはご自由にご利用ください。ただし、趣味のプログラムなので保証はありません。
------------------------------
Option Explicit
Dim row As Long
Dim col As Long
Const epsilon As Double = 0.000001
Public Sub Calc10()
Sheet1.Cells.Clear
row = 1
col = 1
Call Calc10A(1, 1, 9, 9)
End Sub
'演算子の表示
Public Function OperationText(op As Long) As String
OperationText = ""
If op = 0 Then
OperationText = "'+"
ElseIf op = 1 Then
OperationText = "'-"
ElseIf op = 2 Then
OperationText = "'*"
ElseIf op = 3 Then
OperationText = "'/"
End If
End Function
'演算
Public Function OperationCalc(op As Long, a0 As Double, a1 As Double) As Double
OperationCalc = a0
If op = 0 Then
OperationCalc = a0 + a1
ElseIf op = 1 Then
OperationCalc = a0 - a1
ElseIf op = 2 Then
OperationCalc = a0 * a1
ElseIf op = 3 Then
If Math.Abs(a1) < epsilon Then
OperationCalc = a0
Else
OperationCalc = a0 / a1
End If
End If
End Function
'a(0) - a(3) : 0 - 9の数字4つ
'a(4) : 1回目の演算結果
'a(5) : 2回目の演算結果
'a(6) : 3回目の演算結果
Public Sub Calc10A(a0 As Long, a1 As Long, a2 As Long, a3 As Long)
'---------- 演算子選択のIndex ----------
Dim i0 As Long
Dim i1 As Long
Dim i2 As Long
'---------- 数字選択のIndex ----------
Dim j0 As Long
Dim j1 As Long
Dim j2 As Long
Dim j3 As Long
Dim j4 As Long
Dim j5 As Long
'------------------------------
Dim a(6) As Double
a(0) = a0
a(1) = a1
a(2) = a2
a(3) = a3
a(4) = 0
a(5) = 0
a(6) = 0
'---------- 1回目の演算 ----------
For i0 = 0 To 3
For j0 = 0 To 3
For j1 = 0 To 3
If j1 <> j0 Then
a(4) = OperationCalc(i0, a(j0), a(j1))
'---------- 2回目の演算 ----------
For i1 = 0 To 3
For j2 = 0 To 4
If j2 <> j0 And j2 <> j1 Then
For j3 = 0 To 4
If j3 <> j0 And j3 <> j1 And j3 <> j2 Then
a(5) = OperationCalc(i1, a(j2), a(j3))
'---------- 3回目の演算 ----------
For i2 = 0 To 3
For j4 = 0 To 5
If j4 <> j0 And j4 <> j1 And j4 <> j2 And j4 <> j3 Then
For j5 = 0 To 5
If j5 <> j0 And j5 <> j1 And j5 <> j2 And j5 <> j3 And j5 <> j4 Then
a(6) = OperationCalc(i2, a(j4), a(j5))
'---------- 1回目の演算の表示 ----------
Sheet1.Cells(row, col + 0) = OperationText(i0)
Sheet1.Cells(row, col + 1) = a(j0)
Sheet1.Cells(row, col + 2) = a(j1)
col = col + 3
If i0 = 3 And Math.Abs(a(j1)) < epsilon Then
Sheet1.Cells(row, col) = "Divided by Zero"
GoTo label
End If
'---------- 2回目の演算の表示 ----------
Sheet1.Cells(row, col + 0) = OperationText(i1)
Sheet1.Cells(row, col + 1) = a(j2)
Sheet1.Cells(row, col + 2) = a(j3)
col = col + 3
If i1 = 3 And Math.Abs(a(j3)) < epsilon Then
Sheet1.Cells(row, col) = "Divided by Zero"
GoTo label
End If
'---------- 3回目の演算の表示 ----------
Sheet1.Cells(row, col + 0) = OperationText(i2)
Sheet1.Cells(row, col + 1) = a(j4)
Sheet1.Cells(row, col + 2) = a(j5)
col = col + 3
If i2 = 3 And Math.Abs(a(j5)) < epsilon Then
Sheet1.Cells(row, col) = "Divided by Zero"
GoTo label
End If
'------------------------------
Sheet1.Cells(row, 10) = a(6)
label:
row = row + 1
col = 1
End If
Next j5
End If
Next j4
Next i2
'------------------------------
End If
Next j3
End If
Next j2
Next i1
'------------------------------
End If
Next j1
Next j0
Next i0
'------------------------------
End Sub