JavaScript (ES6), 65 64 байт
f=(a,i=1)=>a>i?(c=f(a-i,i+=2))[0]==i?[i-2,...c]:f(a,i):a<i?0:[i]
Повертає масив, якщо є рішення, або 0 для рішення немає.
Це вкрай неефективний, але гострий спосіб вирішення проблеми.
Він шукає перше рішення, використовуючи, a-i
і i=1
навіть якщо він не працює рекурсивний стек. Якщо це рішення не починається i+2
, тоді ми рекурсивно шукаємо перше рішення за допомогою a
і i+2
.
Безумовно
f=(a,i=1)=>
a > i ?
(c = f(a - i, i += 2))[0] == i ?
[i-2, ...c] :
f(a, i) :
a < i ?
0 :
[i]
Тестові приклади:
f=(a,i=1)=>a>i?(c=f(a-i,i+=2))[0]==i?[i-2,...c]:f(a,i):a<i?0:[i]
console.log(JSON.stringify(f(1))); //[1]
console.log(JSON.stringify(f(3))); //[3]
console.log(JSON.stringify(f(4))); //[1, 3]
console.log(JSON.stringify(f(5))); //[5]
console.log(JSON.stringify(f(6))); //[0]
console.log(JSON.stringify(f(9))); //[1, 3, 5]
console.log(JSON.stringify(f(15))); //[3, 5, 7]
console.log(JSON.stringify(f(104))); //[23, 25, 27, 29]
Щоб зрозуміти, наскільки це неефективно, рішення f(104)
вимагає 69 535 рекурсивних дзвінків. Стек ніколи не перевищує 51 рівень глибиною, тому немає проблем із переповненням стека.
Для вирішення f(200)
необхідних 8,6 мільйонів рекурсивних викликів, з глибиною 99 рівнів. (Його рішення є [11,13,15,17,19,21,23,25,27,29]
.)
Ось наочне зображення запущеної програми:
r=0;
output=o=>setTimeout(_=>O.textContent += o + '\n', r++ * 20);
f=(a,i=1,s='',o = s + 'a=' + a + '; i=' + i + ';')=>
(
output(o),
a > i ?
(c = f(a - i, i += 2, s + ' '))[0] == i ? (
output(o + ' a > i; [i-2, ...c] = [' + [i-2, ...c] + '];'),
[i-2, ...c]
) : (
output(o + ' a > i; c=[' + c + ']; ' + 'c[0]+2 != i ... dead end\n' + s + 'trying a, i+2:'),
f(a, i, s)
) :
a < i ? (
output(o + ' a < i ... dead end'),
0
) : (
output(o + ' a == i;'),
[i]
)
)
f(21); //[5, 7, 9]
<pre id=O></pre>