Quante partizioni ho?


16

Il numero di partizione di un numero intero positivo è definito come il numero di modi in cui può essere espresso come somma di numeri interi positivi. In altre parole, il numero di partizioni intere che ha. Ad esempio, il numero 4ha le seguenti partizioni:

[[1, 1, 1, 1], [1, 1, 2], [1, 3], [2, 2], [4]]

Quindi, ha 5partizioni. Questo è OEIS A000041 .


Compito

Dato un numero intero positivo N determinare il suo numero di partizione.

  • Si applicano tutte le regole standard.

  • L'input e l'output possono essere gestiti con qualsiasi mezzo ragionevole.

  • Questo è , quindi vince il codice più breve in byte.


Casi test

Input | Produzione

1 | 1
2 | 2
3 | 3
4 | 5
5 | 7
6 | 11
7 | 15
8 | 22
9 | 30
10 | 42

1
Sono quasi
sicuro che

@DJMcMayhem Umm, ok. Fammi sapere se trovi un duplicato. Mi dispiace, sono nuovo in tutto questo!

1
@DJMcMayhem forse questa domanda che hai posto dato che si tratta di un breve passaggio da "generazione" a "conteggio" ma non devi necessariamente generare tutte le partizioni per contarle ...
Giuseppe,

1
questo è un duplicato, TRANNE che è un popcon (?) e chiuso come troppo ampio. Imho, questo è molto meglio scritto e dovrebbe essere tenuto aperto, mentre quello vecchio dovrebbe essere (riaperto e) chiuso come dupe
Rod

2
@Rod, è un brutto pop-con, ma cambiare il motivo stretto per ingannare non sarebbe un miglioramento. Il requisito prestazionale ci sarebbe un ostacolo al porting di alcune risposte (nessuno genererà le partizioni 24061467864032622473692149727991 di 1000 in un paio di minuti); e l'implementazione di Hardy-Ramanujan-Rademacher non è esattamente giocata a golf ... Tuttavia, potrebbe valere la pena aprire una discussione in meta su cosa fare con questa domanda e quella.
Peter Taylor,

Risposte:


13

Pyth , 3 byte

l./

Provalo qui!oppure prova una suite di test.

La formattazione della risposta ha richiesto molto più tempo rispetto alla scrittura del codice stesso: P.


Come?

Pyth è lo strumento giusto per il lavoro.

l. / Programma completo con input implicito.

 ./ Partizioni intere. Restituisce tutti gli elenchi ordinati di numeri interi positivi che si aggiungono all'input.
l Lunghezza.
      Emette implicitamente il risultato.

34

Mathematica, 11 byte

PartitionsP

Spiegazione

¯\_(ツ)_/¯


8

Emojicode 0,5, 204 201 byte

🐋🚂🍇🐖🅰️➡🚂🍇🍊⬅🐕1🍇🍎1🍉🍮s 0🔂k⏩0🐕🍇🍦t➖🐕k🍮r t🔂i⏩1 t🍇🍊😛🚮t i 0🍇🍮➕r i🍉🍉🍮➕s✖r🅰️k🍉🍎➗s🐕🍉🍉

Provalo online!

-3 byte usando "minore di o uguale a 1" invece di "minore di 2" perché l'emoji "minore di" ha una codifica UTF-8 piuttosto lunga. Inoltre ha reso tun congelato per silenziare un avviso senza influire sul conteggio dei byte.

Estende la classe 🚂 (intera) con un metodo chiamato 🅰️. Puoi scrivere un semplice programma che prende un numero dall'input, chiama 🅰️ sul numero e stampa il risultato in questo modo:

🏁🍇
 🍦str🔷🔡😯🔤Please enter a number🔤
 🍊🍦num🚂str 10🍇
  😀🔡🅰️num 10
 🍉🍓🍇
  😀🔤Learn what a number is, you moron!🔤
 🍉
🍉

