From: Enrique Meza Date: 2004-02-05T11:15:03+09:00 Subject: Re: eistein's riddle Very interesting code... but hangup forever... ./einstein.rb:24:in `find': Interrupt from ./einstein.rb:24:in `detect' from ./einstein.rb:24:in `each' from ./einstein.rb:24:in `detect' from ./einstein.rb:24:in `find' from ./einstein.rb:28:in `nationality' from ./einstein.rb:40 If i runnit with irb: einstein.rb(main):061:0> puts "The " + pet("fish").nationality + " owns the fish" The Brit owns the fish => nil But seems wrong answer... I think in 'detect' line is the bug... ----------- CODE --------------------------------------- #!/usr/local/bin/ruby class Amb def initialize @failureContinuation = proc{raise "Amb goal tree exhausted"} end def fail @failureContinuation.call(nil) end def assert(bool) fail unless bool end def choose(procArray) kPrev = @failureContinuation callcc do |kEntry| procArray.each do |p| callcc do |kNext| @failureContinuation = proc do |v| @failureContinuation = kPrev kNext.call(v) end kEntry.call(p.call) end end kPrev.call(nil) end end def one_of(enumerable) choose(enumerable.collect{|ea| proc{ea}}) end def maybe one_of([true, false]) end end $colors = ["red", "white", "yellow", "blue", "green"] $nationalities = ["Brit", "Swede", "Dane", "Norwegian", "German"] $beverages = ["tea", "coffee", "milk", "beer", "water"] $cigars = ["Pall Mall", "Blends", "Dunhill", "Prince", "Bluemasters"] $pets = ["dogs", "birds", "cats", "horse", "fish"] class House attr_reader :color, :nationality, :beverage, :cigar, :pet def initialize @color = $amb.one_of($colors) @nationality = $amb.one_of($nationalities) @beverage = $amb.one_of($beverages) @cigar = $amb.one_of($cigars) @pet = $amb.one_of($pets) end end def find(property, value) $houses.detect{|h| h.send(property) == value} || $amb.fail end def color(s) find(:color, s) end def nationality(s) find(:nationality, s) end def beverage(s) find(:beverage, s) end def cigar(s) find(:cigar, s) end def pet(s) find(:pet, s) end def next_door(h1, h2) ($houses.index(h1) - $houses.index(h2)).abs == 1 end $amb = Amb.new $houses = (1..5).collect{House.new} puts "Finding.... red..\n" $amb.assert(nationality("Brit").color == "red") #fact 2 puts "Finding.... dogs..\n" $amb.assert(nationality("Swede").pet == "dogs") #fact 3 $amb.assert(nationality("Dane").beverage == "tea") #fact 4 $amb.assert(houses.index(color("white")) - houses.index(color("green")) == 1) #fact 5 $amb.assert(color("green").beverage == "coffee") #fact 6 $amb.assert(cigar("Pall Mall").pet == "birds") #fact 7 $amb.assert(color("yellow").cigar == "Dunhill") #fact 8 $amb.assert(houses[2].beverage == "milk") #fact 9 $amb.assert(houses[0].nationality == "Norwegian") #fact 10 $amb.assert(next_door(cigar("Blends"), pet("cats"))) #fact 11 $amb.assert(next_door(cigar("Dunhill"), pet("horse"))) #fact 12 $amb.assert(cigar("Bluemasters").beverage == "beer") #fact 13 $amb.assert(nationality("German").cigar == "Prince") #fact 14 $amb.assert(next_door(nationality("Norwegian"), color("blue"))) #fact 15 $amb.assert(next_door(cigar("Blends"), beverage("water"))) puts "All 15 facts...\n" Regards, -- Enrique Meza