昨日は、算数パズルを汎用的に解けることを目標に、様々な情報を抽出してみた。
infoment.hatenablog.com
今回は、先日抽出したものをクラスモジュールに移植して、
更にあれこれといじってみた。
とは言え、未だ道半ば。何となく見えてきたような気がするが、今日はここまで。
クラスモジュール(ArithmeticPuzzleClass)
Option Explicit Enum CalculationType my足し算 my引き算 my掛け算 my割り算 End Enum Dim myReg As RegExp Dim MatchCase As MatchCollection Dim mySubMatches As SubMatches Dim Digits As Long Dim CharacterDict As Dictionary Private Sub Class_Initialize() Set myReg = New RegExp myReg.Pattern = "(.+)([+-×÷/])(.+)(=)(.+)" Set CharacterDict = New Dictionary End Sub Public Sub init(Equation As String) Equation = StrConv(Equation, vbWide) If myReg.test(Equation) Then Set MatchCase = myReg.Execute(Equation) Set mySubMatches = MatchCase(0).SubMatches End If Digits = 1 Dim i As Long Dim j As Long Dim s As String For i = 0 To 2 For j = 1 To Len(mySubMatches(i)) s = Mid(mySubMatches(i), j, 1) If CharacterDict.Exists(s) = False Then CharacterDict(s) = Digits Digits = Digits + 1 End If Next Next Digits = Digits - 1 End Sub Public Property Get myOperator() As CalculationType Select Case mySubMatches(1) Case "+": myOperator = my足し算 Case "-": myOperator = my引き算 Case "×": myOperator = my割り算 Case "÷", "/": myOperator = my割り算 End Select End Property Public Property Get iMin() As Long iMin = 10 ^ (Digits - 1) End Property Public Property Get iMax() As Long iMax = 10 ^ Digits - 1 End Property Function CheckDuplication(val As Long) As Boolean Dim Dict As Dictionary Set Dict = New Dictionary Dim i As Long For i = 1 To Digits If Dict.Exists(Mid(val, i, 1)) Then CheckDuplication = True Exit For Else Dict(Mid(val, i, 1)) = Mid(val, i, 1) End If Next End Function
標準モジュール
Sub 算数パズル() Dim APC As ArithmeticPuzzleClass Set APC = New ArithmeticPuzzleClass APC.init "かき×くう=きゃく" Dim か As Long Dim き As Long Dim く As Long Dim う As Long Dim や As Long Dim 乗数 As Long Dim 被乗数 As Long Dim 答え As Long Dim i As Long Dim j As Long For i = APC.iMin To APC.iMax j = j + 1 か = Mid(i, 1, 1) き = Mid(i, 2, 1) く = Mid(i, 3, 1) う = Mid(i, 4, 1) や = Mid(i, 5, 1) If か <> 0 And き <> 0 And く <> 0 Then 乗数 = か * 10 + き 被乗数 = く * 10 + う 答え = き * 100 + や * 10 + く If 乗数 * 被乗数 = 答え Then If APC.CheckDuplication(i) = False Then Debug.Print "か:" & か & vbNewLine & _ "き:" & き & vbNewLine & _ "く:" & く & vbNewLine & _ "う:" & う & vbNewLine & _ "や:" & や & vbNewLine End If End If End If Next End Sub
現時点で、正解は出せている。
引き続き、検討を進める。
明日に続きます。
参考まで。