------=_Part_3102_4389072.1136134866960
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
Content-Disposition: inline
I guess we're allowed to submit solutions now... here's my first ever ruby
quiz solution (these quizzes are a great idea, btw):
It's is an iterated-depth DFS w/ memoization written in a functional style
for fun.
It exploits the fact that the optimal path through the maze will never have
consecutive double/halves, which reduces the avg branching factor of the
search tree to ~2. Keeping track of this state makes the code a little
uglier, but faster on the longer searches.
Maurice
#! /usr/bin/ruby
# These return the next number & state
ARROWS =3D [lambda { |x,state| (state !=3D :halve) ? [x*2, :double] : nil }=
, #
double
lambda { |x,state| (x.modulo(2).zero? and state !=3D :double) ?
[x/2, :halve] : nil }, #halve
lambda { |x,state| [x+2, :initial]}] # add_two
def solver(from, to)
# constraining depth on a DFS
retval =3D nil
depth =3D 1
@memo =3D nil
# special case
return [from] if from =3D=3D to
while (retval.nil?)
retval =3D memo_solver(from, to, depth)
depth +=3D 1
end
retval
end
# cant use hash default proc memoization since i dont want to memoize on th=
e
# state parameter, only on the first 3
def memo_solver(from, to, maxdepth, state=3D:initial)
@memo ||=3D Hash.new
key =3D [from, to, maxdepth]
if not @memo.has_key? key
@memo[key] =3D iter_solver(from, to, maxdepth, state)
@memo[key]
else
@memo[key]
end
end
def iter_solver(from, to, maxdepth, state)
return nil if maxdepth.zero?
# generate next numbers in our graph
next_steps =3D ARROWS.map { |f| f.call(from, state) }.compact
if next_steps.assoc(to)
[from, to]
else
# havent found it yet, recur
kids =3D next_steps.map { |x,s| memo_solver(x, to, maxdepth-1, s)
}.compact
if kids.length.zero?
nil
else
# found something further down the tree.. return the shortest list up
best =3D kids.sort_by { |x| x.length }.first
[from, *best]
end
end
end
list =3D [ [1,1], [1,2], [2,9], [9,2], [2, 1234], [1,25], [12,11], [17,1],
[22, 999], [2, 9999], [222, 9999] ]
require 'benchmark'
list.each do |i|
puts Benchmark.measure {
p solver(*i)
}
end
I had the same thought, then decided it doesn't fit. But too, I'm
interested in watching these solutions.
I have a feeling they'll be based on exhaustive searches with a pinch
of pruning and a dash of optimization.
--Steve
------=_Part_3102_4389072.1136134866960--