わさっきhb

大学(教育研究)とか ,親馬鹿とか,和歌山とか,とか,とか.

Rubyで(63÷21)×18−27+53 = 35+72−81×(12÷36)

No.24

(63÷21)×18−27+53 = 35+72−81×(12÷36)

umashika-news.jp -&nbspumashika-news リソースおよび情報

へえ.先日Rubyスクリプトで動作確認してみましょう.

$ ruby pmtd-parser-no_tw.rb "(63÷21)×18-27+53"
(63÷21)×18-27+53=80

$ ruby pmtd-parser-no_tw.rb "35+72-81×(12÷36)"
35+72-81×(12÷36)=107

あれ,合いません.どうやら,12÷36を0と評価してしまうのが問題のようです.
ではスクリプトをいじりましょう.整数と加減乗除なので,有理数が扱えれば十分です.Rubyでは,「require "rational"」とすることで,Rationalクラスが使用できます.
出来上がりは,またもgistに置いています.今回も,syntax.rbは必要です.

前のスクリプトで,文字列を整数値に変換しているのは,インスタンス変数@numの中の

      val = x.join.to_i()

でした.これを

      val = Rational(x.join)

とすると,Ruby 1.9では問題なく動作しましたが,1.8ではエラーになります.

      val = Rational(x.join.to_i)

とすることで,Ruby 1.8/1.9両対応になりました.
次に,Rationalのインスタンスの出力は,整数値になる場合でも「80/1」のように,分母が表示されてしまいます.これは,Rational#to_sの定義を上書きしました.
あとちょっと欲張って,入力の数字やプラスマイナス,それとカッコは,日本語文字でもいいことにしてみました.これをASCII文字に変換するのに,String#trを使ったのですが,Ruby 1.9では文字単位,1.8ではバイト単位なのを忘れていて,訳の分からない出力になり苦労しました.Ruby 1.8では,jcodeをロードすることで,解決しました.
出力は次のとおり.12÷36が「1/3」になっています.

$ ruby -v
ruby 1.8.8dev (2011-03-03) [i386-cygwin]

$ ruby pmtd-parser-rational.rb
(63÷21)×18-27+53=80
35+72-81×(12÷36)=80

$ ruby -d pmtd-parser-rational.rb
(略)
expr2: x=[Rational(12, 1), [["÷", Rational(36, 1)]]]:Array, val=1/3
expr: x=[Rational(1, 3), []]:Array, val=1/3
prim_par: x=["(", Rational(1, 3), ")"]:Array, val=1/3
prim2: x=[Rational(1, 3), []]:Array, val=1/3
prim3_num: x=Rational(1, 3):Rational, val=1/3
expr2: x=[Rational(81, 1), [["×", Rational(1, 3)]]]:Array, val=27
expr: x=[Rational(35, 1), [["+", Rational(72, 1)], ["-", Rational(27, 1)]]]:Array, val=80
80