Я читаю книгу Pearls of Functional Algorithm Design. Пытался реализовать решение по принципу "разделяй и властвуй" для задачи наименьшее свободное число.
minfree xs = minfrom 0 (length xs) xs
minfrom a 0 _ = a
minfrom a n xs = if m == b - a
then minfrom b (n-m) vs
else minfrom a (m) us
where b = a + 1 + (n `div` 2)
(us,vs) = partition (<b) xs
m = length us
Но это работает не быстрее решения, которое можно было бы назвать «наивным». Который
import Data.List ((\\))
minfree' = head . (\\) [0..]
Я не знаю, почему это так, что не так с алгоритмом «разделяй и властвуй» и как его улучшить.
Пытался использовать BangPatterns
, реализовав версию partition
, которая также возвращает длину первого списка в кортеже, поэтому исключается дополнительный обход для m =length us
. Ни у кого из них не было улучшений.
Первый занимает более 5 секунд, тогда как второй делает это почти мгновенно в ghci на входе [0..9999999]
.