Account Options

  1. Sign in
The old Google Groups will be going away soon, but your browser is incompatible with the new version.
Google Groups Home
« Groups Home
Postfix to Infix (#148)
There are currently too many topics in this group that display first. To make this topic appear first, remove this option from another topic.
There was an error processing your request. Please try again.
flag
  Messages 1 - 25 of 50 - Collapse all  -  Translate all to Translated (View all originals)   Newer >
The group you are posting to is a Usenet group. Messages posted to this group will make your email address visible to anyone on the Internet.
Your reply message has not been sent.
Your post was successful
 
From:
To:
Cc:
Followup To:
Add Cc | Add Followup-to | Edit Subject
Subject:
Validation:
For verification purposes please type the characters you see in the picture below or the numbers you hear by clicking the accessibility icon. Listen and type the numbers you hear
 
Ruby Quiz  
View profile  
 More options Nov 30 2007, 8:28 am
Newsgroups: comp.lang.ruby
From: Ruby Quiz <ja...@grayproductions.net>
Date: Fri, 30 Nov 2007 08:28:17 -0500
Local: Fri, Nov 30 2007 8:28 am
Subject: [QUIZ] Postfix to Infix (#148)
The three rules of Ruby Quiz:

1.  Please do not post any solutions or spoiler discussion for this quiz until
48 hours have passed from the time on this message.

2.  Support Ruby Quiz by submitting ideas as often as you can:

http://www.rubyquiz.com/

3.  Enjoy!

Suggestion:  A [QUIZ] in the subject of emails about the problem helps everyone
on Ruby Talk follow the discussion.  Please reply to the original quiz message,
if you can.

-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- =-=-=

There are many different ways to write mathematical equations.  Infix notation
is probably the most popular and yields expressions like:

        2 * (3 + 5)

Some people like to work with a postfix notation (often called Reverse Polish
Notation or just RPN) though, which doesn't require parentheses for the same
equation:

        2 3 5 + *

You can compare the results of these equations using the Unix utilities bc
(infix) and dc (postfix):

        $ bc <<< '2 * (3 + 5)'
        16
        $ dc <<< '2 3 5 + * p'
        16

The "p" instruction tacked onto the end of the expression for dc just tells it
to print the result.

This week's quiz is to write a script that translates postfix expressions into
the equivalent infix expression.  In the simplest form, your script should
function as such:

        $ ruby postfix_to_infix.rb '2 3 +'
        2 + 3

At minimum, try to support the four basic math operators:  +, -, *, and /.  Feel
free to add others though.  For numbers, remember to accept decimal values.

You can count on the postfix expressions having spaces between each term, if you
like.  While dc is content with 2 3+p, you don't have to support it unless you
want to.

For an added bonus, try to keep the parentheses added to infix expressions to
the minimum of what is needed.  For example, prefer these results:

        $ ruby postfix_to_infix.rb '56 34 213.7 + * 678 -'
        56 * (34 + 213.7) - 678
        $ ruby postfix_to_infix.rb '1 56 35 + 16 9 - / +'
        1 + (56 + 35) / (16 - 9)

to these:

        $ ruby postfix_to_infix.rb '56 34 213.7 + * 678 -'
        ((56 * (34 + 213.7)) - 678)
        $ ruby postfix_to_infix.rb '1 56 35 + 16 9 - / +'
        (1 + ((56 + 35) / (16 - 9)))

Posting equations and your output is not a spoiler.


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Christian von Kleist  
View profile  
 More options Nov 30 2007, 10:24 am
Newsgroups: comp.lang.ruby
From: Christian von Kleist <cvonkle...@gmail.com>
Date: Fri, 30 Nov 2007 10:24:20 -0500
Local: Fri, Nov 30 2007 10:24 am
Subject: Re: [QUIZ] Postfix to Infix (#148)
On Nov 30, 2007 8:28 AM, Ruby Quiz <ja...@grayproductions.net> wrote:

I had this as an assignment for a class once, in Java, so I'll sit
this one out.  Fun quiz!

 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Robert Dober  
View profile  
 More options Nov 30 2007, 2:51 pm
Newsgroups: comp.lang.ruby
From: Robert Dober <robert.do...@gmail.com>
Date: Fri, 30 Nov 2007 14:51:05 -0500
Local: Fri, Nov 30 2007 2:51 pm
Subject: Re: [QUIZ] Postfix to Infix (#148)
On Nov 30, 2007 4:24 PM, Christian von Kleist <cvonkle...@gmail.com> wrote:

Why? I'd rather say that it is quite challange to provide a solution
in Ruby that is not just a rewrite of your Java solution.
I do not think that there are an "ethic" considerations ;).
Cheers
Robert

--

http://ruby-smalltalk.blogspot.com/

---
All truth passes through three stages. First, it is ridiculed. Second,
it is violently opposed. Third, it is accepted as being self-evident.
Schopenhauer (attr.)


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Daniel Martin  
View profile  
 More options Dec 1 2007, 5:18 pm
Newsgroups: comp.lang.ruby
From: Daniel Martin <mar...@snowplow.org>
Date: Sat, 1 Dec 2007 17:18:37 -0500
Local: Sat, Dec 1 2007 5:18 pm
Subject: Re: [QUIZ] Postfix to Infix (#148)
"Christian von Kleist" <cvonkle...@gmail.com> writes:

> I had this as an assignment for a class once, in Java, so I'll sit
> this one out.  Fun quiz!

Well, doubtless in java you solved it in a way that demonstrated your
use of certain basic data structures that you'd just learned about.

There are at least two completely different algorithms to use in
solving this in a conventional manner, and I've just solved it in a
third, completely unconventional ("evil") manner.  So solve it in a
manner different from what you did in class.

(The no-spoiler rule makes phrasing this reply difficult)

Also, being strict about the minimal parentheses rule makes things a
bit interesting:

'1 2 + 3 4 + +' should become '1 + 2 + 3 + 4'

But:

'1 2 - 3 4 - -' should become '1 - 2 - (3 - 4)'

Likewise for multiplication and division.

Also, you could add exponentiation, but if you do remember that infix
exponentiation associates to the right, not the left, so:

'2 2 ^ 2 ^' should become '(2 ^ 2) ^ 2'

But:

'2 2 2 ^ ^' should become '2 ^ 2 ^ 2'

So really, there's lots more to it than whatever you did it in that
java class.

--
s=%q(  Daniel Martin -- mar...@snowplow.org
       puts "s=%q(#{s})",s.to_a.last       )
       puts "s=%q(#{s})",s.to_a.last      


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Todd Benson  
View profile  
 More options Dec 1 2007, 5:27 pm
Newsgroups: comp.lang.ruby
From: Todd Benson <caduce...@gmail.com>
Date: Sat, 1 Dec 2007 17:27:47 -0500
Local: Sat, Dec 1 2007 5:27 pm
Subject: Re: [QUIZ] Postfix to Infix (#148)
On Dec 1, 2007 4:18 PM, Daniel Martin <mar...@snowplow.org> wrote:

> "Christian von Kleist" <cvonkle...@gmail.com> writes:
> But:

> '1 2 - 3 4 - -' should become '1 - 2 - (3 - 4)'

Or '1 - 2 - 3 + 4'  (yikes!) :^0

Todd


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Eric I.  
View profile  
 More options Dec 1 2007, 6:02 pm
Newsgroups: comp.lang.ruby
From: "Eric I." <rubytrain...@gmail.com>
Date: Sat, 1 Dec 2007 15:02:01 -0800 (PST)
Local: Sat, Dec 1 2007 6:02 pm
Subject: Re: Postfix to Infix (#148)
On Dec 1, 5:27 pm, Todd Benson <caduce...@gmail.com> wrote:

> On Dec 1, 2007 4:18 PM, Daniel Martin <mar...@snowplow.org> wrote:

> > "Christian von Kleist" <cvonkle...@gmail.com> writes:
> > But:

> > '1 2 - 3 4 - -' should become '1 - 2 - (3 - 4)'

> Or '1 - 2 - 3 + 4'  (yikes!) :^0

Well one feature of the Ruby Quiz is that our Quiz Master generally
allows submitters quite a bit of flexibility in reinterpreting the
problem.  To me, however, that form seems outside the problem
description, as you're a) applying the distributive property, and b)
ending up with a different set of operators than what you started with
(from 3 minuses to 2 minuses and 1 plus).

And once you start down the road '4 2 3 + *' could become '4 * (2 +
3)', '8 + 12', or even '20'.

Eric

====

Are you interested in on-site Ruby training that's been highly
reviewed by former students?  http://LearnRuby.com


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Todd Benson  
View profile  
 More options Dec 1 2007, 6:30 pm
Newsgroups: comp.lang.ruby
From: Todd Benson <caduce...@gmail.com>
Date: Sat, 1 Dec 2007 18:30:58 -0500
Local: Sat, Dec 1 2007 6:30 pm
Subject: Re: Postfix to Infix (#148)
On Dec 1, 2007 5:05 PM, Eric I. <rubytrain...@gmail.com> wrote:

Of course.  It's not a quiz about simplification.  I just thought it
was funny (a stretch on the minimizing of parentheses).  It keeps the
same digits, though; only changes the operators.  It's quite clear
that the only symbols -- digits or operators -- we're allowed to add
or remove are ) and (.

Cheers,
Todd


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Robert Dober  
View profile  
 More options Dec 2 2007, 8:52 am
Newsgroups: comp.lang.ruby
From: Robert Dober <robert.do...@gmail.com>
Date: Sun, 2 Dec 2007 08:52:50 -0500
Local: Sun, Dec 2 2007 8:52 am
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


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Eric DUMINIL  
View profile  
 More options Dec 2 2007, 9:28 am
Newsgroups: comp.lang.ruby
From: Eric DUMINIL <eric.dumi...@gmail.com>
Date: Sun, 2 Dec 2007 09:28:32 -0500
Local: Sun, Dec 2 2007 9:28 am
Subject: Re: Postfix to Infix (#148)
Here is my solution:

http://pastie.caboo.se/124288
I'm pretty it removes every unnecessary (), at least for - + ** ^ /.

Thanks for the quiz!

On 02/12/2007, Robert Dober <robert.do...@gmail.com> wrote:


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Harry Kakueki  
View profile  
 More options Dec 2 2007, 10:09 am
Newsgroups: comp.lang.ruby
From: Harry Kakueki <list.p...@gmail.com>
Date: Sun, 2 Dec 2007 10:09:23 -0500
Local: Sun, Dec 2 2007 10:09 am
Subject: Re: [QUIZ] Postfix to Infix (#148)

> This week's quiz is to write a script that translates postfix expressions into
> the equivalent infix expression.  In the simplest form, your script should
> function as such:

>         $ ruby postfix_to_infix.rb '2 3 +'
>         2 + 3

> At minimum, try to support the four basic math operators:  +, -, *, and /.  Feel
> free to add others though.  For numbers, remember to accept decimal values.

# Here is my solution.
# It solves the minimum requirements with minimal error checking.
# Removes some parentheses.
#str = "1 56 35 + 16 9 - / +"
str = "1 2 - 3 4 - - 2 * 7.4 + 3.14 * 2 / 1.2 + 3 4 - -"
ops = %w[+ - * /]
arr = str.split(/\s+/)
err = arr.select {|c| c =~ /^\d+\.?\d?/ || ops.include?(c)}
the_stack = []

if arr.length == err.length
  arr.each_with_index do |x,y|
  the_stack << x unless ops.include?(x)
    if ops.include?(x) && the_stack.length > 1
    b = the_stack.pop
    a = the_stack.pop
    the_stack << "(#{a} #{x} #{b})" if (x == "+" || x == "-") && (y <
(arr.length - 1))
    the_stack << "#{a} #{x} #{b}" if x == "*" || x == "/" || y ==
(arr.length - 1)
    end
  end
  puts the_stack[0]
end

# Harry

--
A Look into Japanese Ruby List in English
http://www.kakueki.com/ruby/list.html


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
tho_mica_l  
View profile  
 More options Dec 2 2007, 10:34 am
Newsgroups: comp.lang.ruby
From: tho_mica_l <micat...@gmail.com>
Date: Sun, 2 Dec 2007 07:34:41 -0800 (PST)
Local: Sun, Dec 2 2007 10:34 am
Subject: Re: Postfix to Infix (#148)

> Some people like to work with a postfix notation (often called Reverse Polish
> Notation or just RPN) though, which doesn't require parentheses for the same
> equation:

Since I recently wrote a small RPN calculator in ruby
(http://www.vim.org/scripts/script.php?script_id=2040), I found this
idea interesting.

Here is my take on this. It provides some kind of simplicistic
pattern
matcher and should be extensible. The assumption is made that the
input
consists of numeric data and predefined operators. No error checking
is
done.

Regards,
Thomas.

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, [String, String, false, true]],
                    '*' => [5],
                    '/' => [5],
                    '^' => [5, [String, Numeric, true, false]],
        }
        @opnames = @ops.keys
    end

    def get_elt(op, idx=-1, other_value=nil)
        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 eopp > opp
                return '(%s)' % val
            end
        end
        return val
    end

    def process
        @iqueue.each do |token|
            if @opnames.include?(token)
                val1 = get_elt(token, -2)
                val2 = get_elt(token, -1)
                @ops[token][1..-1].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, '%s %s %s' % [val1, token, val2]]
            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('2 2 ^ 2 ^')             == '(2 ^ 2) ^ 2'
        puts Quiz148.run('2 2 2 ^ ^')             == '2 ^ 2 ^ 2'
    else
        puts Quiz148.run(ARGV)
    end
end


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Jesús Gabriel y Galán  
View profile  
 More options Dec 2 2007, 10:53 am
Newsgroups: comp.lang.ruby
From: Jesús Gabriel y Galán <jgabrielyga...@gmail.com>
Date: Sun, 2 Dec 2007 10:53:51 -0500
Local: Sun, Dec 2 2007 10:53 am
Subject: Re: [QUIZ] Postfix to Infix (#148)
On Nov 30, 2007 2:28 PM, Ruby Quiz <ja...@grayproductions.net> wrote:

Hi,

Fortunately, this week I had some time to check the Ruby quiz, and
even to code something. Unfortunately I only had about 10 minutes, so
I only solved the basic problem:

stack = []
expr = ARGV.join(" ")
expr.split(/ /).each do |x|
  case x
    when *%w{+ * - /}
      op2 = stack.pop
      op1 = stack.pop
      stack.push "(#{op1} #{x} #{op2})"
    else
      stack.push x
    end
  end
  puts stack.pop

This is how it works with the examples. It doesn't remove a single
parenthesis :-(

C:\Jesus>ruby quiz148.rb 2 3 +
(2 + 3)

C:\Jesus>ruby quiz148.rb "56 34 213.7 + * 678 -"
((56 * (34 + 213.7)) - 678)

C:\Jesus>ruby quiz148.rb 1 56 35 + 16 9 - / +
(1 + ((56 + 35) / (16 - 9)))

I'll try to find some time to implement some parenthesis
simplification, although I doubt I will succeed...

Thanks,

Jesus.


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Ken Bloom  
View profile  
 More options Dec 2 2007, 11:08 am
Newsgroups: comp.lang.ruby
From: Ken Bloom <kbl...@gmail.com>
Date: Sun, 02 Dec 2007 16:08:05 GMT
Local: Sun, Dec 2 2007 11:08 am
Subject: Re: [QUIZ] Postfix to Infix (#148)

def convert array
  cur=array.pop
  case cur
  when Numeric: return cur
  when String:
    rhs=convert(array)
    lhs=convert(array)
    return "(#{lhs} #{cur} #{rhs})"
  end
end

equation=ARGV[0].split.collect{|x| Integer(x) rescue Float(x) rescue x}
puts convert(equation)

--
Ken (Chanoch) Bloom. PhD candidate. Linguistic Cognition Laboratory.
Department of Computer Science. Illinois Institute of Technology.
http://www.iit.edu/~kbloom1/


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
tho_mica_l  
View profile  
 More options Dec 2 2007, 11:22 am
Newsgroups: comp.lang.ruby
From: tho_mica_l <micat...@gmail.com>
Date: Sun, 2 Dec 2007 08:22:33 -0800 (PST)
Local: Sun, Dec 2 2007 11:22 am
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


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
James Koppel  
View profile  
 More options Dec 2 2007, 11:40 am
Newsgroups: comp.lang.ruby
From: James Koppel <jamesbkop...@yahoo.com>
Date: Sun, 2 Dec 2007 11:40:44 -0500
Local: Sun, Dec 2 2007 11:40 am
Subject: Re: [QUIZ] Postfix to Infix (#148)
PREC = {:+ => 0,:- => 0,:* => 1,:/ => 1,:% => 1,:^ => 2}
LEFT_ASSOCS = {:+ => true,:- => true,:* => true,:/ => true,
          :% => true,:^ => false}
RIGHT_ASSOCS = {:+ => true,:- => false,:* => true,:/ => false,
          :% => false,:^ => true}

class TreeNode
  attr_accessor :el,:left,:right
  def initialize(el,left,right)
    @el,@left,@right=el,left,right
  end

  def TreeNode.from_postfix(exp_arr)
    stack = []
    exp_arr.each do |exp_str|
      if PREC.keys.include? exp_str.to_sym
        op2,op1 = stack.pop,stack.pop
        stack.push(TreeNode.new(exp_str.to_sym,op1,op2))
      else
        stack.push(exp_str.to_f)
      end
    end
    stack.first
  end

  def to_minparen_infix
    l,r = [left,right].map{|o|o.to_minparen_infix}
    l = "(#{l})" if left.respond_to?(:el) and (PREC[left.el]<PREC[self.el] or  
        (self.el==left.el and not LEFT_ASSOCS[left.el]))
    r= "(#{r})" if right.respond_to?(:el) and (PREC[right.el]<PREC[self.el] or
        (self.el==right.el and not RIGHT_ASSOCS[right.el]))
    l+" #{self.el} "+r
  end
end

class Float
  def to_minparen_infix
    if self%1==0
      to_i.to_s
    else
      to_s
    end
  end
end

puts TreeNode.from_postfix(ARGV.first.split(/ /)).to_minparen_infix


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Pawel Radecki  
View profile  
 More options Dec 2 2007, 12:14 pm
Newsgroups: comp.lang.ruby
From: Pawel Radecki <pawel.j.rade...@gmail.com>
Date: Sun, 2 Dec 2007 12:14:10 -0500
Local: Sun, Dec 2 2007 12:14 pm
Subject: Re: [QUIZ] Postfix to Infix (#148)
Hello everybody,

Here's my solution. I know it's pretty long but I'm still learning...
BIG thanks for the quiz!

#!/usr/bin/env ruby

# Solution to Ruby Quiz #148 (see http://www.rubyquiz.com/quiz148.html)
# by Pawel Radecki (pawel.j.rade...@gmail.com).

# Note1: There may be couple of different and correct postfix to infix
# transformations but this program only gives one and ignores others.
#
# Example:
# postfix: 1 2 + 4 * 5 + 3 -
# infix: (1 + 2) * 4 + 5 - 3
# infix: (1+2)*4+5-3
# infix: 5 + (1 + 2) * 4 - 3
# infix: 5 + 4 * (1 + 2) - 3
# ... (there are more)

# Note2: Unary operators not supported!

# Note3: I don't know why ^ in input argument doesn't work, anybody
knows...?

require 'logger'

$LOG = Logger.new($stderr)

#logging
#$LOG.level = Logger::DEBUG #DEBUG
$LOG.level = Logger::ERROR  #PRODUCTION

class PostfixEquation < String

    private
    @@OPERATOR_PRIORITIES = {
                            'V' => 2,
                            '**' => 2,
                            '*' => 2,
                            '/' => 2,
                            '+' => 3,
                            '-' => 3
                        }

    def normalize_expression (expression)
        a = expression.split

        $LOG.debug("array: #{a}")
        $LOG.debug("#{a[0]} #{a[2]} #{a[1]}")

        @operator_stack.push(a[2])

        $LOG.debug("@operator_stack #{@operator_stack}")

        s = "#{a[0]} #{a[2]} #{a[1]}"
        if @operator_stack.length>1 &&
@@OPERATOR_PRIORITIES[@operator_stack[-2]]<@@OPERATOR_PRIORITIES[a[2]]
            s = "(#{s})"
        end

        if @two_branches
            @operator_stack.pop
        end

        #hack to resolve situation with two complex expressions forming
another
        if a[0] =~/[a-z]+/ && a[1] =~/[a-z]+/
            @two_branches = true
        else
            @two_branches = false
        end

        return s
    end

    public
    def initialize(equation)
        @string = super.to_str
        @label = "a"
        @expressions = {}
        @operator_stack = []
        @two_branches = false
    end

    def to_infix
        $LOG.debug("string: #{@string}")

        while (true)
            $LOG.debug("string: #{@string}")
            $LOG.debug("string lenth: #...@string.length}")

            #look for "(number or letter(s)) (number or letter(s))
operator" pattern
            #where number is chain of any digit and . (dot) characters
            #letter(s) is one or more letters
            #and operator is one of following characters: + - * / p r
            @string =~
/([0-9\.]+|[a-z]+)\s([0-9\.]+|[a-z]+)\s((\*\*)|(V)|\+|\*|\/|-)/
            $LOG.debug("pattern match: #{$`}<<#{$&}>>#{$'}")

            # if the the expression is not valid
            if ($&==nil || $&=="") && @string.length>1
               $LOG.error("Stack is not empty!")
               raise Exception.new("Stack is not empty!")
            end

            @expressions[@label] = $&
            @string = "#{$`}#{@label}#{$'}"
            $LOG.debug("string: #{@string}")
            $LOG.debug("string lenth: #...@string.length}")

            #if it's the last match
            if $`=="" && $'=="" && @string.length==1
               break
            end

            @label.succ!
            $LOG.debug("label: #{@label}")
            $LOG.debug("")

        end

        while (!...@expressions.empty?)
            @string.sub!(/([a-z])/) {
                letter = $1.dup
                s = String.new(normalize_expression(@expressions[letter]))
                @expressions.delete(letter)
                s
            }
            $LOG.debug("string: #{@string}")
            $LOG.debug("")
        end

        return @string
    end
end

USAGE = <<ENDUSAGE
Usage:
    postfix_to_infinix.rb 'mathematical equation'

Valid binary operators: + - * / V **
where
    V is a root operator, ex.: 5 V 1 means 5-th root of a number 1
    ** is a power operator, ex.: 2 ** 3 means power with base 2 and
exponent 3

(Unary operators not supported!)

Example:
    postfix_to_infinix.rb '56 34 213.7 + ** 678 -'
ENDUSAGE

if ARGV.length!=1
    puts USAGE
    exit
end

e = PostfixEquation.new(ARGV[0])
begin
    puts e.to_infix
rescue StandardError => err
    puts err
end

--
Pawel Radecki
m: +48 695 34-64-76
e: pawel.j.rade...@gmail.com
w: http://radeckimarch.blogspot.com/


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Justin Ethier  
View profile  
 More options Dec 2 2007, 12:27 pm
Newsgroups: comp.lang.ruby
From: Justin Ethier <justin.eth...@gmail.com>
Date: Sun, 2 Dec 2007 12:27:52 -0500
Local: Sun, Dec 2 2007 12:27 pm
Subject: Re: [QUIZ] Postfix to Infix (#148)
Note:  parts of this message were removed by the gateway to make it a legal Usenet post.

Hello,

Here is my solution. It minimizes the use of parentheses, and can easily be
extended to support other operators in addition to +, -, * / as long as they
are evaluated from left-to-right:

# This class represents a single token on the infix stack.
# A token may be a single operator / number from the postfix expr, or a
portion of the infix expr being built.
class Token
  # Accepts a token string and optionally the last operator added
  def initialize(tok, last_op = nil)
    @tok, @last_op = tok, last_op
  end

  # Determines if the current token is an operator
  def is_op?
    case @tok
    when "+", "-", "*", "/"
      return true
    else
      return false
    end
  end

  # Defines the precedence of operators
  def precedence(op)
    case op
    when "*", "/"
      return 5
    when "+", "-"
      return 6
    else
      return nil
    end
  end

  # Returns the token with parentheses added if they are needed for the
given op
  def pack(op)
    return "(#{tok})" if last_op != nil and (precedence(op) <
precedence(last_op))
    return tok
  end

  attr_reader :tok, :last_op
end

# Module of Postfix ==> Infix conversion functions
module PostfixToInfix

  # Main convertion function
  def PostfixToInfix.translate(postfix)
    stack, toks = [], postfix.split(" ").reverse

    for tok in toks
      stack << Token.new(tok)
      process_stack(stack)
    end

    process_stack(stack) while stack.size > 1 # Finish stack processing
    stack[0].tok
  end

  # Process the current postfix stack, converting to infix if there is
enough info
  def PostfixToInfix.process_stack(stack)
    while stack.size > 2 and not stack[-1].is_op? and not stack[-2].is_op?
      eq = []
      3.times{ eq << stack.pop }
      op = eq[2].tok
      tok = "#{eq[0].pack(op)} #{op} #{eq[1].pack(op)}"
      stack << Token.new(tok, op)
    end
  end
end

Full Program: http://pastie.caboo.se/124320
Test Cases: http://pastie.caboo.se/124321

Thanks,

Justin

On Nov 30, 2007 8:28 AM, Ruby Quiz <ja...@grayproductions.net> wrote:


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Lee Jarvis  
View profile  
 More options Dec 2 2007, 12:28 pm
Newsgroups: comp.lang.ruby
From: Lee Jarvis <ljjar...@gmail.com>
Date: Sun, 2 Dec 2007 12:28:57 -0500
Local: Sun, Dec 2 2007 12:28 pm
Subject: Re: Postfix to Infix (#148)
Well, here is my submission.. I truly was stuck with this so I just done
the most basic stuff, I will have a look through the other submissions a
bit later to see how others done it..

#!/usr/bin/ruby -w

argv = Array.new
if ARGV.empty?
  puts "#{$0} <Postfix equation>"
else
  ARGV.each do |a|
    if ['+', '-', '/', '*'].include?(a)
      last = argv.pop
      first = argv.pop
      argv << "(#{first} #{a} #{last})"
    else
      argv << a
    end
  end
  puts argv
end

I will try and mod the code to remove some parenthesis.

Regards,
Lee
--
Posted via http://www.ruby-forum.com/.


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
tho_mica_l  
View profile  
 More options Dec 2 2007, 1:20 pm
Newsgroups: comp.lang.ruby
From: tho_mica_l <micat...@gmail.com>
Date: Sun, 2 Dec 2007 10:20:09 -0800 (PST)
Local: Sun, Dec 2 2007 1:20 pm
Subject: Re: Postfix to Infix (#148)
I'm sorry for spamming this list with my inferior solutions. But J
Koppel's approach made me to reconsider my solution, which now
supports custom output format (eg for Arrays), functions with 3+
arity, and functions for which the arity is defined by the last
argument on the stack.

Thomas.

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, 2, nil, [[Object, nil], [String,
'(%s)']]],
                    '*'     => [5],
                    '/'     => [5],
                    '%'     => [5],
                    '<<'    => [3],
                    '^'     => [5, 2, nil, [[String, '(%s)'],
[Numeric, nil]]],
                    '**'    => [5, 2, nil, [[String, '(%s)'],
[Numeric, nil]]],
                    'sqrt'  => [0, 1, '#{op}(#{vals})'],
                    'binom' => [0, 2, '#{op}(#{vals.join(\', \')})'],
                    'sum3'  => [0, 3],
                    'Array' => [0, -1, '[#{vals.join(\', \')}]'],
        }
        @opnames = @ops.keys
    end

    def process
        @iqueue.each do |token|
            if @opnames.include?(token)
                op = token
                opp, arity, fmt, *patterns  = @ops[op]
                case arity
                when -1
                    aop, arity = @stack.pop
                when nil
                    arity = 2
                end
                case arity
                when 1
                    fmt ||= '#{op}#{vals}'
                when 2
                    fmt ||= '#{vals.join(\' \' + op + \' \')}'
                else
                    fmt ||= '#{op}(#{vals.join(\', \')})'
                end
                vals = (1..arity).inject([]) {|a, i| a <<
@stack.pop}.reverse
                idx  = 0
                vals.map! do |aop, val|
                    if aop
                        aopp, *aopatterns  = @ops[aop]
                        if opp > 0 and aopp > opp
                            val = '(%s)' % val
                        end
                    end
                    patterns.each do |pattern|
                        p, e = pattern[idx]
                        if (aop.nil? or aopp > 0) and val.kind_of?(p)
                            if e
                                val = e % val
                            end
                            break
                        end
                    end
                    idx += 1
                    val
                end
                @stack << [op, eval("\"#{fmt}\"")]
            else
                @stack << [nil, eval(token)]
            end
        end
        # The stack should include only one element here. A check
would
        # be necessary.
        o, v = @stack.pop
        v
    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)'
        puts Quiz148.run('1 2 2 binom 3 2 ^ sum3')    == 'sum3(1,
binom(2, 2), 3 ^ 2)'
        puts Quiz148.run('1 2 2 binom 3 3 Array')     == '[1, binom(2,
2), 3]'
        puts Quiz148.run('1 2 3 3 Array 4 <<')        == '[1, 2, 3] <<
4'
        puts Quiz148.run('1 2 3 3 Array 4 2 * <<')    == '[1, 2, 3] <<
(4 * 2)'
    else
        puts Quiz148.run(ARGV)
    end
end


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Ken Bloom  
View profile  
 More options Dec 2 2007, 1:38 pm
Newsgroups: comp.lang.ruby
From: Ken Bloom <kbl...@gmail.com>
Date: Sun, 02 Dec 2007 18:38:05 GMT
Local: Sun, Dec 2 2007 1:38 pm
Subject: Re: [QUIZ] Postfix to Infix (#148)

It appears to be this regex over here. You need to escape the ^ if you
want to use it in a regex, because ^ signals the beginning of a line in a
regex.

>             @string =~
> /([0-9\.]+|[a-z]+)\s([0-9\.]+|[a-z]+)\s((\*\*)|(V)|\+|\*|\/|-)/

--Ken

--
Ken (Chanoch) Bloom. PhD candidate. Linguistic Cognition Laboratory.
Department of Computer Science. Illinois Institute of Technology.
http://www.iit.edu/~kbloom1/


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Daniel Martin  
View profile  
 More options Dec 2 2007, 2:16 pm
Newsgroups: comp.lang.ruby
From: Daniel Martin <mar...@snowplow.org>
Date: Sun, 2 Dec 2007 14:16:18 -0500
Local: Sun, Dec 2 2007 2:16 pm
Subject: Re: [QUIZ] Postfix to Infix (#148)

Ruby Quiz <ja...@grayproductions.net> writes:
> This week's quiz is to write a script that translates postfix
> expressions into the equivalent infix expression.

#! /usr/bin/env ruby
#
# Accepts RPN using the basic four operations + - / *, as well as
# ^ to denote exponentiation, and outputs infix notation with the
# minimum number of parentheses.  Note that infix exponentiation
# associates to the right, so 2 ^ 2 ^ 2 == 2 ^ (2 ^ 2)

instr = ARGV.join(' ');
s = instr.dup
s.gsub!(/(\d+(\.\d*)?)/, '<n:\1>')
s.gsub!(/\s/,'')

# Data structures?  We don't need no stinkin' data structures.
# Postfix expression to infix expression via regular expressions.

while s =~ /<.*</ do
  f = false
  f |= s.gsub!(%r{<.:([^>]*)><.:([^>]*)>\+}, '<+:\1 + \2>')

  f |= s.gsub!(%r{<.:([^>]*)><[+-]:([^>]*)>-}, '<-:\1 - (\2)>')
  f |= s.gsub!(%r{<.:([^>]*)><[^+-]:([^>]*)>-}, '<-:\1 - \2>')

  f |= s.gsub!(%r{<[+-]:([^>]*)><[+-]:([^>]*)>\*}, '<*:(\1) * (\2)>')
  f |= s.gsub!(%r{<[+-]:([^>]*)><[^+-]:([^>]*)>\*}, '<*:(\1) * \2>')
  f |= s.gsub!(%r{<[^+-]:([^>]*)><[+-]:([^>]*)>\*}, '<*:\1 * (\2)>')
  f |= s.gsub!(%r{<[^+-]:([^>]*)><[^+-]:([^>]*)>\*}, '<*:\1 * \2>')

  f |= s.gsub!(%r{<[+-]:([^>]*)><[*/+-]:([^>]*)>/}, '</:(\1) / (\2)>')
  f |= s.gsub!(%r{<[^+-]:([^>]*)><[*/+-]:([^>]*)>/}, '</:\1 / (\2)>')
  f |= s.gsub!(%r{<[+-]:([^>]*)><[^*/+-]:([^>]*)>/}, '</:(\1) / \2>')
  f |= s.gsub!(%r{<[^+-]:([^>]*)><[^*/+-]:([^>]*)>/}, '</:\1 / \2>')

  f |= s.gsub!(%r{<[^n]:([^>]*)><[^n^]:([^>]*)>\^}, '<^:(\1) ^ (\2)>')
  f |= s.gsub!(%r{<[^n]:([^>]*)><[n^]:([^>]*)>\^}, '<^:(\1) ^ \2>')
  f |= s.gsub!(%r{<n:([^>]*)><[^n^]:([^>]*)>\^}, '<^:\1 ^ (\2)>')
  f |= s.gsub!(%r{<n:([^>]*)><[n^]:([^>]*)>\^}, '<^:\1 ^ \2>')
  unless f
    raise "Malformed RPN string: '#{instr}' (s is #{s})"
  end
end

s.gsub!(/<.:(.*)>/, '\1')
puts s

__END__

--
s=%q(  Daniel Martin -- mar...@snowplow.org
       puts "s=%q(#{s})",s.to_a.last       )
       puts "s=%q(#{s})",s.to_a.last      


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Adam Shelly  
View profile  
 More options Dec 2 2007, 3:02 pm
Newsgroups: comp.lang.ruby
From: Adam Shelly <adam.she...@gmail.com>
Date: Sun, 2 Dec 2007 15:02:49 -0500
Local: Sun, Dec 2 2007 3:02 pm
Subject: Re: [QUIZ] Postfix to Infix (#148)
On Nov 30, 2007 5:28 AM, Ruby Quiz <ja...@grayproductions.net> wrote:

> This week's quiz is to write a script that translates postfix expressions into
> the equivalent infix expression.

Here's mine.

It removes parenthesis, and handles all the binary operators in Ruby
(unless I missed some).
You can use a different set of operators and precedence rules by
changing the $Operators hash.

#postfix to infix
# ruby quix #148
# Adam Shelly
#
#  Converts postfix to infix notation
#  uses ruby's operators & precedence rules

$Operators = {
 '&&'=>0, '||'=>0,
 '=='=>1, '==='=>1, '<=>'=>1,
 '<='=>2, '>='=>2,   '<' =>2, '>'=>2,
 '^' =>3,  '|' =>3,
 '&' =>4,
 '<<'=>5, '>>'=>5,
 '+' =>6,  '-' =>6,
 '*' =>7,  '/' =>7, '%'=> 7,
 '**'=>8,
 :term=>10
 }

class Term
 attr_reader :precedence
 def initialize str, groupPrec=nil
   @s = str
   @precedence = $Operators[str]||groupPrec||$Operators[:term]
 end
 def isOp
   @precedence != $Operators[:term]
 end
 def parenthesize
   @s="(#{@s})"
 end
 def to_s
   @s
 end
end

class Infix
 def initialize rpn
   stack=[]
   rpn.split.each do |t|
     term = Term.new(t)
     if term.isOp
       lval = stack.pop
       rval = stack.pop
       raise "Empty Stack" unless lval && rval
       lval.parenthesize if lval.precedence < term.precedence
       rval.parenthesize if rval.precedence < term.precedence
       phrase = "#{rval} #{term} #{lval}"
       tok = Token.new(phrase,term.precedence)
#       p term
     end
     stack.push term
   end
   @expr = stack.pop
    raise "Extra terms" unless stack.size==0
 end
 def to_s
   @expr
 end
end

if __FILE__ == $0
  puts Infix.new(ARGV.join(' ')).to_s
end

-Adam


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Adam Shelly  
View profile  
 More options Dec 2 2007, 3:09 pm
Newsgroups: comp.lang.ruby
From: Adam Shelly <adam.she...@gmail.com>
Date: Sun, 2 Dec 2007 15:09:24 -0500
Local: Sun, Dec 2 2007 3:09 pm
Subject: Re: [QUIZ] Postfix to Infix (#148)
On Dec 2, 2007 12:02 PM, Adam Shelly <adam.she...@gmail.com> wrote:

> On Nov 30, 2007 5:28 AM, Ruby Quiz <ja...@grayproductions.net> wrote:
> > This week's quiz is to write a script that translates postfix expressions into
> > the equivalent infix expression.

> Here's mine.

I should know better than to try to cleanup my code, and then submit
it without running it first.

This line:

>        tok = Token.new(phrase,term.precedence)

should read
          term = Term.new(phrase, term.precedence)

-Adam


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Alex Shulgin  
View profile  
 More options Dec 2 2007, 3:19 pm
Newsgroups: comp.lang.ruby
From: Alex Shulgin <alex.shul...@gmail.com>
Date: Sun, 2 Dec 2007 12:19:24 -0800 (PST)
Local: Sun, Dec 2 2007 3:19 pm
Subject: Re: Postfix to Infix (#148)
On Nov 30, 3:28 pm, Ruby Quiz <ja...@grayproductions.net> wrote:

> -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- =-=-=

> There are many different ways to write mathematical equations.  Infix notation
> is probably the most popular and yields expressions like:

>         2 * (3 + 5)

> Some people like to work with a postfix notation (often called Reverse Polish
> Notation or just RPN) though, which doesn't require parentheses for the same
> equation:

>         2 3 5 + *

#!/usr/bin/ruby

$prec_tbl = {
  ['*', '+'] => true,
  ['*', '-'] => true,
  ['/', '+'] => true,
  ['/', '-'] => true,
  ['-', '-'] => true,
  ['/', '/'] => true

}

def precede?(top, op)
  $prec_tbl[[top, op]]
end

def infix(arr, top = nil)
  throw "invalid postfix expression" unless !arr.empty?
  op = arr.pop
  if op =~ /\+|\-|\*|\//
    right = infix(arr, op)
    left = infix(arr, op)
    par = precede?(top, op)
    (par ? "(" : "") + "#{left} #{op} #{right}" + (par ? ")" : "")
  else
    op
  end
end

STDIN.each do |line|
  arr = line.split(/\s+/)
  begin
    res = infix(arr)
    throw "invalid postfix expression" unless arr.empty?
    puts "#{res} => #{eval(res)}"
  rescue
    STDERR.puts $!
  end
end

--
Alex Shulgin


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Daniel Martin  
View profile  
 More options Dec 2 2007, 3:54 pm
Newsgroups: comp.lang.ruby
From: Daniel Martin <mar...@snowplow.org>
Date: Sun, 2 Dec 2007 15:54:12 -0500
Local: Sun, Dec 2 2007 3:54 pm
Subject: Re: [QUIZ] Postfix to Infix (#148)

"Adam Shelly" <adam.she...@gmail.com> writes:
> I should know better than to try to cleanup my code, and then submit
> it without running it first.

> This line:
>>        tok = Token.new(phrase,term.precedence)
> should read
>           term = Term.new(phrase, term.precedence)

Even with that cleanup, it doesn't seem to work:

esau:/tmp$ ruby asrq148.rb '2 3 - 5 +'
+
esau:/tmp$ ruby asrq148.rb '2 3 -'
-

--
s=%q(  Daniel Martin -- mar...@snowplow.org
       puts "s=%q(#{s})",s.to_a.last       )
       puts "s=%q(#{s})",s.to_a.last      


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Messages 1 - 25 of 50   Newer >
« Back to Discussions « Newer topic     Older topic »