数日前 、難解なプログラミング言語であるBefungeをいじりました。Befunge は LIFO スタックを使用してデータを保存します。プログラムを書くとき、0 から 9 までの数字は、実際には、対応する値をスタックにプッシュする Befunge 命令です。たとえば、これは 7 をスタックにプッシュします。
34+
9 より大きい数値をプッシュするには、9 以下の数値で計算を行う必要があります。これにより、123 が得られます。
99*76*+
オイラー問題 1を Befunge で解決しているときに、かなり大きな数値 999 をスタックにプッシュする必要がありました。ここで、できるだけ少ない指示でこのタスクを達成するにはどうすればよいか考え始めました。用語を中置記法で書き留め、思いついた共通因数を取り出すことで
9993+*3+*
999 を生成する 2 つの 2 桁の数を単純に乗算することもできます。
39*66*1+*
これについてしばらく考えた後、与えられた整数に対して逆ポーランド記法でこれらの規則に従って最小の式を出力するプログラムを作成することにしました。これは私がこれまでに持っているものです(underscorejsでNodeJSで書かれています):
var makeExpr = function (value) {
if (value < 10) return value + "";
var output = "", counter = 0;
(function fn (val) {
counter++;
if(val < 9) { output += val; return; };
var exp = Math.floor(Math.log(val) / Math.log(9));
var div = Math.floor(val / Math.pow(9, exp));
_( exp ).times(function () { output += "9"; });
_(exp-1).times(function () { output += "*"; });
if (div > 1) output += div + "*";
fn(val - Math.pow(9, exp) * div);
})(value);
_(counter-1).times(function () { output+= "+"; });
return output.replace(/0\+/, "");
};
makeExpr(999);
// yields 999**99*3*93*++
このコードは単純に式を構成しているため、明らかに長すぎます。今私の質問:
- 逆ポーランド記法で式を簡略化するアルゴリズムはありますか?
- 簡略化は中置記法の方が簡単ですか?
- のような式は
9993+*3+*
可能な限り最小のものであると証明できますか?
いくつかの洞察を与えることができれば幸いです。前もって感謝します。