#!/usr/bin/ruby

#
## https://rosettacode.org/wiki/Parsing/RPN_to_infix_conversion
#

func p(pair, prec) {
    pair[0] < prec ? "( #{pair[1]} )" : pair[1];
}

func rpm_to_infix(string) {
    say "#{'='*17}\n#{string}";
    var stack = [];
    string.each_word { |w|
        if (w ~~ /\d/) {
            stack << [9, w.to_f];
        }
        else {
            var y = stack.pop;
            var x = stack.pop;
            given(w) {
              when ('^')   { stack << [4, [p(x,5), w, p(y,4)].join(' ')] }
              when (<* />) { stack << [3, [p(x,3), w, p(y,3)].join(' ')] }
              when (<+ ->) { stack << [2, [p(x,2), w, p(y,2)].join(' ')] }
            }
            say stack;
        }
    };
    '-'*17 -> say;
    stack.map{_[1]};
}

var tests = [
    '3 4 2 * 1 5 - 2 3 ^ ^ / +',
    '1 2 + 3 4 + ^ 5 6 + ^',
];

var results = [];
tests.each { results << rpm_to_infix(_).join(' '); say results[-1]; };

assert_eq(results, ['3 + 4 * 2 / ( 1 - 5 ) ^ 2 ^ 3', '( ( 1 + 2 ) ^ ( 3 + 4 ) ) ^ ( 5 + 6 )'])