recursion - 如何在所有情况下使这个 F# 函数尾递归?
问题描述
我一直在努力解决今年的 F# 代码出现问题,以此来提高我在这门语言方面的技能。我为第 8 天第 1 部分提出了以下解决方案:
namespace AdventOfCode2018.Core
module Day8 =
let calculatePart1 input =
let rec take numberToTake numberTaken taken remaining =
if numberTaken = numberToTake || List.isEmpty remaining then
taken, remaining
else
take numberToTake (numberTaken + 1)
(List.head remaining :: taken) (List.tail remaining)
let rec calculate input sum depth maxDepth =
let quantityOfChildNodes, quantityOfMetadata, remaining =
match input with
| qc :: qm :: tl -> qc, qm, tl
| _ -> 0, 0, []
let input, sum =
match quantityOfChildNodes with
| 0 -> remaining, sum
| q -> calculate remaining sum 1 q
let metadata, remaining = take quantityOfMetadata 0 [] input
let sum = sum + List.sum metadata
if depth = maxDepth then remaining, sum
else calculate remaining sum (depth + 1) maxDepth
calculate input 0 0 1 |> snd
我的代码对问题产生了正确的解决方案,并且似乎运行得足够快(在 i7 机器上使用我的拼图输入 13 毫秒)。但是,在调试代码时,我注意到它不是尾递归的。其中的第一个递归调用会calculate
生成一个新的堆栈帧。函数末尾的第二个递归调用没有。我确信必须可以将第一个调用编写为尾递归,但我不确定如何。
解决方案
推荐阅读
- mongodb - 在我刷新数据库连接之前,Mongoose 不会获取数据
- graphql - 是否使用 GraphQL 查询或变异来发送外部消息
- autohotkey - 我的脚本在某些时候崩溃了,我已经消除了调试器能够发现的所有语法错误
- reactjs - 使用 React 在 ASP.NET Core 3 中更改用于获取数据的基本 URL
- javascript - 带有颜色和行号的 console.log 包装器
- wpf - .net Core 3.1 WPF 关闭 Cleartype?
- javascript - 如何将文本放入 react-icons 组件中?
- html - 更改侧面和卡片之间的边距大小
- macos - macOs Time Machine:两个独立的驱动器还是一个 RAID-1?
- python - Python,将函数应用于数据是参数的熊猫数据框