I took a look into bi-directional search, and it's really a rewarding 
technique. I predicted a 16-fold performance increase, but it was 12. 
I'm storing the result of both searches in a common array. To keep the 
two solutions separated I use the sign. When the other side, there is a 
connection, between the two growing trees.

I really tried to find something more clever than Simon's solutions, but 
had to give up. Kudos to Simon!

Thanks to everybody, it's been really nice to follow everybody's 
efforts!

Christer

Timings:

    t solve(      2,      9).size, 6    #1
    t solve(     22,     99).size, 8    #2
    t solve(    222,    999).size, 16   #3
    t solve(   2222,   9999).size, 25   #4
    t solve(  22222,  99999).size, 36   #5
    t solve( 222222, 999999).size, 47   #6
    t solve(2222222,9999999).size, 58   #7
    t solve(9999999,2222222).size, 61   #7
    t solve( 999999, 222222).size, 51   #6
    t solve(  99999,  22222).size, 42   #5
    t solve(   9999,   2222).size, 33   #4
    t solve(    999,    222).size, 23   #3
    t solve(     99,     22).size, 13   #2
    t solve(      9,      2).size, 9    #1

Each test consists of two problems.

Test 7:
Simon     1.833 secs
Christer  3.425 secs

Test 6:
Simon     0.321 secs
Christer  0.551 secs
Ryan     37     secs

Test 5:
Simon     0.11  secs
Christer  0.15  secs
Ryan      4.597 secs
Tristan   7.18  secs
Kenneth  13.93  secs
Zed      14.241 secs
Kero     70.6   secs

Test 4:
Chris     2.614 secs

Test 2:
James     0.12  secs


def solve start, target
  return [start] if start == target
  @max = 2 + 2 * [start,target].max
  @back = []
  @back[start] = start
  @back[target] = -target
  @ready = nil
  q1 = [start]
  q2 = [target]
  loop do
    q1 = solve_level(q1, 1)
    break if @ready
    q2 = solve_level(q2, -1)
    break if @ready
  end
  path(@ready[1]).reverse + path(@ready[0])
end

def path(number)
  nr = abs(@back[number])
  [number] + (nr == number ? [] : path(nr))
end

def solve_level(queue, sign)
  @queue = []
  @sign = sign
  queue.each do |number|
    store number, number * 2
    store number, number + 2 * sign
    store number, number / 2 if number[0] == 0
    break if @ready
  end
  @queue
end

def store number, result
  return if result > @max
  return if result <= 0
  if @back[result].nil? then
    @queue.unshift result
    @back[result] = number * @sign
  else
    if sign(@back[result]) == -@sign then
      @ready = number, result
    end
  end
end

def abs(x) x > 0 ? x : -x end
def sign(x) x > 0 ? 1 : -1 end



-- 
Posted via http://www.ruby-forum.com/.