JavaScript (ES6), 65 64 bajtów
f=(a,i=1)=>a>i?(c=f(a-i,i+=2))[0]==i?[i-2,...c]:f(a,i):a<i?0:[i]
Zwraca tablicę, jeśli istnieje rozwiązanie, lub 0 dla braku rozwiązania.
Jest to bardzo nieefektywny, ale golfowy rozwiązanie problemu.
Szuka pierwszego rozwiązania za pomocą a-ii i=1, nawet jeśli nie działa na stos rekurencyjny. Jeśli to rozwiązanie się nie zacznie i+2, wówczas rekurencyjnie szukamy pierwszego rozwiązania za pomocą ai i+2.
Bez golfa
f=(a,i=1)=>
a > i ?
(c = f(a - i, i += 2))[0] == i ?
[i-2, ...c] :
f(a, i) :
a < i ?
0 :
[i]
Przypadki testowe:
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]
Aby dowiedzieć się, jak to jest nieefektywne, rozwiązanie f(104)wymaga 69 535 połączeń rekurencyjnych. Stos nigdy nie ma więcej niż 51 poziomów głębokości, więc nie ma problemu z przepełnieniem stosu.
Rozwiązanie f(200)wymaga 8,6 miliona połączeń rekurencyjnych, z głębokością stosu 99 poziomów. (Jego rozwiązaniem jest [11,13,15,17,19,21,23,25,27,29].)
Oto wizualna reprezentacja uruchomionego programu:
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>