我一直在努力解决今年的F#代码问世问题,以此来提高我的语言能力。我为Day 8, Part 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机器上的我的拼图输入13ms)。但是,在调试代码时,我注意到它不是尾递归的。 calculate
中的第一个递归调用将生成一个新的堆栈帧。函数末尾的第二个递归调用没有。我确定写第一个调用必须是尾递归的,但我不确定怎么做。