Skip to content

Instantly share code, notes, and snippets.

@acook
Last active December 17, 2015 00:49
Show Gist options
  • Save acook/5523462 to your computer and use it in GitHub Desktop.
Save acook/5523462 to your computer and use it in GitHub Desktop.
# 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
#!/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 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 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