Skip to content

Instantly share code, notes, and snippets.

@douglasjose
Created May 2, 2015 05:42
Show Gist options
  • Save douglasjose/f99d5eb0ade907da91e8 to your computer and use it in GitHub Desktop.
Save douglasjose/f99d5eb0ade907da91e8 to your computer and use it in GitHub Desktop.
"Cheryl's Birthday" solution in Scala, based on the solution from Peter Norvig at http://nbviewer.ipython.org/url/norvig.com/ipython/Cheryl.ipynb
package com.douglasjose.tech
/**
* "Cheryl's Birthday" solution in Scala, based on the solution from Peter Norvig at
* http://nbviewer.ipython.org/url/norvig.com/ipython/Cheryl.ipynb
*
* @author Douglas José (@douglasjose)
*/
class CherylsBirthday {
type Date = (Symbol, Int)
type Part = Either[Symbol, Int]
val dates:List[Date] = List(
('may, 15), ('may, 16), ('may, 19),
('jun, 17), ('jun, 18),
('jul, 14), ('jul, 16),
('aug, 14), ('aug, 15), ('aug, 17)
)
def month(d: Date):Part = Left(d._1)
def day(d: Date):Part = Right(d._2)
def tell(part: Part, possibleDates: List[Date] = dates) =
possibleDates.filter {d => part match {
case Left(month) => d._1 == month
case Right(day) => d._2 == day
}
}
def know(possibleDates: List[Date]) = possibleDates.length == 1
// Albert: I don't know when Cheryl's birthday is, but I know that Bernard does not know too.
def statement3(date: Date) = {
val possibleDates = tell(month(date))
!know(possibleDates) && possibleDates.forall(d => !know(tell(day(d))))
}
// Bernard: At first I don't know when Cheryl's birthday is, but I know now.
def statement4(date: Date) = {
val atFirst = tell(day(date))
!know(atFirst) && know(atFirst.filter(statement3))
}
// Albert: Then I also know when Cheryl's birthday is.
def statement5(date: Date) = know(tell(month(date)).filter(statement4))
def statements3to5(date: Date) = statement3(date) && statement4(date) && statement5(date)
def cherylsBirthday(possibleDates: List[Date] = dates) = possibleDates.filter(statements3to5)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment