Created
December 23, 2011 16:22
-
-
Save gromnitsky/1514630 to your computer and use it in GitHub Desktop.
Molloy Problem
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env ruby | |
# -*-ruby-*- | |
require 'pp' | |
require 'minitest/autorun' | |
class Pocket | |
MAX = 16 | |
attr_reader :stones, :name | |
def initialize(name, stones = []) | |
@name = name | |
@stones = *stones | |
end | |
def to_s | |
"#{name}: #{@stones.to_s}" | |
end | |
def <<(s) | |
return false unless @stones.size < MAX | |
@stones << s | |
return true | |
end | |
def moveStoneTo(pocket) | |
return false if @stones.size == 0 | |
idx = (rand @stones.size).to_i | |
e = @stones[idx] | |
@stones.delete_at idx | |
# actual Molloy's sucking of 'e' stone | |
yield e if block_given? | |
return pocket << e | |
end | |
end | |
class Molloy # Java style! | |
def initialize(p1, p2, p3, p4) | |
@p1 = p1 | |
@p2 = p2 | |
@p3 = p3 | |
@p4 = p4 | |
end | |
def self.print_pockets(*p) | |
p.each {|idx| pp idx } | |
puts "" | |
end | |
# must return an array | |
def rotate | |
fail "override me" | |
end | |
def suckStones(verbose = true) | |
Molloy.print_pockets @p1, @p2, @p3, @p4 if verbose | |
q = rotate | |
if verbose | |
Molloy.print_pockets @p1, @p2, @p3, @p4 | |
pp q | |
pp q.size | |
end | |
q | |
end | |
end | |
class SeasideMolloy < Molloy | |
def initialize(p1, p2, p3, p4) | |
super p1, p2, p3, p4 | |
end | |
def rotate | |
q = [] | |
while @p1.moveStoneTo(@p4) {|idx| q << idx }; end | |
while @p2.moveStoneTo(@p1) {|idx| q << idx }; end | |
while @p3.moveStoneTo(@p2) {|idx| q << idx }; end | |
while @p4.moveStoneTo(@p3); end | |
q | |
end | |
end | |
# [1] ==> [4*] | |
# | |
# /\ || | |
# || \/ | |
# | |
# [2] <== [3] | |
class TestSeasideMolloy < MiniTest::Unit::TestCase | |
def setup | |
p1 = Pocket.new 1, [1, 2, 3, 4, 5, 6] | |
p2 = Pocket.new 2, [7, 8, 9, 10, 11] | |
p3 = Pocket.new 3, [12, 13, 14, 15, 16] | |
p4 = Pocket.new 4 | |
@sm = SeasideMolloy.new p1, p2, p3, p4 | |
@sm.suckStones | |
end | |
def test_sucking | |
256.times { | |
q = @sm.suckStones false | |
assert_equal Pocket::MAX, q.uniq.size | |
} | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment