Page 69 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 通常モードに戻る ┃ INDEX ┃ ≪前へ │ 次へ≫ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ▼計算式をつくるには おらんじゅ 02/9/10(火) 22:20 ┣Re:計算式をつくるには こうちゃん 02/9/11(水) 10:10 ┣大きく分けて2通り JuJu 02/9/11(水) 13:14 ┗Re:計算式をつくるには 禰宜 02/9/11(水) 23:00 ┗Re:計算式をつくるには おらんじゅ 02/9/12(木) 21:08 ─────────────────────────────────────── ■題名 : 計算式をつくるには ■名前 : おらんじゅ ■日付 : 02/9/10(火) 22:20 -------------------------------------------------------------------------
ab × c ~~~~~~ de +fg ~~~~~~ hi という式で、a〜iまでに1〜9の数字を一度だけ使用して 計算式を成り立たせたいのですが、 VBAではどのようにつくったらいいのでしょうか。 関数などで考えてみたのですが、どうしても出来ません。 よろしくお願いいたします。 |
おらんじゅ さん、こんにちは > ab >× c >~~~~~~ > de >+fg >~~~~~~ > hi > >という式で、a〜iまでに1〜9の数字を一度だけ使用して >計算式を成り立たせたいのですが、 VBAではどのようにつくったらいいのでしょうか。 > >関数などで考えてみたのですが、どうしても出来ません。 >よろしくお願いいたします。 かなり冗長ですが、ゴリゴリとプロシージャ作ってみました。 標準モジュールに貼り付けて、実行してみてください。 ロジックももっとエレガントにしないといかんですが・・・^^; #このロジックでは組み合わせは1通りしか探せなかったけど、正解かなぁ(??) Sub test() Dim j As Integer Dim k As Integer Dim l As Integer Dim m As Integer Dim n As Integer Dim DE As Integer Dim HI As Integer For j = 1 To 9 For k = 1 To 9 For l = 1 To 9 DE = ABCD(Trim(CStr(j)), Trim(CStr(k)), Trim(CStr(l))) If DE > 0 Then For m = 1 To 9 For n = 1 To 9 HI = DEFG(Trim(CStr(j)), Trim(CStr(k)), _ Trim(CStr(l)), Left(Trim(CStr(DE)), 1), _ Right(Trim(CStr(DE)), 1), Trim(CStr(m)), _ Trim(CStr(n))) If HI > 0 Then MsgBox j & k & l & _ Left(Trim(CStr(DE)), 1) & _ Right(Trim(CStr(DE)), 1) & _ m & n & _ Left(Trim(CStr(HI)), 1) & _ Right(Trim(CStr(HI)), 1) End If Next Next End If Next Next Next End Sub Function DEFG(A As String, B As String, C As String, _ D As String, E As String, F As String, G As String) As Integer Dim DE As Integer Dim FG As Integer Dim HI As Integer Dim HH As String Dim II As String DE = CInt(D & E) FG = CInt(F & G) HI = DE + FG If A = B Or A = C Or A = D Or A = E Or A = F Or A = G _ Or B = C Or B = D Or B = E Or B = F Or B = G _ Or C = D Or C = E Or C = F Or C = G _ Or D = E Or D = F Or D = G _ Or E = F Or E = G _ Or F = G _ Then DEFG = 0 Exit Function End If If HI > 98 Then DEFG = 0 Else HH = Left(Trim(CStr(HI)), 1) II = Right(Trim(CStr(HI)), 1) If HH <> A And HH <> B And HH <> C And HH <> D And _ HH <> E And HH <> F And HH <> G And _ II <> A And II <> B And II <> C And II <> D And _ II <> E And II <> F And II <> G And _ HH <> II And _ HH <> "0" And _ II <> "0" _ Then DEFG = HI Else DEFG = 0 End If End If End Function Function ABCD(A As String, B As String, C As String) As Integer Dim AB As Integer Dim DE As Integer Dim DD As String Dim EE As String AB = CInt(A & B) DE = AB * CInt(C) If A = B Or A = C Or B = C Then ABCD = 0 Exit Function End If If DE > 87 Then ABCD = 0 Else DD = Left(Trim(CStr(DE)), 1) EE = Right(Trim(CStr(DE)), 1) If DD <> A And DD <> B And DD <> C And _ EE <> A And EE <> B And EE <> C And _ DD <> EE And _ DD <> "0" And _ EE <> "0" _ Then ABCD = DE Else ABCD = 0 End If End If End Function |
おらんじゅさん、こんにちはぁ > ab >× c >~~~~~~ > de >+fg >~~~~~~ > hi >という式で、a〜iまでに1〜9の数字を一度だけ使用して >計算式を成り立たせたいのですが、 VBAではどのようにつくったらいいのでしょうか。 方法は大きく分けて2種類あります。 1.1〜9の数字を全パターン入れて、式が正しいか評価する。 2.式が正しい数字を入れて、1〜9の数字になっているか評価する。 ほとんどの場合、2の方が繰り返し回数が少ないので速いです。 1.1〜9の重複しない数字を求める方法はいろいろありますが、一例として、 Sub Macro1() Shuffle "123456789" End Sub Sub Shuffle(ByVal strData As String, Optional ByVal lngNum As Long = 1) Dim strTmp As String Dim strC As String Dim i As Long If lngNum < Len(strData) Then '' シャッフル For i = lngNum To Len(strData) strTmp = strData If i <> lngNum Then strC = Mid(strTmp, i, 1) Mid(strTmp, i, 1) = Mid(strTmp, lngNum, 1) Mid(strTmp, lngNum, 1) = strC End If Shuffle strTmp, lngNum + 1 Next Else '' 判定 If CLng(Mid(strData, 1, 2)) * CLng(Mid(strData, 3, 1)) = CLng(Mid(strData, 4, 2)) And _ CLng(Mid(strData, 4, 2)) + CLng(Mid(strData, 6, 2)) = CLng(Mid(strData, 8, 2)) Then MsgBox strData End If End If End Sub 総当りなので、かなり遅いと思います。 そのかわりに、式が変更になっても修正が簡単です。 (わかりやすいように文字列で処理しています) 2.ab, c, fg だけ総当り、de, hi は式から計算 Sub Macro2() Dim ab As Long, c As Long, de As Long, fg As Long, hi As Long Dim p(1 To 9) As Long Dim flags(1 To 9) As Boolean Dim j As Long For ab = 12 To 98 For c = 1 To 9 For fg = 12 To 98 de = ab * c hi = de + fg If de <= 98 And hi <= 98 Then p(1) = ab \ 10 p(2) = ab Mod 10 p(3) = c p(4) = de \ 10 p(5) = de Mod 10 p(6) = fg \ 10 p(7) = fg Mod 10 p(8) = hi \ 10 p(9) = hi Mod 10 For j = LBound(flags()) To UBound(flags()) flags(j) = False Next For j = LBound(p()) To UBound(p()) If 1 <= p(j) And p(j) <= 9 Then If flags(p(j)) Then Exit For flags(p(j)) = True Else Exit For End If Next If j > UBound(p()) Then MsgBox p(1) & p(2) & p(3) & p(4) & p(5) & p(6) & p(7) & p(8) & p(9) End If End If Next Next Next End Sub >#このロジックでは組み合わせは1通りしか探せなかったけど、正解かなぁ(??) 私も1通りなので、多分正解かなぁ 重複判断って面倒くさいですね^^; 横レスごめんね。実は昨日から考えてたの^^; ではではぁ |
失礼いたします。 こんな感じでもOKかな? まず積の部分(上5桁)を条件に処理し、 その後、和の部分(下4桁)を処理するというのが 早く処理する第一歩かもしれません。 Sub Part_1() Dim i As Long Dim t As Integer Dim Flag_1 As Boolean For i = 12345 To 98765 If InStr(CStr(i), "0") = 0 Then If Val(Left(i, 2)) * Val(Mid(i, 3, 1)) = Val(Mid(i, 4, 2)) Then Flag_1 = True For t = 1 To 9 If InStr(CStr(i), t) <> InStrRev(CStr(i), t) Then Flag_1 = False Exit For End If Next If Flag_1 = True Then Call Part_2(i) End If End If Next End Sub Private Sub Part_2(k As Long) Dim m As Long Dim n As Integer Dim Flag_2 As Boolean For m = k * 10000 + 1234 To k * 10000 + 9876 If InStr(CStr(m), "0") = 0 Then If Val(Right(k, 2)) + Val(Mid(m, 6, 2)) = Val(Right(m, 2)) Then Flag_2 = True For n = 1 To 9 If InStr(CStr(m), n) <> InStrRev(CStr(m), n) Then Flag_2 = False Exit For End If Next If Flag_2 = True Then MsgBox CStr(m) End If End If Next End Sub [Part_1]と[Part_2]があり、Part_2はPrivateです。 Part_1を実行するとOKです。 他の方と同様に答えは1つでした。 では。 |
こうちゃんさん、jujuさん、禰宜さん、こんなに早いご回答感謝です! 私は初心者なもので、それぞれのマクロを理解するのに時間がかかってしまいまして・・・。 勉強になりました!どうもありがとうございました! |