Wow, this is pretty freaky.  My solution is eerily similar to Ken's
(albeit less concise), and I hadn't seen his code until now.  Look:

On Apr 8, 9:21 pm, "Marcel Ward" <ward... / gmail.com> wrote:
> On 08/04/07, Carl Porth <badc... / gmail.com> wrote:
>
> > After going back and reading the current solutions, I like Ken Bloom's
> > each_partition method.  It's much cleaner than my combinations method.

I wrote an Array#each_partition too, and my first implementation of it
looked almost just like his:

  def each_partition(n = length)
    if n < 1
       yield []
    else
      (0..length-n).each do |x|
         section=self[x, length]
         self[0, x].each_partition(n-1) do |part|
           yield part << section
         end
       end
    end
    self
  end

I rewrote this when I found an iterative algorithm for it, but I
hadn't realized that that seemingly extraneous argument could be used
to limit the number of partitions, which is clever.  Still, this is a
fundamental algorithm in combinatorics, so I'm not too surprised that
he chose to put in Array.  This is where it gets eerie:

> I agree, very clean and efficient.  The three lines that put it all
> together using #zip are what makes this work for me:
>
> Digits.each_partition(Operators.length+1) do |digitspart|
>   OperatorPerms.each do |operatorsperm|
>      expression=digitspart.zip(operatorsperm).flatten.join
> ...

my version of the above:

  digits.send(digits_message) do |part|
    ...
    operators.send(*ops_send_args) do |tuple|
      expr = part.zip(tuple).join(' ')
      ...

And then I go on to eval(expr), as Ken did.  Take it for granted that
my uses of send() do essentially the same thing.  Weird, no?

>
> I think I would be feeling very happy if I'd submitted this solution :)
>
> --
> Marcel

I was, too, before I saw Ken's.

Harrison