RosettaCodeData/Task/Dinesmans-multiple-dwelling-problem/Scala/dinesmans-multiple-dwelling-problem-3.scala
2015-02-20 00:35:01 -05:00

47 lines
2.1 KiB
Scala

import scala.math.abs
object Dinesman2 extends App {
val groundFloor = 1
abstract class Rule(val person: String) { val exclusion: Map[String, Int] => Boolean }
/** Rules with related tenants and restrictions*/
def rulesDef(topFloor: Int) = List(
new Rule("Baker") { val exclusion = (_: Map[String, Int])(person) != topFloor },
new Rule("Cooper2") { val exclusion = (_: Map[String, Int])(person) != groundFloor },
new Rule("Fletcher4") {
val exclusion = (suggestedFloor2: Map[String, Int]) => !List(groundFloor, topFloor).contains(suggestedFloor2(person))
}, new Rule("Miller") {
val exclusion = (suggestedFloor3: Map[String, Int]) => suggestedFloor3(person) > suggestedFloor3("Cooper2")
}, new Rule("Smith") {
val exclusion = (suggestedFloor4: Map[String, Int]) => abs(suggestedFloor4(person) - suggestedFloor4("Fletcher4")) != 1
}, new Rule("Fletcher4") {
val exclusion = (suggestedFloor5: Map[String, Int]) => abs(suggestedFloor5(person) - suggestedFloor5("Cooper2")) != 1
})
def extensionDef(topFloor: Int) = List(new Rule("Rollo5") {
val exclusion = (suggestedFloor6: Map[String, Int]) => !List(3, 4, topFloor).contains((suggestedFloor6: Map[String, Int])(person))
}, new Rule("Rollo5") {
val exclusion = (suggestedFloor7: Map[String, Int]) => suggestedFloor7(person) < suggestedFloor7("Smith")
}, new Rule("Rollo5") {
val exclusion = (suggestedFloor8: Map[String, Int]) => suggestedFloor8(person) > suggestedFloor8("Fletcher4")
})
def allRulesDef(topFloor: Int) = rulesDef(topFloor) ++ extensionDef(topFloor)
val tenants = allRulesDef(0).map(_.person).distinct // Pilot balloon to get # of tenants
val topFloor = tenants.size
val exclusions = allRulesDef(topFloor).map(_.exclusion)
tenants.permutations.map(_ zip (groundFloor to topFloor)).
filter(p => exclusions.forall(_(p.toMap))).toList match {
case Nil => println("No solution")
case xss => {
println(s"Solutions: ${xss.size}")
xss.foreach { l =>
println("possible solution:")
l.foreach(p => println(f"${p._1}%11s lives on floor number ${p._2}"))
}
}
}
}