On Dec 3, 2007 12:14 PM, Christian von Kleist <cvonkleist / gmail.com> wrote: > > On Dec 3, 2007 9:42 AM, Eric Mahurin <eric.mahurin / gmail.com> wrote: > > > > On Dec 3, 2007 8:05 AM, Ken Bloom <kbloom / gmail.com> wrote: > > > > > On Sun, 02 Dec 2007 22:23:23 -0500, Eric Mahurin wrote: > > > > > > > Note: parts of this message were removed by the gateway to make it a > > > > legal Usenet post. > > > > > > > > On Nov 30, 2007 7:28 AM, Ruby Quiz <james / grayproductions.net> wrote: > > > > > > > >> For an added bonus, try to keep the parentheses added to infix > > > >> expressions to > > > >> the minimum of what is needed. > > > >> > > > >> > > > > My solution does the above, plus a few more things: > > > > > > > > * maintains an OO data structure (to do everything below) * further > > > > reduce parentheses (and post-fix stack depth) by using some > > > > associativity > > > > * evaluates the result > > > > * gives stack-reduced post-fix form > > > > > > > > The basic idea of the solution is to have an object for each expression > > > > (possibly with sub-expressions as operands) and have methods for > > > > applying another operation in either direction (i.e. have both #add and > > > > #radd - reverse add). This allows independent decisions on what each > > > > type of expression should do when it is in either operand of another > > > > operation. > > > > > > > > Here are a few examples (result shows internal postfix, infix, and > > > > result): > > > > > > > >>ruby quiz148.rb "2 3 5 + *" > > > > 2 3 5 + * => 2*(3 + 5) => 16 > > > >>ruby quiz148.rb "56 34 213.7 + * 678 -" > > > > 56 34 213.7 + * 678 - => 56*(34 + 213.7) - 678 => 13193.2 > > > >>ruby quiz148.rb "1 56 35 + 16 9 - / +" > > > > 1 56 35 + 16 9 - / + => 1 + (56 + 35)*(16 - 9) => 14 > > > >>ruby quiz148.rb "1 2 3 4 5 + + + +" > > > > 1 2 + 3 + 4 + 5 + => 1 + 2 + 3 + 4 + 5 => 15 > > > >>ruby quiz148.rb "1 2 3 4 5 - - - -" > > > > 1 2 - 3 + 4 - 5 + => 1 - 2 + 3 - 4 + 5 => 3 > > > > > > This doesn't look right. > > > 3 5 * 5 8 * / => 3*5*(5*8) => 0 > > > > > > Thanks Ken, > > > > I obviously didn't test divide. My previously solution has a stupid typo in > > Quotient#to_s. Should be: > > > > class Quotient < Product > > def to_s > > "#{@left}/#{@right}" # had a * operator here before, whoops! > > end > > ... > > > > Here's a couple more tests: > > > > >ruby quiz148.rb "3 5 / 5 8 / /" > > 3 5 / 5 / 8 * => 3/5/5*8 => 0 > > >ruby quiz148.rb "3 5 5 8 / / /" > > 3 5 5 / 8 * / => 3/(5/5*8) => 0 > > > > All the results are zero because it is using ruby's Fixnum#/. The last form > > isn't quite optimal because it preferring to minimize divisions over > > minimizing groupings/stack-depth. If you use the commented code in > > Product#rdiv like this: > > > > def rdiv(other) > > # could do this to reduce grouping and stack depth > > # but this will increase expensive divisions > > @left.rdiv(other).div(@right) # might have more divisions now > > #other.div(Group.new(self)) > > end > > > > > > you'll get this: > > > > >ruby quiz148.rb "3 5 5 8 / / /" > > > > 3 5 / 5 * 8 / => 3/5*5/8 => 0 > > > > > Wow, there was a lot of activity on this quiz over the weekend! > > Fine, here is my 5-minute solution which doesn't optimize parentheses: > > #!/usr/bin/ruby > terms = [] > ARGV[0].split(/\s/).each { |t| terms << (%w(+ - / *).include?(t) ? > "(#{terms.slice!(-2)} #{t} #{terms.slice!(-1)})" : t) } > puts terms[0] > > It was originally a few lines longer as the ternary operator was an > if/else/end. Some of the solutions look very long! I haven't thought > about it yet, but the reduction of parentheses must be challenging! > Sorry, here's the non-obfuscated version: terms = [] ARGV[0].split(/\s/).each do |t| terms << if %w(+ - / *).include?(t) "(#{terms.slice!(-2)} #{t} #{terms.slice!(-1)})" else t end end puts terms[0]