Ruby Cadet Club #1

Original 99/02/16, by guel

[ruby] RPN 電卓

えーと、私の最初の 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 ^



RPN 電卓, AWK 版

比較のために、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$


RPN 電卓, Perl 版

比較のために、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.