Так увлёкся игрой
Bitburner, что решил начать выполнять контракты. Условие одного из них следующее (не дословно, но суть та же): найти количество возможных разбиений заданного натурального числа как минимум на два натуральных слагаемых.
Например, число разбиений для числа 4 равно 4:
4 = 1 + 1 + 1 + 1
4 = 2 + 1 + 1
4 = 2 + 2
4 = 3 + 1
Для числа 5 равно 6:
5 = 1 + 1 + 1 + 1 + 1
5 = 2 + 1 + 1 + 1
5 = 2 + 2 + 1
5 = 3 + 1 + 1
5 = 3 + 2
5 = 4 + 1
Задачка довольно простая и известная (на рекурсию). Но решал ли я её самостоятельно, не помню уже. Так вот, так как я играю по-честному, то решил без гугла. Оказалось, не такая она уже и простая
Пришлось очень хорошенько напрячься, чтобы получить работающий алгоритм, да такой, чтобы не было за него стыдно, т.е. без всяких там массивов и прочих костылей. Получился весьма интересный алгоритм:
- Код: Выделить всё
/** @param {NS} ns **/
function ways_to_sum(n, lim)
{
let waysToSum = 0;
if (n > 1) {
for (let i = 2; i <= n; ++i) {
if (i < lim) {
for (let j = 0; j < Math.floor(n / i); ++j) {
waysToSum += 1 + ways_to_sum(n - i * (j + 1), i);
}
}
}
}
return waysToSum;
}
export async function main(ns)
{
const n = ns.args[0];
const lim = ns.args[1];
let total_ways_to_sum = 1 + ways_to_sum(n, lim);
ns.tprint("There are " + total_ways_to_sum + " ways to sum " + n);
}
А главное - он работает
Так вот, решил я посмотреть на решение этой проблемы в Интернете. Нашлись разные, но именно такого решения пока не нашёл. Довольно быстрый получился для рекурсивного
* * *
А вот уже задачка для учёных и немножко для философов
Доказать или опровергнуть гипотезу о том, что можно создать вычислительную систему, на которой рекурсивные алгоритмы будут выполняться быстрее итеративных линейных, т.е. не просто быстрее, а быстрее уже существующих. На вычислительных системах с бесконечной памятью, а, следовательно, и стеком, и O(1) скоростью выделения памяти, рекурсия, думаю, будет быстрее итерации. Только сложно представить себе систему с бесконечной памятью (а ещё сложнее - с "рекурсивной" памятью). Для итеративных алгоритмов самый ценный ресурс - время, которое мы считаем бесконечным, но всё равно жалуемся и плюёмся в экран на медленные алгоритмы. Для рекурсивных алгоритмов самый ценный ресурс - память, которая, в отличие от времени, не бесконечна. Но тут уже философия. Мы, например, не готовы ждать 100 млн лет результатов работы алгоритма (так что для конкретного человека время как раз таки вполне конечно)