私が持ってる玩具でジャマイカというのがあるのですが

http://www.masudaya.com/product/jamaica.html
これの最適解をExcelマクロで出す方法を考えてください。
詳細はコメント参照。

回答の条件
  • 1人2回まで
  • 登録:
  • 終了:2009/10/28 15:36:43
※ 有料アンケート・ポイント付き質問機能は2023年2月28日に終了しました。

ベストアンサー

id:Mook No.1

回答回数1314ベストアンサー獲得回数393

ポイント60pt

面白そうなので一応作成してみました。


Shoot で初期化、Jamaica で回答を表示します。

実際の計算をしているのは JCalc の部分です。

Option Explicit

'//-------------------------------------------
'// True  ・・・ 完全一致のみ表示
'// False ・・・ 最も近い計算値を表示
Const CompleteMatch = True

Public Goal As Double       '// 目標値(黒ダイスの合計)
Public Nqueue(5) As Double  '// 白ダイス
Public OutRow As Long       '// 結果出力行
Public NearNum As Double    '// 近似解表示字の最近値

Sub Shoot()
'-----------------------------------------------------------------
    Columns("B").Value = ""
    
    Dim c
    For Each c In Array("D1", "D2", "D3", "D4", "D5", "F2")
        Range(c).Value = Int(Rnd() * 6) + 1
    Next
    Range("F1").Value = 10 * (Int(Rnd() * 6) + 1)
End Sub

'-----------------------------------------------------------------
Sub Jamaica()
'-----------------------------------------------------------------
    Dim c, ns, i As Long
    
    ns = Array("D1", "D2", "D3", "D4", "D5")
    For i = 0 To 4
        Nqueue(i) = CDbl(Range("Num" & i + 1))
    Next
    Nqueue(5) = 1
    Goal = CDbl(Range("F1").Value + Range("F2").Value)
    
    If CompleteMatch = True Then
        NearNum = Goal
        Range("B2") = "NO ANSWER"
        OutRow = 2
    Else
        NearNum = 0
    End If
    
    JCalc Nqueue(0), 0, CStr(Nqueue(0))
End Sub

'-----------------------------------------------------------------
Sub JCalc(num As Double, ByVal index As Integer, exp As String)
'-----------------------------------------------------------------
    If index = 4 Then
        If Abs(Goal - NearNum) > Abs(Goal - num) Then
            NearNum = num
            OutRow = 2
            Columns("B") = ""
        End If
        
        If num = NearNum Then
            Cells(OutRow, "B").Value = exp & " = " & num
            OutRow = OutRow + 1
        End If
        Exit Sub
    End If
    
    index = index + 1
    JCalc num + Nqueue(index), index, "(" & exp & " + " & Nqueue(index) & ")"
    JCalc num - Nqueue(index), index, "(" & exp & " - " & Nqueue(index) & ")"
    JCalc num * Nqueue(index), index, "(" & exp & " * " & Nqueue(index) & ")"
    JCalc num / Nqueue(index), index, "(" & exp & " / " & Nqueue(index) & ")"
    JCalc Nqueue(index) - num, index, "(" & Nqueue(index) & " - " & exp & ")"
    If num <> 0 Then JCalc Nqueue(index) / num, index, "(" & Nqueue(index) & "/" & exp & ")"
End Sub

GUI を付けたファイルを公開しましたので、興味あったらご覧ください。

http://d.hatena.ne.jp/Mook/20091027

  • id:kine2525
    11/2ぐらいをを締め切りとして、きちんと動作して最も短いマクロを書いた人に最大ポイントを進呈します。
    つまり通常の人力検索と違い後出しが有利なシステムになってます。

    以前Excelマクロを覚えたての頃につくりかけて断念した経緯があり、
    今なら頑張れば作れそうですが、皆さんのプログラムで勉強したいので問題として提出することにしました。

    なお、足し算と掛け算の中身の重複する回答は省くようにしてください(たとえば4*5+3+2と2+3+5*4は同一)
  • id:SALINGER
    これは、真ん中の黒が10~60、他が1~6でしょうか?
    ()は使えないということになりますか?
  • id:kine2525
    上の行はそうです、6面サイコロを使います。説明不足すみません・・・
    たとえば黒で50と3が出たら、残りの白数字で53になるように組み合わせる感じです。

    あと下の行、「白で出た数字を組み合わせて黒数字を作る」という考えなので()を使った計算も当然アリです。
    それがマクロを作るのを難しくしてる要因でもありまして、多分逆ポーランド記法の木構造あたりの考えを使ったらいいのかなと。
     
  • id:Mook
    できたと思っていましたが、計算パターンがもれてるようです。
    修正できたらコメントしますので、それまでオープンしないでください。
  • id:kine2525
    ごめんなさい!
    こちらの過失で間違ってオープンしてしまったので一旦打ち切り、Mookさんにはポイントといるか賞を差し上げます。

    なお質問はこちらに移動しました。
    http://q.hatena.ne.jp/1256711755
  • id:Mook
    かえってお手数をかけてしまってすみません。

この質問への反応(ブックマークコメント)

トラックバック

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

回答リクエストを送信したユーザーはいません