From: tho_mica_l Date: 2007-12-03T01:25:03+09:00 Subject: Re: Postfix to Infix (#148) After trinking some coffee, I added functions and templates: class Quiz148 class << self def run(args) iqueue = args.map {|e| e.split(/\s+/)}.flatten return Quiz148.new(iqueue).process end end def initialize(iqueue) @iqueue = iqueue @depth = 0 @stack = [] @ops = { '+' => [10], '-' => [10, nil, [Object, String, false, true]], '*' => [5], '/' => [5], '%' => [5], '^' => [5, nil, [String, Numeric, true, false]], '**' => [5, nil, [String, Numeric, true, false]], 'sqrt' => [0, nil, [Object, true]], 'binom' => [5, '#{op}(#{val1}, #{val2})'], } @opnames = @ops.keys end def get_elt(op, idx=-1) val = @stack.delete_at(idx) case val when Array eop, val = val else eop = nil end if op and eop opp, *opatterns = @ops[op] eopp, *epatterns = @ops[eop] if opp != 0 and eopp > opp return '(%s)' % val end end return val end def process @iqueue.each do |token| if @opnames.include?(token) op = token opp, fmt, *patterns = @ops[op] if opp == 0 fmt ||= '#{op}#{val1}' val1 = get_elt(token, -1) patterns.each do |p1, e1| if val1.kind_of?(p1) val1 = '(%s)' % val1 if e1 break end end @stack << [token, eval("\"#{fmt}\"")] else fmt ||= '#{val1} #{op} #{val2}' val1 = get_elt(token, -2) val2 = get_elt(token, -1) patterns.each do |p1, p2, e1, e2| if val1.kind_of?(p1) and val2.kind_of?(p2) val1 = '(%s)' % val1 if e1 val2 = '(%s)' % val2 if e2 break end end @stack << [token, eval("\"#{fmt}\"")] end else @stack << eval(token) end end # The stack should include only one element here. A check would # be necessary. get_elt(nil) end end if __FILE__ == $0 if ARGV.empty? puts Quiz148.run('2 3 +') == '2 + 3' puts Quiz148.run('56 34 213.7 + * 678 -') == '56 * (34 + 213.7) - 678' puts Quiz148.run('1 56 35 + 16 9 - / +') == '1 + (56 + 35) / (16 - 9)' puts Quiz148.run('1 2 + 3 4 + +') == '1 + 2 + 3 + 4' puts Quiz148.run('1 2 - 3 4 - -') == '1 - 2 - (3 - 4)' puts Quiz148.run('1 3 4 - -') == '1 - (3 - 4)' puts Quiz148.run('2 2 ^ 2 ^') == '(2 ^ 2) ^ 2' puts Quiz148.run('2 2 2 ^ ^') == '2 ^ 2 ^ 2' puts Quiz148.run('2 sqrt 2 2 ^ ^') == 'sqrt(2) ^ 2 ^ 2' puts Quiz148.run('2 3 2 2 ^ ^ sqrt 3 + *') == '2 * (sqrt(3 ^ 2 ^ 2) + 3)' puts Quiz148.run('2 3 binom 2 2 ^ ^') == 'binom(2, 3) ^ 2 ^ 2' puts Quiz148.run('1 2 3 2 2 ^ ^ binom + 3 *') == '(1 + binom(2, 3 ^ 2 ^ 2)) * 3' puts Quiz148.run('2 3 2 2 ^ ^ binom') == 'binom(2, 3 ^ 2 ^ 2)' else puts Quiz148.run(ARGV) end end