```All solutions you posted are fun. But now it's time for REAL challenge. :)))

'a b c d = 1 2 + and = ='
should be converted to
'a = b = ( c = d and 1 + 2 )'

My program does this.

commutativity/non-commutativity, and associativity type (left or
right)
construct OP_STRENGTH

input = 'a b c d = 1 2 + and = ='

#
OP_STRENGTH = {
:left  => {'and'=>-1, '='=>1, '+'=>2, '-'=>2, '*'=>4, '/'=>4},
:right => {'and'=>-1, '='=>0 ,'+'=>2, '-'=>3, '*'=>4, '/'=>5}
}

def parenthesize(triplet, top_op_strength, side)
q = [ [triplet, top_op_strength, side] ]
while !q.empty?
t,top_op_strength,side = q.pop
if t.is_a?(Array)
if OP_STRENGTH[side][t[1]] < top_op_strength
print '( '
q << ')'
end
q << [t[2], OP_STRENGTH[:right][t[1]], :left]
q << t[1]
q << [t[0], OP_STRENGTH[:left][t[1]], :right]
else
print t, ' '
end
end
end

require 'benchmark'
puts Benchmark.measure {
stack = []
input.strip.split.each do |token|
case token
when '*', '+', '/', '-', '=', 'and'
stack << [stack.pop, token, stack.pop].reverse!
else
stack << token
end
end

parenthesize(stack.last, 0, :right)
puts
}

And the second thing.
For inputs

'0 ' + (1..10000).to_a.join(' - ') + ' *'
(1..N).to_a.join(' ') + ' /' * (N-1)

where N = 10000 i have benchmark:

0.282000   0.000000   0.282000
0.313000   0.000000   0.313000

```