Created
July 6, 2013 02:30
-
-
Save kiris/5938391 to your computer and use it in GitHub Desktop.
http://www.itmedia.co.jp/enterprise/articles/1004/03/news002_2.html が会社で流行ってたのでScalaで解いてみた。
枝切りとかは面倒なのでしてない。
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
object Mahjong { | |
type Hands = Seq[(Int, Int)] | |
type State = (List[Mentsu], Option[Int], Option[Mati]) | |
abstract class Mentsu | |
case class Zyuntsu(n: Int) extends Mentsu | |
case class Kotsu(n: Int) extends Mentsu | |
abstract class Mati | |
case class ZyuntsuMati(n1: Int, n2:Int) extends Mati | |
case class KotsuMati(n1: Int) extends Mati | |
case class AtamaMati(n1: Int) extends Mati | |
def collectGoal(hands:Hands, state:State):List[State] = { | |
hands.filter(_._2 > 0) match { | |
case Nil => | |
List(state) | |
case xs => | |
kotsu(xs, state) ++ zyuntsu(xs, state) ++ atama(xs, state) ++ mati(xs, state) | |
} | |
} | |
def kotsu(hands:Hands, state:State):List[State] = { | |
hands match { | |
case (n, i) :: tail if i >= 3 => | |
collectGoal((n, i - 3) :: tail, state.copy(_1 = state._1 :+ Kotsu(n))) | |
case _ => | |
Nil | |
} | |
} | |
def zyuntsu(hands:Hands, state:State):List[State] = { | |
hands.splitAt(3) match { | |
case (xs @ List((n1, i1), (n2, i2), (n3, i3)), tail) if n2 - n1 == 1 && n3 - n2 == 1 => | |
collectGoal(xs.map({case (n, i) => (n, i - 1)}) ++ tail, state.copy(_1 = state._1 :+ Zyuntsu(n1))) | |
case _ => | |
Nil | |
} | |
} | |
def atama(hands:Hands, state:State):List[State] = { | |
(hands, state) match { | |
case ((n, i) :: tail, (_, None, mati)) if i >= 2 && mati.filter(_.isInstanceOf[AtamaMati]).isEmpty => | |
collectGoal((n, i - 2) :: tail, state.copy(_2 = Some(n))) | |
case _ => | |
Nil | |
} | |
} | |
def mati(hands:Hands, state:State):List[State] = { | |
state match { | |
case (_, _, None) => | |
zyuntsuMati(hands, state) ++ kotsuMati(hands, state) ++ atamaMati(hands, state) | |
case _ => | |
Nil | |
} | |
} | |
def zyuntsuMati(hands:Hands, state:State):List[State] = { | |
hands.splitAt(2) match { | |
case (xs @ List(n1, n2), tail) if n2._1 - n1._1 <= 2 => | |
collectGoal(xs.map({case (n, i) => (n, i - 1)}) ++ tail, state.copy(_3 = Some(ZyuntsuMati(n1._1, n2._1)))) | |
case _ => | |
Nil | |
} | |
} | |
def kotsuMati(hands:Hands, state:State):List[State] = { | |
hands match { | |
case (n, i) :: tail if i >= 2 => | |
collectGoal((n, i - 2) :: tail, state.copy(_3 = Some(KotsuMati(n)))) | |
case _ => | |
Nil | |
} | |
} | |
def atamaMati(hands:Hands, state:State):List[State] = { | |
(hands, state) match { | |
case ((n, i) :: tail, (_, None, _)) => | |
collectGoal((n, i - 1) :: tail, state.copy(_3 = Some(AtamaMati(n)))) | |
case _ => | |
Nil | |
} | |
} | |
def main(args:Array[String]): Unit = { | |
val in = args(0) | |
val hands = (1 to 9).map(i => (i, in.count(i.toString == _.toString))).toList | |
val result = collectGoal(hands, (Nil, None, None)).distinct.map({ case (mentsu, atama, mati) => | |
val atamaStr = atama.map(n => s"${n}${n}") | |
val mentsuStr = mentsu.map { | |
case Zyuntsu(n) => Some(s"${n}${n+1}${n+2}") | |
case Kotsu(n) => Some(s"${n}${n}${n}") | |
} | |
val matiStr = mati.get match { | |
case ZyuntsuMati(n1, n2:Int) => s"${n1}${n2}" | |
case KotsuMati(n: Int) => s"${n}${n}" | |
case AtamaMati(n: Int) => s"${n}" | |
} | |
((mentsuStr :+ atamaStr).flatten.map(n => s"(${n})") :+ s"[${matiStr}]").mkString("") | |
}) | |
println(result.mkString("\n")) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment