class Hanoi::Jane::RegularTowers

Attributes

base[R]
disc[R]
discs[R]
from[R]
stacks[RW]
to[R]
total[R]

Public Class Methods

deserialise(path) click to toggle source
# File lib/hanoi/jane/towers/regular_towers.rb, line 134
def RegularTowers.deserialise path
  File.open path do |f|
    Marshal.load f
  end
end
diff(this, that) click to toggle source
# File lib/hanoi/jane/towers/regular_towers.rb, line 108
def RegularTowers.diff this, that
  this.chars.reverse.each_with_index do |bit, index|
    if bit < that.chars.reverse[index]
    return index
    end
  end
end
find_disc(stacks, disc) click to toggle source
# File lib/hanoi/jane/towers/regular_towers.rb, line 120
def RegularTowers.find_disc stacks, disc
  stacks.each_with_index do |stack, index|
    return index if stack.index disc
  end

  raise SearchException.new '%s not found in stacks' % disc
end
find_stack(stacks:, from:, disc:, total: nil) click to toggle source
# File lib/hanoi/jane/towers/regular_towers.rb, line 89
def RegularTowers.find_stack stacks:, from:, disc:, total: nil
  # if the next stack is empty, move there
  if stacks[(from + 1) % 3] == []
    return (from + 1) % 3
  end

  # if the next stack has a smaller top disc than our disc, go one more over
  if stacks[(from + 1) % 3][-1] < disc
    return (from + 2) % 3
  end

  # default to the next one
  (from + 1) % 3
end
new(discs = 3) { |self| ... } click to toggle source
# File lib/hanoi/jane/towers/regular_towers.rb, line 9
def initialize discs = 3
  @discs = discs
  @total = 0
  @base = 2
  @stacks = self.class.starter_stacks @discs

  yield self if block_given?
end
rebase(value, base, width) click to toggle source
# File lib/hanoi/jane/towers/regular_towers.rb, line 116
def RegularTowers.rebase value, base, width
  '%0*d' % [width, value.to_s(base)]
end
starter_stacks(discs) click to toggle source
# File lib/hanoi/jane/towers/regular_towers.rb, line 104
def RegularTowers.starter_stacks discs
  [(0...discs).to_a.reverse, [], []]
end

Public Instance Methods

==(other) click to toggle source
# File lib/hanoi/jane/towers/regular_towers.rb, line 140
def == other
  self.inspect == other.inspect
end
binary() click to toggle source
# File lib/hanoi/jane/towers/regular_towers.rb, line 81
def binary
  rebased
end
clone() click to toggle source
# File lib/hanoi/jane/towers/regular_towers.rb, line 60
def clone
  c = self.dup
  c.stacks = self.stacks.clone.map { |s| s.clone }
  c
end
discs=(discs) click to toggle source
# File lib/hanoi/jane/towers/regular_towers.rb, line 18
def discs= discs
  @discs = discs
  @stacks = self.class.starter_stacks @discs
end
each() { |self| ... } click to toggle source
# File lib/hanoi/jane/towers/regular_towers.rb, line 52
def each
  yield self if @total == 0
  until solved
    move
    yield self
  end
end
inspect() click to toggle source
# File lib/hanoi/jane/towers/regular_towers.rb, line 39
def inspect
  {
    stacks: @stacks,
    moves: @total,
    binary: rebased,
    moved: {
      disc: @disc,
      from: @from,
      to: @to
    }
  }
end
move() click to toggle source
# File lib/hanoi/jane/towers/regular_towers.rb, line 23
def move
  before = binary
  @total += 1
  after = binary

  @disc = self.class.diff before, after

  @from = self.class.find_disc @stacks, @disc
  @to = self.class.find_stack stacks: @stacks, from: @from, disc: @disc, total: @total
  @stacks[@to].push @stacks[@from].pop
end
rebased() click to toggle source
# File lib/hanoi/jane/towers/regular_towers.rb, line 85
def rebased
  self.class.rebase @total, @base, @discs
end
serialise(path) click to toggle source
# File lib/hanoi/jane/towers/regular_towers.rb, line 128
def serialise path
  File.open path, 'w' do |f|
    f.write Marshal.dump self
  end
end
solved() click to toggle source
# File lib/hanoi/jane/towers/regular_towers.rb, line 35
def solved
  rebased.chars.all? { |digit| digit.to_i == @base - 1 }
end
to_json() click to toggle source
# File lib/hanoi/jane/towers/regular_towers.rb, line 77
def to_json
  inspect.to_json
end
to_s() click to toggle source
# File lib/hanoi/jane/towers/regular_towers.rb, line 66
def to_s
  s = ''
  @stacks.each do |stack|
    s += stack.to_s
    s += "\n"
  end
  s += '---'

  s
end