Questa parte potrebbe essere giocata a golf omettendo i messaggi e la gestione degli errori, ma non è inclusa nella partitura, quindi preferisco mostrare più funzionalità di Emojicode, migliorando nel contempo la leggibilità lungo il percorso.

Ungolfed

🐋🚂🍇
 🐖🅰️➡🚂🍇
  🍊◀️🐕2🍇
   🍎1
  🍉
  🍮sum 0
  🔂k⏩0🐕🍇
   🍦nmk➖🐕k
   🍮sig nmk
   🔂i⏩1 nmk🍇
    🍊😛🚮nmk i 0🍇
     🍮➕sig i
    🍉
   🍉
   🍮➕sum✖sig🅰️k
  🍉
  🍎➗sum🐕
 🍉
🍉

Spiegazione

Nota: molta scelta delle emoji non ha molto senso nell'emojicode 0.5. È 0.x, dopo tutto. 0.6 risolverà questo.

Emojicode è un linguaggio di programmazione orientato agli oggetti che presenta generici, protocolli, optionals e chiusure, ma questo programma non utilizza chiusure e tutti i generici e protocolli possono essere considerati impliciti, mentre l'unica opzione appare nello stub I / O.

Il programma funziona solo su alcuni tipi: 🚂 è il tipo intero, 🔡 è il tipo di stringa e ⏩ è il tipo di intervallo. Appaiono anche alcuni booleani (👌), ma sono usati solo in condizioni. I booleani possono assumere un valore di 👍 o 👎, che corrispondono rispettivamente a vero e falso.

Attualmente non ci sono operatori in Emojicode, quindi addizioni, comparazioni e altre operazioni che normalmente sono operatori vengono implementate come funzioni, facendo sì che le espressioni utilizzino la notazione con prefisso . Gli operatori sono inoltre previsti in 0.6.

Affrontiamo prima il programma di test.

🏁

Questo è il blocco 🏁, che può essere paragonato al principale da altre lingue.

🍇 ... 🍉

Uva e angurie dichiarano blocchi di codice in emojicode.

🍦str🔷🔡😯🔤Please enter a number🔤

Questo dichiara un nome "congelato" stre lo imposta su una nuova stringa creata usando l'inizializzatore (costruttore) 😯, che accetta un prompt come stringa e quindi immette una riga dall'utente. Perché usare un congelato anziché una variabile? Non cambierà, quindi una variabile emetterebbe un avviso.

🍊🍦num🚂str 10

Analizziamolo. 🚂str 10chiama il metodo on sul strcongelato con l'argomento 10. Per convenzione, i metodi denominati con il nome di un tipo convertono l'oggetto in quel tipo. 10 è la base da utilizzare per la conversione di numeri interi. Questo metodo restituisce un optional, 🍬🚂. Gli optionals possono contenere un valore del tipo base o il nulla, ⚡. Quando la stringa non contiene un numero, viene restituito ⚡. Per utilizzare il valore, è necessario scartare l'opzione opzionale usando 🍺, che genera un errore di runtime se il valore è ⚡. Pertanto, è buona norma verificare la presenza di nulla prima di scartare un optional. È così comune, infatti, che Emojicode ha una scorciatoia per questo. Normalmente, 🍊è un "if".🍊🍦 variable expressionsignifica: valuta l'espressione. Se il facoltativo contiene nulla, la condizione viene valutata 👎 (falso). Altrimenti, variableviene creato un nome congelato con il valore non scartato dell'opzione facoltativa e la condizione restituisce 👍, (vero). Pertanto, nell'uso normale, 🍇 ... 🍉viene inserito il blocco che segue il condizionale.

😀🔡🅰️num 10

🅰️ è il metodo che il codice principale aggiunge a 🚂 usando 🐋 che calcola il numero di partizioni. Questo chiama 🅰️ sul numcongelato che abbiamo dichiarato nel condizionale e converte il risultato in una stringa usando la base 10 con il metodo 🔡. Quindi, 😀 stampa il risultato.

