我正在try 解决以下问题:

两个玩家从一堆硬币开始,每个玩家可以 Select 从一堆硬币中取出一枚或两枚硬币.拿出最后一枚硬币的玩家输了.

我想出了以下幼稚的递归实现 (playgound):

func gameWinner(coinsRemaining int, currentPlayer string) string {
    if coinsRemaining <= 0 {
        return currentPlayer
    }

    var nextPlayer string

    if currentPlayer == "you" {
        nextPlayer = "them"
    } else {
        nextPlayer = "you"
    }

    if gameWinner(coinsRemaining-1, nextPlayer) == currentPlayer || gameWinner(coinsRemaining-2, nextPlayer) == currentPlayer {
        return currentPlayer
    } else {
        return nextPlayer
    }
}

func main() {
  fmt.Println(gameWinner(4, "you")) // "them"
}

上面的代码运行良好.

然而,当我通过实现备忘录来改进这个解决方案时(见下文,或on the playgound),我得到了错误的答案.

func gameWinner(coinsRemaining int, currentPlayer string, memo map[int]string) string {
    if coinsRemaining <= 0 {
        return currentPlayer
    }

    var nextPlayer string

    if currentPlayer == "you" {
        nextPlayer = "them"
    } else {
        nextPlayer = "you"
    }

    if _, exists := memo[coinsRemaining]; !exists {
        if gameWinner(coinsRemaining-1, nextPlayer, memo) == currentPlayer || gameWinner(coinsRemaining-2, nextPlayer, memo) == currentPlayer {
            memo[coinsRemaining] = currentPlayer
        } else {
            memo[coinsRemaining] = nextPlayer
        }
    }

    return memo[coinsRemaining]
}

func main() {
    memo := make(map[int]string)
    fmt.Println(gameWinner(4, "you", memo))
}

任何关于第二个实现返回不同值给第一个实现的帮助都将不胜感激!

推荐答案

你的回忆录错了:获胜者不仅取决于当前的硬币数量,还取决于轮到谁.您需要以下内容:

type state struct {
    coinsRemaining int
    currentPlayer string
}
memo := make(map[state]string)

Go相关问答推荐

区分Terminal和Hook Zerolog Go中的错误级别日志(log)输出

使用恶意软件 scanner (ClamAV)时的Google云存储桶上传文件验证

向API网关终结点发出POST请求时出现AWS Lambda With Go:";Rune me.InvalidEntrypoint";错误

如何在使用中介资源时处理函数中的`defer`

使用GO从RDPMC获得价值

Go SQLCMD比Windows本机版本慢吗?

错误&对象已被Golang在K8s操作符上修改

如何使用 AWS sdk 在 Go 中正确解组 PartiQL 查询的结果?

优化方式中所有可能组合的字符串相似度

如何从 Go Lambda 函数返回 HTML?

有没有办法在 Golang 中使用带有 go-simple-mail lib 的代理?

我突然无法再将我的 GoLang 应用程序部署到 Google AppEngine

CBC Decrypter 解密加密文本,但部分文本被随机字符替换

如何模仿联合类型

Go gmail api 快速入门导致本地主机拒绝连接 ERR_CONNECTION_REFUSED

显示作为服务帐户身份验证的谷歌日历事件 - Golang App

将 CSVExport 函数传递给处理程序 Gin

为什么 go.mod 中的所有依赖都是间接的?

行之间的模板交替设计

Golang 与 Cassandra db 使用 docker-compose:cannot connect (gocql)