Mathematica, 79 byte
Min[2#/(d=Divisors@#~Cases~_?OddQ)+d]-2⌊(2#)^.5+.5⌋+⌈Sqrt[8#+1]~Mod~1⌉&
Spiegazione
Non potevo preoccuparmi di implementare l'algoritmo nella sfida, quindi volevo cercare una scorciatoia per la soluzione. Mentre ne ho trovato uno, purtroppo non batte la risposta di Mathematica che implementa l'algoritmo. Detto questo, sono sicuro che questo non è ancora ottimizzato, e potrebbero esserci altre lingue che possono beneficiare di questo approccio o di alcune delle intuizioni acquisite nel processo.
Quindi sostengo che la sequenza che dovremmo calcolare è:
f (n) = 2 * ( A212652 (n) - A002024 (n)) + 1 + A023532 (n-1)
In alternativa, è f (n) = 1 se n è un numero triangolare e f (n) = 2 * ( A212652 (n) - A002024 (n) + 1) altrimenti.
Nella prima espressione, A023532 codifica semplicemente questi due diversi casi. Le altre due sequenze (più 1) sono la differenza tra il numero intero più grande k nella decomposizione più lunga di n in numeri interi consecutivi (k-i + 1) + (k-i + 2) + ... + k = n e il numero intero più grande j in modo che 1 + 2 + ... + j <n .
In parole un po 'più semplici, ecco come troviamo la risposta per i numeri non triangolari: in primo luogo, troviamo il numero triangolare più grande T j che è inferiore a n . Quindi j è il penultimo numero intero che viene aggiunto durante il passaggio 1 (perché dopo aver aggiunto j + 1 avremo superato n ). Quindi decomponi n nel numero massimo (o più piccolo) di numeri interi consecutivi possibile e chiama il massimo tra questi numeri k . Il risultato è semplicemente 2 * (kj) . La ragione intuitiva di ciò è che il massimo nella decomposizione cresce di 1 ogni altro passo e ci fermiamo quando raggiungiamok .
Dobbiamo mostrare quattro cose per dimostrare che funziona:
- f (n) = 1 per i numeri triangolari. Questo è banalmente il caso, perché il primo passo scorre semplicemente attraverso tutti i numeri triangolari. Se abbiamo colpito n esattamente durante questo processo, abbiamo finito e c'era solo un passo da calcolare.
- Per tutti gli altri numeri, finiamo sempre dopo una fase di eliminazione, mai dopo una fase di inserimento. Ciò significa che tutte le altre f (n) sono pari.
- In ogni passaggio di inserimento dopo il primo, aggiungiamo solo un singolo numero. Questo garantisce che raggiungeremo una decomposizione includendo k dopo kj coppie di passi.
- La decomposizione finale di n che otteniamo è sempre la decomposizione più lunga possibile di n in numeri interi consecutivi, ovvero è sempre la decomposizione di n con il massimo più basso tra i numeri sommati. In altre parole, l'ultimo numero che aggiungiamo alla somma è sempre A212652 (n) .
Abbiamo già mostrato perché (1) è vero. Successivamente, dimostriamo che non possiamo terminare con un passaggio di inserimento tranne quello iniziale (che non accade per i numeri non triangolari).
Supponiamo che siamo finiti in una fase di inserimento, raggiungendo n dopo aver aggiunto un valore p alla somma. Ciò significa che prima di questo passaggio di inserimento, il valore era np ( o inferiore se aggiungessimo più valori contemporaneamente). Ma questo passaggio di inserimento è stato preceduto da un passaggio di eliminazione (dal momento che non avremmo potuto premere n durante il passaggio 1). L'ultimo valore q che abbiamo rimosso durante questo passaggio di eliminazione era necessariamente inferiore a p a causa del modo in cui l'algoritmo funziona. Ciò significa che prima di rimuovere q avevamo n-p + q ( o meno ) che è inferiore a n. Ma questa è una contraddizione, perché avremmo dovuto smettere di rimuovere numeri interi quando avessimo premuto n-p + q invece di rimuovere un altro q . Ciò dimostra il punto (2) sopra. Quindi ora sappiamo che finiamo sempre in una fase di eliminazione e che quindi tutti i numeri non triangolari hanno persino output.
Successivamente dimostriamo (3) che ogni passaggio di inserimento può inserire solo un valore. Questo è essenzialmente un corollario di (2). Abbiamo dimostrato che dopo aver aggiunto un valore non possiamo toccare n esattamente e poiché la dimostrazione utilizzava una disuguaglianza, non possiamo nemmeno finire sotto n (poiché allora n-p + q sarebbe comunque inferiore a n e non avremmo dovuto rimuovere che molti valori in primo luogo). Pertanto, ogni volta che aggiungiamo un singolo valore, siamo garantiti per superare n perché siamo andati sotto n rimuovendo un valore più piccolo. Quindi, sappiamo che l'estremità superiore della somma cresce di 1 ogni altro passaggio. Conosciamo il valore iniziale di questa fascia superiore (è la m più piccola taleT m > n ). Ora abbiamo solo bisogno di capire questa fascia alta una volta raggiunta la somma finale. Quindi il numero di passaggi è semplicemente il doppio della differenza (più 1).
Per fare ciò, dimostriamo (4) che la somma finale è sempre la decomposizione di n nel maggior numero possibile di numeri interi, o la decomposizione in cui il massimo in quella decomposizione è minimo (cioè è la prima decomposizione possibile). Lo faremo di nuovo per contraddizione (la formulazione in questa parte potrebbe essere un po 'più rigorosa, ma ho già trascorso troppo tempo su questo ...).
Supponiamo che la prima / più lunga decomposizione possibile di n sia qualche a + (a + 1) + ... (b-1) + b , a ≤ b , e dire che l'algoritmo lo salta. Ciò significa che nel momento in cui b viene aggiunto, a non deve più far parte della somma. Se a fosse parte della somma s , allora avremmo n ≤ s in quel momento. Quindi o la somma contiene solo i valori da a a b , che equivale a n e ci fermiamo (quindi non abbiamo saltato questa decomposizione), oppure c'è almeno un valore in meno di a nella somma, vinci quale caso n <se quel valore verrebbe rimosso fino a quando non avremo raggiunto la somma esatta (di nuovo, la decomposizione non è stata saltata). Quindi dovremmo sbarazzarci di a prima di aggiungere b . Ciò significa che dovremmo raggiungere una situazione in cui a è il componente più piccolo della somma e il più grande non è ancora b . Tuttavia, a quel punto non possiamo rimuovere a , poiché la somma è chiaramente inferiore a n (poiché manca b ), quindi dobbiamo prima aggiungere valori fino a quando non aggiungiamo b e premiamo n esattamente. Questo dimostra (4).
Quindi, tenendo insieme queste cose: sappiamo che la prima coppia di passaggi ci dà un valore massimo di A002024 (n) . Sappiamo che il valore massimo della decomposizione finale è A212652 (n) . E sappiamo che questo massimo viene incrementato una volta in ogni coppia di passaggi. Quindi, l'espressione finale è 2 * ( A212652 (n) - A002024 (n) + 1) . Questa formula funziona quasi per i numeri triangolari, ad eccezione del fatto che per quelli abbiamo bisogno solo di 1 passaggio invece di 2, motivo per cui correggiamo il risultato con la funzione indicatore dei numeri triangolari (o il suo contrario, a seconda di quale sia più conveniente).
Infine, per quanto riguarda l'implementazione. Per la prima sequenza, sto usando la formula MIN (dispari d | n; n / d + (d-1) / 2) da OEIS. Risulta per salvare alcuni byte se prendiamo il fattore 2 in questa espressione per ottenere MIN (dispari d | n; 2n / d + d-1) , perché -1 quindi si annulla con +1 nella mia prima versione di f (n) che codifica direttamente i due casi per numeri triangolari e non triangolari. Nel codice, questo è:
Min[2#/(d=Divisors@#~Cases~_?OddQ)+d]
Per quest'ultima sequenza ( 1, 2, 2, 3, 3, 3, ...
), possiamo usare un semplice modulo chiuso:
⌊(2#)^.5+.5⌋
E infine, la funzione dell'indicatore inverso dei numeri triangolari è 0 ogni volta che 8n + 1 è un quadrato perfetto. Questo può essere espresso in Mathematica come
⌈Sqrt[8#+1]~Mod~1⌉
Esistono molti modi per esprimere queste ultime due sequenze e spostare un offset costante tra loro, quindi sono sicuro che questa non sia ancora un'implementazione ottimale, ma spero che ciò possa dare ad altri un punto di partenza per esaminare nuovi approcci in le loro lingue.
Da quando ho affrontato tutti questi problemi, ecco un diagramma della sequenza fino a n = 1000 (potrei anche calcolare 100k in un paio di secondi, ma in realtà non mostra ulteriori approfondimenti):
Potrebbe essere interessante esaminare le variazioni di quelle linee molto dritte, ma lo lascerò a qualcun altro ...