逆ポーランド記法の電卓をつくる

20円の商品を9つ、5円の商品を7つに消費税5%加算した金額はいくらだというのを普通電卓で計算しようとすると、

20×9を計算してM+、5×7を計算してM+、MRで2つを足した結果を呼び出して×1.05などすると思う。

まぁめんどくさいなぁと思うところだが、まだM+があるからなんとかなってる。


大概の関数電卓なら式を打ち込んで計算できて便利ですね。

ただ、そういう機能を持った電卓を作ろうと考えると難しい。

普通電卓なら作るのは簡単だけど、それではおもしろくないと。

そう思ってArduinoで作った電卓では逆ポーランド記法で入力するようにした。


逆ポーランド記法というのは演算子を後ろに書く方法ですね。

1+2と演算子を真ん中におくのが中置記法、+ 1 2 と演算子を前に置くのがポーランド記法、

まぁこの2つはよくありそうな表記だけど、1 2 +と演算子を後ろに置く逆ポーランド記法は不気味。

ただ、1と2を足して という風に口で言うのと同じような並びになってるので意外と打ちやすいし、

あと式を受けとった後の処理が非常に便利だというのが非常にうれしい。

ポーランド記法・逆ポーランド記法ともに括弧を省略してもうまく表すことが出来る。

(1+2)×(3+4)は逆ポーランド記法だと 1 2 + 3 4 + * と表すことができる。括弧無しでうまくいくのは処理が易しい理由の1つか。


処理が便利だというのは、数字を受け取った時はスタックにpushして、演算子を受け取った時はスタックからpopして計算して結果をpushするだけで済むから。

1 2 + 3 4 + * を例にとって考えてみる。

まず1をpushしてスタックが[1]となり、2をpushして[1,2]となる、ここで+を受け取ったら2つpopして1と2を取り出して足して3をpushしてスタックは[3]に。

次に3、4をpushして[3,3,4]、ここで+を受け取ったら2つpopして3と4を取り出して、足した7をpushして[3,7]、

ここで*を受け取ったら2つpopして3と7を取り出して21をpushして最終的に[21]となって、この計算ができた。

括弧のことを考えなくてよくて、演算子を受け取ったら受け取った時にその計算をすればいいというのがうれしい。


そんなわけでRubyでそんな電卓を作ってみた。

p gets.split(/\s+/).inject([]){|s,x|
  if    x=='+'
    t=s.pop;s.push(s.pop+t)
  elsif x=='-'
    t=s.pop;s.push(s.pop-t)
  elsif x=='*'
    t=s.pop;s.push(s.pop*t)
  elsif x=='/'
    t=s.pop;s.push(s.pop/t)
  else
    s.push(x.to_f)
  end
  s
}

たったこんなけで大概の四則演算はできる計算機が作れるってんだからうれしいね。

getsで入力された文字列を空白で区切って、区切ったそれぞれについて演算子ならスタックにpopして計算してpush、数字ならそれをpushするということをしているだけ。

ここに最初に書いた例を計算してみよう。

20 9 * 5 7 * + 1.05 * と入力すればよい。そしたら225.75と出てきた。

普通電卓ならM+を使わないとできなかった計算がそのまま入力できた。


ただ電卓を作ってもおもしろくないが、スタックを用意して少し工夫するだけで出来ることは広がる。

実におもしろい。

まぁこれが普段計算するのに便利なのかといわれると、便利な時もあるし不便な時もあるというのが答えかなと。

ただ、逆ポーランド記法の電卓はマニアには人気があるそうだから、意外と便利なのかも知れない。