この問題を解くプログラムを作ってください。誰でも無料で入手可能なら言語は問いません。また、ライブラリなどを使ってもいいです。その場合は、言語やライブラリの入手先のURLも教えてください。それから、VBAは無料じゃありませんが、Excelは、PCを買った時についてきたのでVBAも可とします。
●式を成り立たせる問題
http://homepage3.nifty.com/sugaku/sisoku.htm
rubyで書いてみました。
operator = ["+","-","*","/","=="] operator.permutation(5) {|a,b,c,d,e| s = "5.0#{a}4.0#{b}3.0#{c}2.0#{d}1.0#{e}0.0" begin puts s if eval(s) rescue end }
答えはこちらです。
5.0-4.0*3.0/2.0+1.0==0.0
5.0==4.0*3.0/2.0-1.0+0.0
Rubyは順列を作る関数や組み合わせを作る関数があるので便利ですね。
順列
http://ref.xaio.jp/ruby/classes/array/permutation
組み合わせ
JavaScriptによって力任せに解く方法です。
回答として表示される '*' は '×' に、'/' は '÷' に置き換えて読んでください。
<html> <head> <html lang="ja"> <head> <body> <script type="text/javascript"> <!-- //正解を表示 var tbl = new Array('+', '-', '*', '/', '=='); function check() { var i, c1, c2; var e = '5'; for (i = 0; i < n; i++) { c1 = tbl[p[i] - 1]; c2 = (n - i - 1); e = e + c1 + c2; } if (eval(e)) { e = e.replace('==', '='); document.write(e + '<br />'); } } //順列の生成 var n = 5; var p = new Array(n); var ok = new Array(n + 1); function perm(pos, k) { var j; p[pos] = k; if (pos == n - 1) { check(); } else { ok[k] = false; for (j = 1; j <= n; j++) { if (ok[j]) perm(pos + 1, j); } ok[k] = true; } } var i; for (i = 1; i <= n; i++) ok[i] = true; for (i = 1; i <= n; i++) perm(0, i); --> </script> </body> </html>
参考「eval」
回答ありがとうございます。コピペして拡張子をjsにしたらエラーでしたが、拡張子をhtmlにしてIE8で実行したら、うまく動きました。(^_^;
昔、ジャマイカという玩具の回答を出すプログラムを問う質問がありました。
数字は一つ少ないですが、数字の順番はバラバラで四則演算を自由に使えカッコも使っていいという
複雑なものでとても苦労して作った記憶があります。
http://q.hatena.ne.jp/1256711755
最後の演算子は÷にならないとか、小手先的な効率化は図ることはできるでしょうが、
これくらいだと逆にコードが長くなって効果も薄いでしょうし。
凝ったことは何もしてないので回答するのは恥ずかしいですが。
VBAです。
Sub macro() Dim str As String Dim str1 As String Dim str2 As String Dim str3 As String Dim str4 As String Dim res As String Dim i1 As Integer Dim i2 As Integer Dim i3 As Integer Dim i4 As Integer Dim h(4) As String str = "+-*/=" For i1 = 1 To 5 h(0) = Mid(str, i1, 1) str1 = Replace(str, h(0), "") For i2 = 1 To 4 h(1) = Mid(str1, i2, 1) str2 = Replace(str1, h(1), "") For i3 = 1 To 3 h(2) = Mid(str2, i3, 1) str3 = Replace(str2, h(2), "") For i4 = 1 To 2 h(3) = Mid(str3, i4, 1) h(4) = Replace(str3, h(3), "") res = "5" & h(0) & "4" & h(1) & "3" & h(2) & "2" & h(3) & "1" & h(4) & "0" If TypeName(Evaluate(res)) <> "Error" Then If Evaluate(res) = "True" Then Debug.Print res End If End If Next i4 Next i3 Next i2 Next i1 End Sub
回答ありがとうございます。Cですが、私が作ったのもこれに近かったです。(^_^;
rubyで書いてみました。
operator = ["+","-","*","/","=="] operator.permutation(5) {|a,b,c,d,e| s = "5.0#{a}4.0#{b}3.0#{c}2.0#{d}1.0#{e}0.0" begin puts s if eval(s) rescue end }
答えはこちらです。
5.0-4.0*3.0/2.0+1.0==0.0
5.0==4.0*3.0/2.0-1.0+0.0
Rubyは順列を作る関数や組み合わせを作る関数があるので便利ですね。
順列
http://ref.xaio.jp/ruby/classes/array/permutation
組み合わせ
回答ありがとうございます。やはり、ruby 最強ですかね。(^_^;
ruby でやってみた。
class Array def permutations(k=self.size) return [[]] if k < 1 perm = [] self.each do |e| x = self.dup x.delete_at(x.index(e)) x.permutations(k-1).each do |p| perm << ([e] + p) end end perm end end numbers = [5, 4, 3, 2, 1, 0] ["+", "-", "*", "/", "="].permutations.each { |operators| exp = "" operators.each_with_index { |e, i| exp << numbers[i].to_s + e } exp << numbers[5].to_s if /(.*)=(.*)/ =~ exp then begin if eval "#{$1} == #{$2}".gsub(/\d/, "\\&.0") then puts exp end rescue ZeroDivisionError # NOP end end }
手持ちの ruby が古いんで、Array.product が使えなくって、順列生成もコーディングした。
実行結果は、以下の通り。
5-4*3/2+1=0 5=4*3/2-1+0
回答直前に、式の評価が整数演算になってて、変な答えまで抽出してたので、ちょっとあわてた :-)
回答ありがとうございます。コピペして拡張子をrbにしてファイルを作って実行したら、ちゃんと動きました。こういう方法もあったんですね。(^_^;
やっつけですが、Perlだとこんな感じになりました。
※1÷0は計算できないため、1×0に変更してます。
#!/usr/bin/perl use strict; use warnings; my($left,$right,$kaihi); my @hoge; $hoge[1] = '+'; $hoge[2] = '-'; $hoge[3] = '*'; $hoge[4] = '/'; $hoge[5] = '='; for my $num1(1..5){ for my $num2(1..5){ for my $num3(1..5){ for my $num4(1..5){ for my $num5(1..5){ if($num1==$num2||$num1==$num3||$num1==$num4||$num1==$num5){ }elsif($num2==$num3||$num2==$num4||$num2==$num5){ }elsif($num3==$num4||$num3==$num5){ }elsif($num4==$num5){ }else{ if($hoge[$num5] eq '/'){ $kaihi = '*'; }else{ $kaihi = $hoge[$num5]; } if($hoge[$num1] eq '='){ $left = 5; $right= "4 $hoge[$num2] 3 $hoge[$num3] 2 $hoge[$num4] 1 $kaihi 0"; } if($hoge[$num2] eq '='){ $left = "5 $hoge[$num1] 4"; $right= "3 $hoge[$num3] 2 $hoge[$num4] 1 $kaihi 0"; } if($hoge[$num3] eq '='){ $left = "5 $hoge[$num1] 4 $hoge[$num2] 3"; $right= "2 $hoge[$num4] 1 $kaihi 0"; } if($hoge[$num4] eq '='){ $left = "5 $hoge[$num1] 4 $hoge[$num2] 3 $hoge[$num3] 2"; $right= "1 $kaihi 0"; } if($hoge[$num5] eq '='){ $left = "5 $hoge[$num1] 4 $hoge[$num2] 3 $hoge[$num3] 2 $hoge[$num4] 1"; $right= 0; } if(eval($left) == eval($right)){ print "5 $hoge[$num1] 4 $hoge[$num2] 3 $hoge[$num3] 2 $hoge[$num4] 1 $hoge[$num5] 0\n"; } } } } } } } exit;
実行結果
5 - 4 * 3 / 2 + 1 = 0
5 = 4 * 3 / 2 - 1 + 0
回答ありがとうございます。perlはまだインストールしていなかったので確認できませんでした。入手先のURLも付けてくれるとよかったです。(^_^;
言語はpython http://www.python.orgです
import itertools for c in itertools.permutations(['+', '-', '/', '*', '==']): expression = '5.0'+c[0]+'4.0'+c[1]+'3.0'+c[2]+'2.0'+c[3]+'1.0'+c[4]+'0.0' try: if eval(expression): print(expression.replace('==', '=').replace('.0', '')) except: continue
回答ありがとうございます。これもruby 並にすごいですね。でも、これもまだインストールしてなかったので確認できませんでした。(^_^;
入手先のURLも付けてくださってありがとうございます。
書いてて自己嫌悪に陥るような酷い回答ですが・・・
import random lst=['+','-','*','/','=='] res=False while res==False: random.shuffle(lst) exp='5.0'+lst[0]+'4.0'+lst[1]+'3.0'+lst[2]+'2.0'+lst[3]+'1.0'+lst[4]+'0.0' try: res=eval(exp) except: print(u'あばばばば') if res: print(exp.replace('==','=').replace('.0','')) break else: print(exp.replace('==','!=').replace('.0',''))
言語はPythonです。
回答ありがとうございます。やはりスクリプト系だと楽でいいですね。
入手先URLも日本語で分かりやすくてよかったです。
Python でリストの内包表記を使ってやってみました。
print([ ' '.join(['5.', a, '4.', b, '3.', c, '2.', d, '1.', e, '0.']) for e in set(['+','-','*','==']) for a in set(['+','-','*','/','==']) - set([e]) for b in set(['+','-','*','/','==']) - set([e, a]) for c in set(['+','-','*','/','==']) - set([e, a, b]) for d in set(['+','-','*','/','==']) - set([e, a, b, c]) if eval(' '.join(['5.', a, '4.', b, '3.', c, '2.', d, '1.', e, '0.']))])
出力
['5. - 4. * 3. / 2. + 1. == 0.', '5. == 4. * 3. / 2. - 1. + 0.']
http://www.python.jp/doc/2.4/tut/node7.html#SECTION0071400000000...
回答ありがとうございます。Ruby*2,Perl*1,Python*3ですね。(^_^;
参考URLもありがとうございます。
回答ありがとうございます。やはり、ruby 最強ですかね。(^_^;