From: Robert Dober Date: 2007-12-02T22:52:50+09:00 Subject: Re: Postfix to Infix (#148) Here goes my solution for this Quiz, I am confident that solutions 1 and 2 are correct, well 3 too, for 4 that is less sure ;). Nice to have a quiz which can be solved in less time again. Robert ############################### # Read postfix from args or stdin # Print an infix solution *without* paranthesis postfix = ARGV.empty? ? $stdin.read.split : ARGV postfix = postfix.map{ | ele | Integer( ele ) rescue ele } stack = [] postfix.each do | ele | case ele when Integer stack << ele else rhs = stack.pop stack[ -1 ] = stack[ -1 ].send( ele, rhs ) end end puts stack.first.to_s #########################################################" # Read postfix from args or stdin # Print an infix solution with *many* paranthesis postfix = ARGV.empty? ? $stdin.read.split : ARGV postfix = postfix.map{ | ele | Integer( ele ) rescue ele } stack = [] postfix.each do | ele | case ele when Integer stack << ele else rhs = stack.pop stack[ -1 ] = "( #{stack[ -1 ]} ) #{ele} ( #{rhs} )" end end puts stack.first ################################################## # Read postfix from args or stdin # Print an infix solution with *some* paranthesis # the stupid ( and expensive ) way. class Expression Combinations = [ ["", "", "", ""], ["( ", " )", "", ""], ["", "", "( ", " )"], ["( ", " )", "( ", " )"] ] attr_reader :text, :value def initialize text @value = Integer( text ) @text = text end def apply op, rhs new_text = "#@text #{op} #{rhs.text}" @value = @value.send( op, rhs.value ) Combinations.each do | parens | txt = ["", @text, " #{op} ", rhs.text ]. zip( parens ).flatten.join if eval( txt ) == @value then return @text = txt end end raise RuntimeError, "ooops" end end postfix = ARGV.empty? ? $stdin.read.split : ARGV postfix = postfix.map{ | ele | Expression.new( ele ) rescue ele } stack = [] postfix.each do | ele | case ele when Expression stack << ele else rhs = stack.pop stack.last.apply ele, rhs end end puts stack.first.text ############################################# # Read postfix from args or stdin # Print an infix solution with *some* paranthesis # (the clever way?) class Expression Priorities = { "**" => 2, "*" => 1, "/" => 1, "%" => 1, "+" => 0, "-" => 0, nil => 3 } Commutative = %w[ * + ] attr_reader :text, :top_op def initialize text @top_op = nil @text = text end def apply op, rhs @text = parented_text( op ) + " #{op} " << rhs.parented_text( op, false ) @top_op = op end def comm? op Commutative.include? op end def parented_text op, is_lhs=true my_prio = Priorities[ @top_op ] op_prio = Priorities[ op ] return @text if op_prio < my_prio return "( #@text )" if op_prio > my_prio return @text if comm?( op ) || is_lhs "( #@text )" end end postfix = ARGV.empty? ? $stdin.read.split : ARGV postfix = postfix.map{ | ele | Expression::Priorities[ ele ] ? ele : Expression.new( ele ) } stack = [] postfix.each do | ele | case ele when Expression stack << ele else rhs = stack.pop stack[ -1 ].apply ele, rhs end end puts stack.first.text