0

首先,如果标题具有误导性,我深表歉意,它基于我认为我的问题可能是什么。我正在创建一个惰性元组列表,最终目标是找到所有值小于或等于 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 的初学者,我似乎无法理解为什么。我已经尝试过使用和不使用反引号的论点,但这也不起作用。想知道是否有人可以帮助我解决问题,并且我想知道是否可以在函数中“全局”匹配给定的整数参数。谢谢!

4

1 回答 1

1

不知道这是否返回正确的结果,但它可以编译(类型检查)。

def unfold_remix(n: Int): LazyList[Option[(Int, Int, Int)]] =
  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)
      }
      Some((Some(current), maybeNext))
  }

(而且,是的,对于一个相对简单的任务来说,这实在是太多的代码了。)

于 2020-03-07T20:49:13.383 回答