Skip to content

Instantly share code, notes, and snippets.

@chasballew
Created April 26, 2015 01:18
Show Gist options
  • Save chasballew/3194f5ba5ef1603d4d54 to your computer and use it in GitHub Desktop.
Save chasballew/3194f5ba5ef1603d4d54 to your computer and use it in GitHub Desktop.
Cheryl's Birthday in Ruby
# http://nbviewer.ipython.org/url/norvig.com/ipython/Cheryl.ipynb
DATES = ['May 15', 'May 16', 'May 19',
'June 17', 'June 18',
'July 14', 'July 16',
'August 14', 'August 15', 'August 17']
def month(date)
date.split[0]
end
def day(date)
date.split[1]
end
def tell (part, possible_dates=DATES)
# When Cheryl tells part of her birthday, return a new list of possible dates.
possible_dates.select { |date| date if date.include? part }
end
def know(possible_dates)
# If there is only one possible date left, we know Cheryl's birthday.
possible_dates.length == 1
end
def cheryls_birthday(possible_dates=DATES)
# Return a list of the possible dates for which statements 3 to 5 are true.
possible_dates.select { |date| date if statements3to5(date) }
end
def statements3to5(date)
statement3(date) && statement4(date) && statement5(date)
end
def statement3(date)
# Albert: I don't know when Cheryl's birthday is,
possible_dates = tell(month(date))
clause1 = (not know(possible_dates))
# but I know that Bernard does not know too.
clause2 = possible_dates.all? { |d| not know(tell(day(d)))}
clause1 && clause2
end
def statement4(date)
# At first, Bernard doesn't know.
at_first = tell(day(date))
clause1 = (not know(at_first))
# But after just considering dates for which statement 3 is true, he knows.
clause2 = know(at_first.select { |d| statement3(d) } )
# check: DATES.select { |d| statement3(d) }.select{ |d| statement4(d) }
clause1 && clause2
end
def statement5(date)
# After hearing the month and statement 4, Albert knows
know(tell(month(date)).select { |d| statement4(d) })
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment