blackanger 2007-9-15 15:13
Ruby 汉诺塔
国外的一个人写的小程序。
[code]
#Josh Goebel
class HanoiRack
class Peg
attr_reader :id, :rings
def initialize( id )
@id = id
@rings = []
end
def push( ring_size )
if @rings.last < ring_size
raise "Cannot put #{ring_size} on top of #{@rings.last}"
end unless @rings.empty?
@rings << ring_size
end
def pop
raise "No rings on peg #{self} left to pop!" if @rings.empty?
@rings.pop
end
def ring_count
@rings.length
end
def to_s
"<Peg #@id>"
end
alias_method :inspect, :to_s
end
end
class HanoiRack
attr_reader :pegs
def initialize( largest_ring_size=7 )
@pegs = [
Peg.new( :A ),
Peg.new( :B ),
Peg.new( :C )
]
@largest_ring_size = largest_ring_size
@largest_ring_size.downto(1){ |ring_size| @pegs[0].push(ring_size) }
@max_rings = @pegs[0].ring_count
end
def move_stack( source_peg, dest_peg, num_rings=source_peg.ring_count )
spare_peg = @pegs.find{ |peg| peg!=source_peg && peg!=dest_peg }
if num_rings == 1
move_ring( source_peg, dest_peg )
else
move_stack( source_peg, spare_peg, num_rings-1 )
move_ring( source_peg, dest_peg )
move_stack( spare_peg, dest_peg, num_rings-1 )
end
end
# Move the topmost ring off one peg and onto another
def move_ring( source_peg, dest_peg )
dest_peg.push( source_peg.pop )
puts self, " "
end
def to_s
s = ""
widest_ring = @largest_ring_size * 2 - 1
@max_rings.downto( 0 ){ |stack_spot|
s << @pegs.map{ |peg|
if ring_size = peg.rings[ stack_spot ]
( '-' * (ring_size*2-1) ).center( widest_ring )
else
peg.id.to_s.center( widest_ring )
end
}.join( ' ' ) + "\n"
}
s
end
end
if __FILE__ == $0
r = HanoiRack.new( 5 )
puts r, " "
r.move_stack( r.pegs.first, r.pegs.last )
end
[/code]
blackanger 2007-9-15 15:15
代码显示有问题啊
blackanger 2007-9-15 18:58
你没玩过汉诺塔啊?