🍓🍇 ... 🍉

🍓 significa "altro", quindi questo blocco viene inserito quando l'utente non ha inserito un numero correttamente.

😀🔤Learn what a number is, you moron!🔤

Stampa il valore letterale della stringa.

Ora diamo un'occhiata al programma principale. Spiegherò la versione non golfata; la versione golfata ha appena rimosso lo spazio bianco e le variabili sono state rinominate con nomi a lettera singola.

🐋🚂🍇 ... 🍉

Estendi la classe 🚂. Questa è una funzionalità che non si trova comunemente nei linguaggi di programmazione. Invece di creare una nuova classe con 🚂 come superclasse, 🐋 modifica 🚂 direttamente.

🐖🅰️➡🚂🍇 ... 🍉

Crea un nuovo metodo chiamato 🅰️ che restituisce 🚂. Restituisce il numero di partizioni calcolate utilizzando la formulaa(n) = (1/n) * Sum_{k=0..n-1} sigma(n-k)*a(k)

🍊⬅🐕1🍇
 🍎1
🍉

🐕 è simile thiso selfproveniente da altre lingue e si riferisce all'oggetto sul quale è stato chiamato il metodo. Questa implementazione è ricorsiva, quindi questa è la condizione finale: se il numero su cui è stato chiamato il metodo è minore o uguale a 1, restituisce 1.

🍮sum 0

Crea una nuova variabile sume impostala su 0. Assume implicitamente il tipo 🚂.

🔂k⏩0🐕

🔂 scorre su tutto ciò che implementa il protocollo 🔂🐚⚪️, mentre ⏩ è un intervallo letterale che capita di implementare 🔂🐚🚂. Un intervallo ha un valore iniziale, un valore di arresto e un valore di passo, che si presume sia 1 se start < stopo -1 altrimenti. Si può anche specificare il valore del passo usando ⏭ per creare l'intervallo letterale. Il valore iniziale è inclusivo, mentre il valore finale è esclusivo, quindi questo è equivalente for k in range(n)o Sum_{k=0..n-1}nella formula.

🍦nmk➖🐕k

Dobbiamo calcolare sigma (n - k), o la somma dei divisori di n - kin altre parole, e l'argomento è necessario alcune volte, quindi questo memorizza n - knella variabile nmkper salvare alcuni byte.

🍮sig nmk
🔂i⏩1 nmk

Questo imposta la sigvariabile sull'argomento di sigma e scorre su tutti i numeri da 1 a nmk - 1. Potrei inizializzare la variabile su 0 e iterare su 1..nmk ma farlo in questo modo è più breve.

🍊😛🚮nmk i 0

🚮 calcola il resto, o modulo e 😛 verifica l'uguaglianza, quindi la condizione sarà 👍 se iè un divisore di nmk.

🍮➕sig i

Questo è un incarico su chiamata, simile alla += -= >>=famiglia dell'operatore in alcune delle lingue inferiori, prive di emoji. Questa riga può anche essere scritta come 🍮 sig ➕ sig i. Pertanto, al termine del ciclo interno, sigconterrà la somma dei divisori di n - k, osigma(n - k)

🍮➕sum✖sig🅰️k

Un altro compito per chiamata, quindi questo si aggiunge sigma(n - k) * A(k)al totale, proprio come nella formula.

🍎➗sum🐕

Infine, la somma viene divisa per n e viene restituito il quoziente. Questa spiegazione probabilmente ha richiesto tre volte tanto quanto scrivere il codice stesso ...



3

Ottava, 18 byte

partcnt(input(''))

Utilizza la funzione integrata partcnt.

Non riesco a farlo bene usando una funzione anonima usando @, qualche aiuto sarebbe apprezzato.


3

Retina , 34 byte

.+
$*
+%1`\B
;$'¶$`,
,

%O`1+
@`.+

Provalo online!

Spiegazione

.+
$*

Converti l'input in unario.

+%1`\B
;$'¶$`,

