Last active
December 17, 2015 00:49
-
-
Save acook/5523462 to your computer and use it in GitHub Desktop.
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
# This is a mostly idomatic class-based Ruby implementation of | |
# Labyrinth's version of the Knights and Knaves logic puzzle. | |
# It's self-resetting once a choice has been made, | |
# so you only get one shot at it before it rerolls. | |
class LabyrinthLogic | |
BOOLS = [true, false] | |
DOORS = [:left, :right] | |
def initialize | |
roll | |
end | |
def left_guard door | |
guard :left, door | |
end | |
def right_guard door | |
guard :right, door | |
end | |
def choose! door | |
return puts "You can only choose left or right!" unless DOORS.include?(door) | |
announce @doors[door] == true | |
roll | |
end | |
private | |
def announce result | |
if result then | |
puts "\e[32mSo, you want to be a hero?\e[0m" | |
else | |
puts "\e[31mYou have been eaten by a grue.\e[0m" | |
end | |
end | |
def guard side, door | |
return puts "Only ask about doors or other guards." unless (BOOLS | DOORS).include? door | |
return puts "Once question per guard." unless @guards.keys.include? side | |
bool = BOOLS.include?(door) ? door : @doors[door] | |
@old_guards[side] = @guards.delete(side) | |
@old_guards[side] ^ bool | |
end | |
def roll | |
puts "Rolling..." | |
@doors = shuffle | |
@guards = shuffle | |
@old_guards = Hash.new | |
nil | |
end | |
def shuffle | |
Hash[DOORS.zip BOOLS.shuffle] | |
end | |
end |
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 | |
# This is a solution to the logic puzzle. | |
require_relative 'labyrinth_logic' | |
door_guards = LabyrinthLogic.new | |
left_guard_answer = door_guards.left_guard :right | |
lie = door_guards.right_guard left_guard_answer | |
truth = !lie && :right || :left | |
door_guards.choose! truth |
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
# This makes it really easy to see that its pretty much just a simple series of xor operations. | |
ldoor, rdoor = (lguard, rguard = [true, false].shuffle).shuffle | |
lguard ^ rguard ^ rdoor == ldoor |
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
# This is just because I wanted to do something horrible. | |
tap{|b|break [!b,!!b].shuffle.tap{|c|c+c.shuffle}.each_slice(3).to_a.tap{|x|break x.last.first == x.first.inject{|m,o| m.nil? ? o : m ^ o}}} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment