Я недавно начал решать проблемы Project Euler в Scala, однако, когда я добрался до проблемы 14, я получил StackOverflowError, поэтому я переписал свое решение на F #, поскольку (как мне сказали), компилятор F #, в отличие от Scala (который производит Javabytecode), переводит рекурсивные вызовы в циклы.Поэтому мой вопрос к вам, как это возможно, что код ниже генерирует исключение StackOverflowException после достижения некоторого числа выше 113000?Я думаю , что рекурсия не должна быть хвостовой рекурсией, чтобы ее можно было перевести / оптимизировать, не так ли?Я попытался несколько переписать мой код, но безуспешно.Я действительно не хочу писать код в императивном стиле с использованием циклов, и я не думаю, что мог бы превратить функцию len в хвостовую рекурсию, даже если это было проблемой, препятствующей ееот оптимизации.
module Problem14 =
let lenMap = Dictionary<'int,'int>()
let next n =
if n % 2 = 0 then n/2
else 3*n+1
let memoize(num:int, lng:int):int =
lenMap.[num]<-lng
lng
let rec len(num:int):int =
match num with
| 1 -> 1
| _ when lenMap.ContainsKey(num) -> lenMap.[num]
| _ -> memoize(num, 1+(len (next num)))
let cand = seq{ for i in 999999 .. -1 .. 1 -> i}
let tuples = cand |> Seq.map(fun n -> (n, len(n)))
let Result = tuples |> Seq.maxBy(fun n -> snd n) |> fst
ПРИМЕЧАНИЕ. Я знаю, что приведенный ниже код очень далек от оптимального, и несколько строк могут быть намного проще, но я не очень хорошо разбираюсь в F # и не стал искатьспособы упростить и сделать его более элегантным (пока).
Спасибо.