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
.
Ungolfed
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>