scalazState
を使用して複雑なステートフルな計算を実行する方法を理解しようとしています。問題は次のとおりです。
List[Int]
潜在的な約数の aと数の a を指定して、一致するペア (除数、数)List[Int]
の ] を見つけます。ここで、約数は最大 1 つの数と一致することが許可されています。List[(Int, Int)
テストとして:
def findMatches(divs: List[Int], nums: List[Int]): List[(Int, Int)]
そして、次の入力を使用します。
findMatches( List(2, 3, 4), List(1, 6, 7, 8, 9) )
最大で 3 試合を獲得できます。リスト lr をトラバースして発生する順序で一致を作成する必要があると規定すると、一致は次のようになります。
List( (2, 6) , (3, 9) , (4, 8) )
したがって、次の 2 つのテストに合格する必要があります。
assert(findMatches(List(2, 3, 4), List(1, 6, 7, 8, 9)) == List((2, 6), (3, 9), (4, 8)))
assert(findMatches(List(2, 3, 4), List(1, 6, 7, 8, 11)) == List((2, 6), (4, 8)))
緊急の解決策は次のとおりです。
scala> def findMatches(divs: List[Int], nums: List[Int]): List[(Int, Int)] = {
| var matches = List.empty[(Int, Int)]
| var remaining = nums
| divs foreach { div =>
| remaining find (_ % div == 0) foreach { n =>
| remaining = remaining filterNot (_ == n)
| matches = matches ::: List(div -> n)
| }
| }
| matches
| }
findMatches: (divs: List[Int], nums: List[Int])List[(Int, Int)]
remaining
の状態と累積を更新する必要があることに注意してくださいmatches
。scalaz traverse のお仕事みたいですね!
私の無駄な作業は、私をここまでさせました:
scala> def findMatches(divs: List[Int], nums: List[Int]): List[(Int, Int)] = {
| divs.traverse[({type l[a] = State[List[Int], a]})#l, Int]( div =>
| state { (rem: List[Int]) => rem.find(_ % div == 0).map(n => rem.filterNot(_ == n) -> List(div -> n)).getOrElse(rem -> List.empty[(Int, Int)]) }
| ) ~> nums
| }
<console>:15: error: type mismatch;
found : List[(Int, Int)]
required: Int
state { (rem: List[Int]) => rem.find(_ % div == 0).map(n => rem.filterNot(_ == n) -> List(div -> n)).getOrElse(rem -> List.empty[(Int, Int)]) }
^