Questo calcola tutte le 2 partizioni n-1 dell'elenco di cifre unario. Lo facciamo ripetutamente ( +) facendo corrispondere il primo ( 1) confine non di parole ( \B, cioè una posizione tra due 1s) in ciascuna riga ( %) e sostituendolo con ;, tutto dopo di esso ( $'), un linefeed ( ), tutto davanti a it ( $`) e ,. Esempio:

1;1,111

diventa

      vv
1;1,1;11
1;1,1,11
^^^^^

Dove vsegna il risultato $'e ^segna il risultato $`. Questo è un linguaggio comune per ottenere il risultato di due diverse sostituzioni contemporaneamente (in pratica inseriamo sia la ;e la ,sostituzione, sia le "metà" mancanti della stringa per completare due sostituzioni complete).

Tratteremo ;come partizioni effettive e ,proprio come segnaposto che impediscono il successivo \Babbinamento. Quindi il prossimo ...

,

... rimuoviamo quelle virgole. Questo ci dà tutte le partizioni. Ad esempio per l'input 4otteniamo:

1;1;1;1
1;1;11
1;11;1
1;111
11;1;1
11;11
111;1
1111

Non ci interessa l'ordine però:

%O`1+

Questo ordina le serie di 1s in ogni riga in modo da ottenere partizioni non ordinate.

@`.+

Infine, contiamo le corrispondenze univoche ( @) .+, ovvero quante linee / partizioni distinte abbiamo ottenuto. Ho aggiunto questa @opzione anni fa, poi me ne sono completamente dimenticata e solo recentemente l'ho riscoperta. In questo caso, salva un byte sulla prima deduplicazione con le righe D`.


3

Python 2 , 54 53 byte

f=lambda n,k=1:1+sum(f(n-j,j)for j in range(k,n/2+1))

Provalo online!

Come funziona

Ogni partizione di n può essere rappresentata come un elenco x = [x 1 , ⋯, x m ] tale che x 1 + ⋯ + x m = n . Questa rappresentazione diventa unica se richiediamo che x 1 ≤ ⋯ ≤ x m .

Definiamo una funzione ausiliaria f (n, k) che conta le partizioni con limite inferiore k , cioè le liste x tali che x 1 + ⋯ + x m = n e k ≤ x 1 ≤ ⋯ ≤ x m . Per l'input n , la sfida richiede quindi l'output di f (n, 1) .

Per numeri interi positivi n e k tale che k ≤ n , esiste almeno una partizione con limite inferiore k : la lista singleton [n] . Se n = k (in particolare, se n = 1 ), questa è l' unica partizione ammissibile. D'altra parte, se k> n , non ci sono soluzioni.

Se k <n , possiamo contare ricorsivamente le partizioni rimanenti costruendole da sinistra a destra, come segue. Per ogni j tale che k ≤ j ≤ n / 2 , possiamo costruire partizioni [x 1 , ⋯, x m ] = [j, y 1 , ⋯, y m-1 ] . Abbiamo che x 1 + ⋯ + x m = n se e solo se y 1 + ⋯ + y m-1 = n - j . Inoltre, x 1 ≤ ⋯ ≤ x m se e solo se j ≤ y 1 ≤ ⋯ ≤ y m-1 .

Pertanto, le partizioni x di n che iniziano con j possono essere calcolate come f (n - j, j) , che conta le partizioni valide y . Richiedendo che j ≤ n / 2 , assicuriamo che j ≤ n - j , quindi esiste almeno un y . Possiamo quindi contare tutte le partizioni di n sommando 1 (per [n] ) ef (n - j, j) per tutti i valori validi di j .

Il codice è un'implementazione diretta della funzione matematica f . Inoltre, rende k di default 1 , quindi f(n)calcola il valore di f (n, 1) per l'ingresso n .


Oh wow, questo è incredibile! Puoi aggiungere una spiegazione su come funziona?

Ho modificato la mia risposta. Se qualcosa non è chiaro, per favore fatemi sapere.
Dennis,

3

J , 37 35 byte

0{]1&((#.]*>:@#.~/.~&.q:@#\%#),])1:

Provalo online!

Spiegazione

0{]1&((#.]*>:@#.~/.~&.q:@#\%#),])1:  Input: n
                                 1:  Constant 1
  ]                                  Get n
   1&(                          )    Repeat n times on x = [1]
                          \            For each prefix
                         #               Length
                      q:@                Prime factors
                 /.~&                    Group equal factors
              #.~                        Compute p+p^2+...+p^k for each group
           >:@                           Increment
                    &.q:                 Product
                           %           Divide
                            #          Length
         ]                             Get x
          *                            Times
   1   #.                              Sum
                              ,        Joim
                               ]       Get x
                                       Set this as next value of x
0{                                   Select value at index 0

Sono sbalordito e sbalordito, ti dispiace pubblicare una spiegazione?
Cole

1
@cole Questo è un approccio iterativo che inizia con la soluzione per p (0) = 1 e crea il successivo usando la formula p(n) = sum(sigma(n-k) * p(k) for k = 0 to n-1) / n. Aggiungerò una spiegazione del codice in seguito quando ritengo che non possa essere abbreviato in modo significativo.
miglia,

2

JavaScript, 125 121 byte

n=>(z=(a,b)=>[...Array(a)].map(b))(++n**n,(_,a)=>z[F=z(n,_=>a%(a/=n,n)|0).sort().join`+`]=b+=eval(F)==n-1&!z[F],b=0)|b||1

Provalo online!

Attenzione: la complessità del tempo e dello spazio è esponenziale. Funziona molto lentamente per grandi numeri.


2

Python 2 , 89 byte

-9 byte di Mr.Xcoder -1 byte di notjagan

lambda n:len(p(n))
p=lambda n,I=1:{(n,)}|{y+(x,)for x in range(I,n/2+1)for y in p(n-x,x)}

Provalo online!



@ Mr.Xcoder Non so nemmeno, perché non ho usato Lambda D:
Dead Possum

Hehe, ¯\_(ツ)_/¯- A proposito, se volessi mantenere una funzione completa, non avresti bisogno della variabile, 94 byte
Mr. Xcoder

@ Mr.Xcoder Sì. Mi sento arrugginito dopo un po 'di tempo lontano da Codegolf: c
Dead Possum



0

Java 8 (229 byte)

import java.util.function.*;class A{static int j=0;static BiConsumer<Integer,Integer>f=(n,m)->{if(n==0)j++;else for(int i=Math.min(m,n);i>=1;i--)A.f.accept(n-i,i);};static Function<Integer,Integer>g=n->{f.accept(n,n);return j;};}

Ungolfed:

import java.util.function.*;

class A {
    static int j = 0;
    static BiConsumer<Integer, Integer> f = (n, m) -> {
        if (n == 0)
            j++;
        else
            for (int i = Math.min(m, n); i >= 1; i--)
                A.f.accept(n - i, i);
    };
    static Function<Integer, Integer> g = n -> {
        f.accept(n, n);
        return j;
    };
}

0

Gelatina , 3 byte

L' Œṗatomo è stato recentemente aggiunto e significa "Partizioni intere".

ŒṗL

Provalo online!

ŒṗL - Programma completo.

Œṗ - Partizioni intere.
  L - Lunghezza.
      - Uscita implicita.


0

JavaScript ES7, 69 byte

n=>(f=(i,s)=>i?[for(c of Array(1+n))f(i-1,s,s-=i)]:c+=!s)(n,n,c=0)&&c

JavaScript ES6, 71 byte

n=>(f=(i,s)=>i?[...Array(1+n)].map(_=>f(i-1,s,s-=i)):c+=!s)(n,n,c=0)&&c

Complessità temporale O (n ^ n), quindi fai attenzione (un ovvio ritardo appare sul mio computer per F(6))

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.