Прежде всего, я прошу прощения, если название этого сообщения вводит в заблуждение, оно основано на том, что я думаю, может быть моей проблемой. Я создаю ленивый список кортежей, конечная цель - найти всех пифагорейских троек со значениями, меньшими или равными n, и вместо того, чтобы создавать все возможные комбинации «троек», я выбрал этот подход который я считаю более эффективным, но может быть излишним, однако, это работает:)
val n = 20
val increasingTriplets = unfold(Option(1, 1, 1)) {
case None => None
case Some(current) =>
val maybeNext = current match {
case (`n`, `n`, `n`) => None
case (x, `n`, `n`) => Some(x + 1, x + 1, x + 1)
case (x, y, `n`) => Some(x, y + 1, y + 1)
case (x, y, z) => Some(x, y, z + 1) // (1,1,1) , (1,1,2), (1,1,3)...etc
}
Some(current, maybeNext)
}.take(nCr(`n`+3-1,3).toInt).filter({ // The formula for the number of combinations with repetition -
case (a,b,c) => a*a + b*b == c*c // - allowed of ? objects from ? types is ?+?−1C?
// Ensures minimum number of lists is always generated(I think)
})
println(unfold_with_pythcomp(increasingTriplets,pythcomp).toList)
// n = 20 List((3,4,5), (4,3,5), (5,12,13), (12,5,13), (6,8,10)
List((3,4,5), (4,3,5), (5,12,13), (12,5,13), (6,8,10), (8,6,10),
(8,15,17), (15,8,17), (9,12,15), (12,9,15), (12,16,20), (16,12,20))
// n = 10
List((3,4,5), (4,3,5), (6,8,10), (8,6,10))
// Implementation of unfold
def unfold[A, S](z: S)(f: S => Option[(A, S)]): LazyList[A] =
f(z).map((p: (A, S)) => p._1 #:: unfold(p._2)(f)).getOrElse(LazyList.empty[A])
def unfold_with_pythcomp[A](l1: LazyList[A], f: A => Option[(A, A)]): LazyList[A] =
// unfolds result list appending the "complement"
l1 match {
case LazyList() => l1
case x #:: y => f(x) match {
case Some((l, r)) => l #:: r #:: unfold_with_pythcomp(y, f)
}
}
def pythcomp(t: (Int, Int, Int)): Option[((Int, Int, Int), (Int, Int, Int))] = t match {
//Creates a "complement" to add since (3,4,5) <-> (4,3,5)
case (a, b, c) => Some((a, b, c), (b, a, c))
}
def fact(n: Int): BigInt = { // These are just for efficiency, you may ignore
@tailrec def go(n: Int, acc: BigInt): BigInt =
if (n <= 0) acc
else go(n - 1, BigInt(n) * acc)
go(n, 1)
}
def nCr(n: Int, r: Int): BigInt = { // These are just for efficiency, you may ignore
fact(n)/(fact(n-r) * fact(r))
}
Теперь я пытаюсь превратить это в функцию, которая будет делать то же самое, пока принимая просто n в качестве аргумента, который может быть очень простым, однако я столкнулся с проблемами, пытаясь сопоставить шаблон с данным n аргументом. Это то, что я придумал до сих пор:
def unfold_remix[Int](`n`: Int): LazyList[Option[(Int, Int, Int)]] =
// not sure if I can use backticks here
unfold(Option(1, 1, 1)) {
case None => None
case Some(current) =>
// Problem could also be from here.
val maybeNext = current match {
case (`n`, `n`, `n`) => None
case (x, `n`, `n`) => Some(x + 1, x + 1, x + 1)
case (x, y, `n`) => Some(x, y + 1, y + 1)
case (x, y, z) => Some(x, y, z + 1) // (1,1,1) , (1,1,2), (1, 1,3)...1st
}
Some(current, **maybeNext**)
// I get an error on this line under maybeNext.
// Too many arguments for method apply(A)
}
Я продолжаю получать сообщение об ошибке при попытке инициализировать список, как я делал ранее, и будучи новичком в Scala Я не могу понять, Почему. Я попробовал аргумент с и без обратной галочки, и это тоже не сработало. Интересно, можно ли кому-нибудь помочь мне разобраться в проблеме, а также мне хотелось бы знать, возможно ли сопоставить шаблон с целочисленным аргументом «глобально» внутри функции. Спасибо!