【问题标题】:Sum of a predefined List F#预定义列表 F# 的总和
【发布时间】:2021-03-30 14:19:50
【问题描述】:

我是 F# 初学者,目前在 BlackJack F# 实现中尝试一些 Lists 操作。

我正在尝试总结我创建的列表的元素,如下所示:

let cardsvalue (k: Cards): List<int> =
    match k with
    |Ace ->  [1;11]
    |Two -> [2] 
    |Three -> [3]
    |Four -> [4]
    |Five -> [5]
    |Six -> [6]
    |Seven -> [7]
    |Eight -> [8]
    |Nine -> [9]
    |Ten | Jack | Queen | King -> [10] 

type Cards 只是二到九、十到国王和王牌的组合。

所以我需要某种递归函数 CardPoints,它只是添加来自 cardsvalue 的项目,例如 [Two; Three] = [5][Ace; Ace; Ace] = [3; 13; 23; 33] 表示 Ace 的所有可能值。我尝试了几种常见的求和方法,但我总是以类型不匹配或不支持运算符错误而告终。例如

let rec CardPoints (cp: List<Cards>): List<int> =   
   match cp with
   | head :: tail -> head + CardPoints tail
   | [] -> 0 

不接受 + 运算符。

我很想看到这个问题的可能实现。感谢您的宝贵时间!

【问题讨论】:

  • 您正在尝试将数字添加到数字列表中
  • 你很亲密,所以告诉你会破坏它。
  • 你介意分享一下吗?它会是什么样子
  • 这里的问题是,这个小组会收到希望你做功课的人的帖子......所以人们对于明确地给你完整的答案非常紧张。
  • 是的,我可以看到。我想人们更乐意留下未回答的问题

标签: list recursion f# sum blackjack


【解决方案1】:

我是 F# 初学者

您的代码显示了一种很好的系统化方法,并且您已经完成了大部分工作以允许类型系统(和智能感知)帮助解决您的问题。

let cardsvalue (k: Cards): List<int> =

具有完全正确类型签名的有用函数。请注意,它是灰色的。这意味着你没有使用它。

let rec CardPoints (cp: List<Cards>): List<int> =

也完全正确。您正在为类型系统提供尽可能多的帮助,这几乎可以肯定它会发现出现问题的确切点。

我总是以类型不匹配或不支持操作员错误告终。例如

    | head :: tail -> head + CardPoints tail

尝试使用绑定来帮助解决这个问题:

    | head :: tail ->
        let tailPoints = CardPoints tail
        head + tailPoints

您可以告诉(通过将鼠标悬停在它们上面)headCardstailPointsList&lt;int&gt;。因此,您尝试将Cards 添加到List&lt;int&gt; 并且没有定义这样的添加操作。

因此,您已将其简化为一项较小的任务:给定一张卡片 (head: Cards),并从剩余卡片中给出可能的积分 (tailPoints: List&lt;int&gt;),您如何从所有卡片中找到可能的积分,哪个应该是List&lt;int&gt;?您将需要使用您当前未使用的功能cardsvalue 和另一个小步骤,然后您就在那里了。

【讨论】:

  • 能否请您展示它是如何完成的,我无法让它工作。最后一个问题 - 你将如何实现 Ace 得分不超过 21 的条件,例如 [Ace;Ace;Ace] 应该只有 13 (1+1+11) 而[Ace; Five; Ace] 应该是 17。
  • 我个人会定义我自己的type Points = Hard of int | Soft of int*int,而不是使用类似match cp with | Hard x -&gt; Hard x | Soft(x,y) -&gt; if y &gt; 21 then Hard x else Soft(x,y) 的东西,但这需要我重新重写所有内容。你能告诉我如果我们使用第三个函数会是什么样子吗?例如let CalScore (cp: List&lt;Cards&gt;): int =
  • @BillyFitt 在尝试扩展或替代方案之前,我会遇到最初的问题并尝试工作。您需要创建一个函数,该函数给出剩余卡片的可能分数的Cardsint list,将返回总体可能分数的int list。您已经有了一个功能,可以让您从卡片中获得可能的分数。这可以用来简化问题,消除Cards,所以在剩下的步骤中你只需要使用整数。
  • 最初的问题是我在帖子中提出的问题。你能告诉我怎么做吗,我的意思是使用我当前未使用的功能卡值和另一个小步骤 - 我仍然无法让它工作
  • 那么你的 cardsValue 函数给你第一张卡片的可能值(一个int list),递归给你tailPoints,另一个int list。所以问题简化为:给定两个int lists,找出所有可能的和。为此,您可能会发现使用函数List.mapList.concat 会很有帮助,或者使用“yield”语法构造一个列表[ for x in someSequence do yield f(x) ]
【解决方案2】:

好的,你的答案非常接近。 但是您正在尝试将“卡”添加到整数列表中。 您要做的是获取卡片的每个可能值并将其添加到其余卡片总和的每个可能值中。

好的,我可能不会这样做,但也许这是最容易理解的答案(假设你理解列表推导)。

它在功能上也不是很完美,但我会留给你去发现和修复。

let rec cardPoints (cp: List<Card>): List<int> =   
   match cp with
   | head :: tail -> 
        [ for val1 in cardsvalue head do
            for val2 in cardPoints tail do 
                val1 + val2 ]
   | [] -> [0]

【讨论】:

  • 谢谢!您可能想将yield 编辑为val1 + val2
  • 我还没有测试过,F# 支持隐式产量,所以在我的脑海里它可以工作,它会给出重复。
猜你喜欢
  • 2019-02-26
  • 2023-04-10
  • 1970-01-01
  • 2014-09-13
  • 2018-07-08
  • 1970-01-01
  • 2012-11-26
  • 2011-04-05
  • 1970-01-01
相关资源
最近更新 更多