Доброе время суток!
Столкнулся со следующей задачей: необходимо вывести список длиной n, состоящий из чисел Трибоначчи (как Фибоначчи только по три складываются), сделать это быстро и памяти много не занимать!
Сначала я решил задачу так:
Trib :: (a, a, a) -> Int -> [Int]
Trib (a, b, c) n = map Tribonachi [1.. n]
where Tribonachi 1 = a
Tribonachi 2 = b
Tribonachi 3 = c
Tribonachi n = Tribonachi (n - 1) + Tribonachi (n - 2) + Tribonachi (n - 3)
Но это было слишком медленно, что впрочем легко предсказуемо. Тогда я, вспомнив про идею использования аккумулятора, написал такой код:
Trib :: (a, a, a) -> Int -> [Int]
Trib (a,b,c) n = Tribonachi [a, b, c] n
where Tribonachi xs n = if length xs == n then xs
else Tribonachi (xs ++ [last xs + last (init xs) + last (init(init xs))]) n
На этот раз сожрало слишком много памяти, тогда я попытался сэкономить память там, где у меня идет слияние двух список (а именно на втором ее аргументе), введя еще 3 аккумулятора (чтобы не нужно было создавать кучу разных список с init), но тогда снова вышел за рамки времени. Последняя надежда какая-нибудь лямбда-абстракция,но я точно ее не придумал пока. Прошу помощи. Где тут можно оптимизировать дальше?