えーと、私の最初の ruby です。(^-^)
機能は四則演算のみです。
毎回、演算後にスタックを表示します。数字を入力してリターンすると、スタックに入ります。いくらでも次々入ります。演算子を入力、リターンすると、計算結果がスタックに入ります。
入力は1行で連続して行うこともできます。 例えば、
1 2 3 4 5 + + リターン
など。
#---------------------------------------------------------- rpn.rb ^ print "RPN CALC of ruby, ready. created by guel 02/14/99\n"; stack = [] while gets split.each do |x| begin case x when /\d/ stack.push(x.to_f) when '+' stack.push(stack.pop + stack.pop) when '*' stack.push(stack.pop * stack.pop) when '-' stack.push(- (stack.pop - stack.pop)) when '/' stack.push(1 / (stack.pop / stack.pop)) else p x print "hey!\n" end rescue print "error, pop empty stack.\n" end end p stack end #---------------------------------------------------------- rpn.rb ^ |
比較のために、AWK 版はこーなります。
#---------------------------------------------------------- rpn.awk^ # RPN CALC of awk by guel 02/16/99 BEGIN { print "RPN CALC of awk, ready." # stack[t = 0] = 0 } { for (i = 1; i<= NF; i++) { if (isNum($i)) { push($i) } else if ($i == "+") { push(pop() + pop()) } else if ($i == "*") { push(pop() * pop()) } else if ($i == "-") { push(- (pop() - pop())) } else if ($i == "/") { push(1 / (pop() / pop())) } } printf("[ ") for (i = 0; i < t; i++) printf("%g ", stack[i]) printf("]\n") } # AWK には、push, pop は無いンで作る。 function push(x) { stack[t++] = x } function pop() { if (t > 0) return stack[--t] else printf("error: poped empty stack\n") } function isNum(x) { return match(x, /^[+-]?[0-9]+$/) } #---------------------------------------------------------- rpn.awk$ |
比較のために、Perl 版はこーなります。
こちらはあんまし、自信はありませぬ。Perl は普段それほどつかっていないモンで。。
3パターン、変なところは遠慮なツッコんでくださいませ。(^-^)/※ 予想に反して、ruby がもっとも行数を節約できました。
#---------------------------------------------------------- rpn.pl ^ # RPN CALC of Perl, by guel 02/16/99 print "RPN CALC of Perl, ready. by guel\n"; while (<>) { chop; foreach (split) { if (&isNum($_)) { &Push($_) } elsif ($_ eq '+') { &Push(&Pop() + &Pop()) } elsif ($_ eq '-') { &Push(- (&Pop() - &Pop())) } elsif ($_ eq '*') { &Push(&Pop() * &Pop()) } elsif ($_ eq '/') { &Push(1 / (&Pop() / &Pop())) } } print "[ ",join(" ",@stack), " ]\n"; } # Perl には push, pop はあるンだけど、ママでは気に入らないので少し変える。 sub Push { push(stack, $_[0]); } sub Pop { if ($#stack > -1) { return pop(stack); } else { printf "error: poped empty stack\n"; } } sub isNum { /^[+\-]?\d+$/ } # 正負|整数部|小数部|指数部 #---------------------------------------------------------- rpn.pl $ |
こうやって3つならべると、それぞれのキャラクターが分かりますね。
私は ruby が一番見た目がすっきりして見やすいと思いますがどうでしょう。
Count (03/21/1999) ->
update 03/21/1999, since 02/16/1999
Copyright (c) 1999 guel. All rights reserved.