はじめに
同僚に「1、1、9、9」の4つの数字を四則演算して10をつくれるかという問題を出されて、30分くらい考えたけど、結局解けませんでした。
Googleで調べればすぐに答えは分かるのですが、それではおもしろくないのでJavaScriptで力技で計算するプログラムを作ってみました。
参考にしたサイト
このプログラムを作成するにあたり、以下を参考にしました。
作成する際のポイント
アルゴリズムが分からなくて非常に苦労しましたが、以下のサイトに非常に詳しく書いてあります。perlのサンプルコードもあります。
4つの数字を a,b,c,d とし、四則演算子を op1,op2,op3 と表したとき、
それらを組み合わせて出来る計算式は次の通りである。*1 op3 d
a op1 *2
あとは、重複しない1〜9までの4つの数字の順列に
- ,-,*,/ の複数使用可能な4つの演算子の中から3つの順列を当てはめて、
それぞれ a〜d,op1〜op3 とし、上の5つの式を計算して 10 になることを確かめればよい。
めも日記(2004-08-28)
HTML
<!DOCTYPE html> <html lang="ja"> <head> <meta charset="utf-8"> <title>4つの数字で10にする</title> <script src="calc.js"></script> </head> <body> <form> <input type="text" id="value1" value="4"> <input type="text" id="value2" value="6"> <input type="text" id="value3" value="3"> <input type="text" id="value4" value="7"> <input type="button" id="calc" value="計算する"> <div id="result"> </div> </form> </body> </html>
Javascript
var calc = { n1:"", n2:"", n3:"", n4:"", calculate: function() { var number = Array(this.n1, this.n2, this.n3, this.n4); var usedNumber; var tmp = ""; var n1, n2, n3, n4; var countN1 = getCount(number, this.n1); var countN2 = getCount(number, this.n2); var countN3 = getCount(number, this.n3); var countN4 = getCount(number, this.n4); for (var i = 0, len = number.length; i < len; i++) { n1 = number[i]; usedNumber = new Array(4); usedNumber[0] = n1; for (var j = 0; j < len; j++) { n2 = number[j]; usedNumber[1] = n2; for (var k = 0; k < len; k++) { n3 = number[k]; usedNumber[2] = n3; for (var l = 0; l < len; l++) { n4 = number[l]; usedNumber[3] = n4; // 数字の個数を数えて全部そろったら演算する if (getCount(usedNumber, this.n1) === countN1) { if (getCount(usedNumber, this.n2) === countN2) { if (getCount(usedNumber, this.n3) === countN3) { if (getCount(usedNumber, this.n4) === countN4) { tmp += calculateEx(n1, n2, n3, n4); } } } } } } } } return tmp; function getCount(array, x) { var count = 0; for (var i = 0, len = array.length; i < len; i++) { if (array[i] === x) { count++; } } return count; } function calculateEx(n1, n2, n3, n4) { var enzanshi = Array("+", "-", "*", "/"); var opt1, opt2, opt3, shiki, answer; var tmp = ""; for (var i = 0, len = enzanshi.length; i < len; i++) { opt1 = enzanshi[i]; for (var j = 0; j < len; j++) { opt2 = enzanshi[j]; for (var k = 0; k < len; k++) { opt3 = enzanshi[k]; // ((a op1 b) op2 c) op3 d shiki = "((" + n1 + opt1 + n2 + ")" + opt2 + n3 + ")" + opt3 + n4; if (answer === 10) { tmp += answer + " = " + shiki + "<br>"; } // (a op1 b) op2 (c op3 d) shiki = "(" + n1 + opt1 + n2 + ")" + opt2 + "(" + n3 +opt3 + n4 + ")"; answer = eval(shiki); if (answer === 10) { tmp += answer + " = " + shiki + "<br>"; } // (a op1 (b op2 c)) op3 d shiki = "(" + n1 + opt1 + "(" + n2 + opt2 + n3 +"))" + opt3 + n4; answer = eval(shiki); if (answer === 10) { tmp += answer + " = " + shiki + "<br>"; } // a op1 ((b op2 c) op3 d) shiki = n1 + opt1 + "((" + n2 + opt2 + n3 +")" + opt3 + n4 + ")"; answer = eval(shiki); if (answer === 10) { tmp += answer + " = " + shiki + "<br>"; } // a op1 (b op2 (c op3 d)) shiki = n1 + opt1 + "(" + n2 + opt2 + "(" + n3 + opt3 + n4 + "))"; answer = eval(shiki); if (answer === 10) { tmp += answer + " = " + shiki + "<br>"; } } } } return tmp; } } }; window.onload = function() { document.getElementById("calc").onclick = function() { calc.n1 = document.getElementById("value1").value; calc.n2 = document.getElementById("value2").value; calc.n3 = document.getElementById("value3").value; calc.n4 = document.getElementById("value4").value; document.getElementById("result").innerHTML = calc.calculate(); alert("end"); } }