Elencare tutte le partizioni ordinate di n


23

La sfida è elencare tutte le partizioni ordinate (composizione (combinatoria)) di un dato intero positivo n. Questi sono gli elenchi dei numeri da 1a ncui somma è n. Ad esempio, dato l'input n = 4, il risultato dovrebbe essere:

4
1, 3
3, 1
2, 2
2, 1, 1
1, 2, 1
1, 1, 2
1, 1, 1, 1

Il risultato può essere in qualsiasi ordine, ma deve contenere una volta ogni partizione ordinata. Questo significa che per n = 4, [1, 1, 2], [1, 2, 1]e [2, 1, 1]devono essere tutti parte del risultato.

Ecco il mio codice JavaScript che raggiunge questo obiettivo:

function range(n) {
    for (var range = [], i = 0; i < n; range.push(++i));
    return range;
}

function composition(n) {
    return n < 1 ? [[]] : range(n).map(function(i) {
        return composition(n - i).map(function(j) {
            return [i].concat(j);
        });
    }).reduce(function(a, b) {
        return a.concat(b);
    });
}

Golfato, ES6 ( 169 167 119 109 105 89 85 byte ):

n=>n?[].concat(...[...Array(n)].map((x,i)=>i+1).map(b=>m(n-b).map(a=>[b,...a]))):[[]]

3
Benvenuti nel sito! Devi specificare un criterio vincente. Code-golf forse? Inoltre, deve essere in quell'ordine specifico? In tal caso, come viene definito l'ordine in generale? Penso che l'ordine lessicografico sarebbe più significativo; o meglio ancora, consenti qualsiasi ordine. Potresti voler usare la sandbox per le sfide future prima di pubblicarle qui
Luis Mendo,

3
@Fatalize Here [2 1 1] è diverso da [1 2 1], a differenza di lì. Sospetto che gli approcci possano essere significativamente diversi
Luis Mendo,

3
Per coloro che hanno chiuso come duplicati: sei sicuro che la differenza indicata nei commenti non sia rilevante? Non voterò per riaprire, poiché penso che anche il martello avrebbe funzionato in quella direzione
Luis Mendo,

3
Suggerirei di non accettare ancora una risposta (anche se puoi cambiarla in qualsiasi momento) perché vedere la domanda accettata in prima pagina potrebbe far pensare alle persone che è finita e non partecipare.
xnor

5
Il termine abituale per queste partizioni ordinate è " composizioni ".
Greg Martin,

Risposte:


7

Pyth, 7 6 byte

Soluzione a 7 byte:

Pyth ha una partizione intera incorporata ./, quindi 5 dei 7 byte sta ottenendo gli ordini.

{s.pM./

Provalo online!

Spiegazione:

     ./  Integer partition (sorted by default)
  .pM    get all the orderings of each of the partitions as a nested list of lists of orderings
 s       Flatten by one layer
{        Remove duplicates

Soluzione a 6 byte:

Se hai un elenco, ./calcolerà con gli ordini; non resta che rendere nuovamente gli elenchi.

lMM./m

Provalo online!

Spiegazione:

     m  Get lists by gathering a list of [0, 1,...input] (I could use U as well)

   ./   Partition with orderings
 MM     Map an operation across each of the orderings lists of elements
l       where that operation is the length of the sublists

Stupefacente. Questa è la più piccola che abbia mai visto finora!
driima,

11

Haskell, 37 byte

f 0=[[]]
f n=[a:x|a<-[1..n],x<-f$n-a]

xnor ha salvato due byte.


1
Sembra che il più semplice f n=[a:x|a<-[1..n],x<-f$n-a]è più breve.
xnor

non è necessario il controllo zero ( given positive integer n ... numbers from 1 to n)
nyro_0

2
f 0=[[]]sembra essere un caso base più breve di f 1=[[1]]:)
Lynn,

@xyLe_ Ha usato un caso base ricorsivo.
xnor

ah certo, hai ragione, mio ​​cattivo
nyro_0

10

Python, 56 byte

f=lambda n:[x+[n-i]for i in range(n)for x in f(i)]or[[]]

Una soluzione ricorsiva: Le partizioni ordinati di nsono una partizione di alcune piccole icon 0<=i<n, seguito dal resto n-icome ultimo elemento. Per un caso base, n=0ha solo la partizione vuota.


Semplice, piccolo eppure sorprendentemente leggibile. Questo è ciò che amo di Python.
driima,

10

Python 2, 61 byte

f=lambda n,s='1,':1/n*[eval(s)]or f(n-1,'1+'+s)+f(n-1,'1,'+s)

Questo non è il più breve, ma mi piace molto il metodo perché è così strano.

Genera ricorsivamente e valuta 2**(n-1)stringhe, come

1+1+1+1,
1,1+1+1,
1+1,1+1,
1,1,1+1,
1+1+1,1,
1,1+1,1,
1+1,1,1,
1,1,1,1,

per n=4. Queste stringhe valutano le tuple che rappresentano tutte le partizioni. Tra due qualsiasi 1 c'è o +, unendoli in un unico numero o a ,, dividendo sezioni adiacenti.


La migliore versione non ricorsiva che potessi fare fuimport re lambda n:map(lambda n:map(len,re.finall('10*',bin(n))),range(1<<n-1,1<<n))
Neil,

1
Una spiegazione con il codice lo renderebbe davvero bello.
noman pouigt,

8

JavaScript (Firefox 30-57), 63 byte

f=n=>n?[for(i of Array(n).keys())for(a of f(i))[n-i,...a]]:[[]]

12
Firefox 30+ sembra un browser speciale per gli utenti più maturi di Internet.
Martin Ender,

Probabilmente non è più breve di questo ...
ETHproductions

In qualche modo questo può essere non golfato per JavaScript in altri browser?
driima,

@Eternity posso port @ altra risposta di xnor per voi: f=n=>n<2?[[1]]:f(n-1).map(([n,...a])=>r.push([1+n,...a],[1,n,...a]),r=[])&&r.
Neil,

6

Mathematica, 40 byte

Join@@Permutations/@IntegerPartitions@#&

Il built-in di Mathematica per le partizioni intere non fornisce tutte le partizioni ordinate , quindi dobbiamo generare tutte le possibili permutazioni di ciascuna di esse, quindi appiattire il risultato.


6

CJam , 17 14 byte

ri"X)"m*{~]p}/

Provalo online!

Spiegazione

So di aver detto che l'uso del prodotto cartesiano è più lungo, ma alla fine ho trovato un modo per usarlo in modo più efficiente. Penso che entrambi gli approcci siano interessanti di per sé, quindi li sto mettendo in post separati.

Questo si basa ancora sull'idea che, possiamo scegliere i ntempi tra l'aggiunta di 1a alla partizione corrente o per incrementare l'ultimo elemento della partizione corrente. In questa soluzione, lo facciamo generando 2 n-1 programmi diversi che corrispondono a queste diverse scelte.

ri      e# Read input and convert to integer N.
        e# Decrement.
"X)"m*  e# Get all strings of length N which consist of 'X' and ')'. If
        e# we treat these strings as CJam code then 'X' pushes a 1 and ')'
        e# increments the top of the stack.
        e# Note that some of these strings will begin with an increment that
        e# doesn't have anything on the stack to work with. This will result in
        e# an error and terminate the program. Luckily, the programs are ordered
        e# such that all programs starting with 'X' are first in the list, so
        e# we get to print all the 2^(N-1) permutations before erroring out.
{       e# For each of these programs (well for the first half of them)...
  ~     e#   Evaluate the string as CJam code. This leaves the partition as
        e#   individual integers on the stack.
  ]p    e#   Wrap the stack in a list and pretty-print it.
}/

Ho guardato questo e ho pensato " Non può essere giusto, darebbe un errore quando valuta la prima stringa che inizia con) ". Quindi ho aggiunto ede testato. +1 per abuso creativo di errore.
Peter Taylor,

6

Gelatina , 7 6 byte

-1 byte grazie a @Dennis (conversione da unario ḅ1, anziché somma per ciascuno per ciascuno S€€)

1ẋŒṖḅ1

TryItOnline

Come?

1ẋŒṖḅ1 - Main link: n          e.g. 4
1ẋ     - repeat 1 n times          [1,1,1,1]
  ŒṖ   - partitions of a list     [[[1],[1],[1],[1]], [[1],[1],[1,1]], [[1],[1,1],[1]],
                                   [[1],[1,1,1]],     [[1,1],[1],[1]], [[1,1],[1,1]],
                                   [[1,1,1],[1]],     [[1,1,1,1]]]
    ḅ1 - from base 1 (vectorises)  [[1,1,1,1],        [1,1,2],         [1,2,1],
                                   [1,3],             [2,1,1],         [2,2],
                                   [3,1],             [4]]

5

Pure Bash, 51

Questa è una porta della brillante risposta di @ xnor , che utilizza più livelli di espansioni bash per ottenere il risultato desiderato:

a=$[10**($1-1)]
eval echo \$[${a//0/{+,']\ $[}1'}],

Ideone.

  • La prima riga è semplicemente un'espansione aritmetica per creare una variabile $acontenente 1seguita dan-1 zeri.
  • La prima espansione ${a//0/{+,']\ $[}1'}sostituisce ciascuna 0in $acopie della stringa {+,']\ $[}1'. Quindi n = 4 otteniamo la stringa1{+,']\ $[}1'{+,']\ $[}1'{+,']\ $[}1'
  • Questo è preceduto da $[e postfisso ],da dare$[1{+,']\ $[}1'{+,']\ $[}1'{+,']\ $[}1]
  • Questa è un'espansione che si espande a $[1+1+1+1], $[1+1+1] 1, $[1+1] $[1+1], $[1+1] 1 1,...
  • Questo viene infine aritmeticamente espanso per dare il risultato richiesto.

L'uso attento delle virgolette, la fuga di barre rovesciate e evalassicura che le espansioni avvengano nell'ordine corretto.


4

Rubino, 61 byte

f=->n{n<1?[[]]:(1..n).map{|i|f[n-i].map{|x|x<<i}}.flatten(1)}

ungolfed

f=->n{
  n < 1 ?
    [[]]
  :
    (1..n).map { |i|
      f[n-i].map { |x|
        x << i
      }
    }.flatten(1)
}

uso

p f[4]
# => [[1, 1, 1, 1], [1, 1, 2], [1, 2, 1], [1, 3], [2, 1, 1], [2, 2], [3, 1], [4]]

2
Hiya! Potresti aggiungere un po 'di spiegazione per le persone (come me) che non hanno familiarità con Ruby?
AdmBorkBork,

x<<iè più corto di [i]+x.
m-chrzan,

@TimmyD Ho aggiunto un codice non salvato e l'utilizzo.
cia_rana,

@ m-chrzan Grazie per il tuo consiglio! L'ho modificato.
cia_rana,

Qualche motivo .flatten(1)non lo è .flatten 1?
Cyoce,

3

Brachylog , 20 byte

~lL#++?,L:=f:{:0x}ad

Provalo online!

Spiegazione

Questa è una situazione in cui penseresti che le lingue dichiarative farebbero bene, ma a causa del sovraccarico +e della difficoltà di scrivere un predicato sommatore che propaga correttamente i vincoli, non lo fanno.

~lL                     L is a list of length Input
  L#+                   L is a list of non-negative integers
  L  +?,                The sum of the elements of L results in the Input
        L:=f            Find all values for the elements of L which satisfy those constraints
            :{:0x}a     Remove all 0s from each sublist of the result of Findall
                   d    Remove all duplicate sublists

Penso che questo si propagherà molto più velocemente se ti concentri su numeri interi positivi e lasci che la lunghezza Lsia compresa tra 1 e input.
mat

@mat Questo è quello che ho fatto inizialmente, ma è più lungo . Dato che +funziona anche su un singolo numero intero, devo forzare .a essere un elenco con ##, e poiché +funziona anche su un elenco di elenchi, devo imporre che gli elementi di .siano numeri interi :#$a.
Fatalizza il

Quindi il problema chiave è la defaultyness delle strutture di dati: quando una variabile appare come argomento di operazioni che vettorializzano, non si può dire se la variabile sta per un singolo intero o un elenco (possibilmente nidificato). Questo è un problema difficile e potrebbe esserci un modo elegante per risolverlo, a partire dalla versione originale e cercando costrutti linguistici adatti che potrebbero semplificarlo. Bel lavoro in ogni caso!
mat

3

CJam , 19 byte

Lari{_1af.+1@f+|}*p

Provalo online!

Spiegazione

CJam non ha un'utile combinatoria integrata per le partizioni intere. Quindi lo faremo manualmente. Per trovare tutte le partizioni ordinate di un numero intero n, possiamo guardare un elenco di nquelli e considerare ogni modo possibile per inserire separatori. Quindi sommeremo le 1s in ogni sezione. Esempio per n = 3:

1 1 1 => 3
1 1|1 => 2|1
1|1 1 => 1|2
1|1|1 => 1|1|1

Ho provato a utilizzare un prodotto cartesiano per generare tutti questi separatori, ma è finito a 21 byte. Invece sono tornato a questa vecchia tecnica per la generazione di gruppi elettrogeni (questo si basa su una vecchia risposta di Dennis ma non riesco a trovarla in questo momento). L'idea è questa: per generare tutte le partizioni possiamo iniziare da un elenco vuoto. Quindi a nvolte possiamo prendere una decisione binaria: o aggiungiamo a 1(corrisponde a un separatore nell'esempio sopra) o incrementiamo l'ultimo valore dell'elenco (corrisponde a non avere un separatore). Per generare tutte le partizioni, eseguiamo semplicemente entrambe le operazioni in ciascun passaggio e manteniamo tutti gli output possibili per il passaggio successivo. Si scopre che in CJam, anteporre e incrementare il primo elemento è più breve, ma il principio rimane lo stesso:

La       e# Push [[]] onto the stack. The outer list will be the list of
         e# all possible partitions at the current iteration, and we initialise
         e# it to one empty partition (basically all partitions of 0).
ri       e# Read input and convert to integer N.
{        e# Repeat this N times...
  _      e#   Duplicate the list of partitions of i-1.
  1af.+  e#   Increment the first element in each of these. This is done
         e#   by performing a pairwise addition between the partition and [1].
         e#   There is the catch that in the first iteration this will turn
         e#   the empty array into [1], so it's equivalent to the next step.
  1@f+   e#   Pull up the other copy of the list of partitions of i-1 and
         e#   prepend a 1 to each of them.
  |      e#   Set union. This gets rid of the duplicate result from the first
         e#   iteration (in all other iterations this is equivalent to concatenating
         e#   the two lists).
         e#   Voilà, a list of all partitions of i.
}*
p        e# Pretty-print the result.

3

T-SQL, 203 byte

golfed:

USE master
DECLARE @ INT=12

;WITH z as( SELECT top(@)cast(number+1as varchar(max))a FROM spt_values WHERE'P'=type),c as(SELECT a*1a,a b FROM z UNION ALL SELECT c.a+z.a,b+','+z.a FROM c,z WHERE c.a+z.a*1<=@)SELECT b FROM c WHERE a=@

Ungolfed:

USE master --needed to make sure it is executed from the correct database
DECLARE @ INT=12

;WITH z as
(
  SELECT top(@)cast(number+1as varchar(max))a
  FROM spt_values
  WHERE'P'=type
),c as
(
  SELECT a*1a,a b
  FROM z
  UNION ALL
  SELECT c.a+z.a,b+','+z.a
  FROM c,z
  WHERE c.a+z.a*1<=@
)
SELECT b 
FROM c
WHERE a=@

Violino


3

Mathematica 10.0, 44 byte

Un tentativo senza utilizzare i builtin relativi alla partizione. Da ciascuna partizione ordinata di dimensione k , vengono generate due partizioni successive di k + 1 : una anteponendo 1 e l'altra aumentando il primo valore.

Nest[##&[{1,##},{#+1,##2}]&@@@#&,{{1}},#-1]&

Un modo più divertente, ma purtroppo di 2 byte più lungo per implementare la stessa idea:

#@{1}&/@Tuples[Prepend[1]@*MapAt[#+1&,1],#-1]&

@alephalpha No, non sarebbe d'aiuto, dato che dovrei cambiare l' MapAtindice in -1.
feersum,

3

05AB1E , 14 12 byte

Salvato 2 byte grazie ad Adnan

>G¹LNãvyO¹Q—

Spiegazione

>G              # for N in range(1..input)
  ¹L            # range(1, input)
    Nã          # cartesian product with N (all combinations of length N)
      v         # for each resulting list
       yO¹Q—    # if it's sum equals the input print it

Provalo online!

La soluzione corrispondente è 2 byte più corta in 2sable .

2 file , 10 byte

>GLNãvyOQ—

Provalo online!


Puoi usare invece di iy,:).
Adnan,

@Adnan: grazie! Dimenticato quello.
Emigna,

3

Haskell, 41 byte

f 1=[[1]]
f n=do a:b<-f$n-1;[1:a:b,a+1:b]

Non è la soluzione Haskell più corta, ma mi piace che non usi i [..]range. Al contrario, calcola in modo ricorsivo le partizioni ncome partizioni di n-1con un nuovo 1 all'inizio o il primo valore uno superiore. Questo rende esplicito il motivo per cui ce 2^(n-1)ne sono.


3

Mathematica, 53 byte

Non batte la risposta di Martin Ender, che utilizza la IntegerPartitionsfunzione incorporata (e gli incorporati sono totalmente a mio agio). (Né batte la risposta di Feersum, che non ho visto fino a tardi.) Ma volevo esercitarmi in una funzione ricorsiva da golf.

If[#<1,{{}},Join@@Table[#~Append~j&/@#0[#-j],{j,#}]]&

Genera in modo ricorsivo tutte le composizioni, generando tutti i possibili numeri finali je quindi richiamandosi su #-jdove si #trova l'input.


È possibile salvare alcuni byte definendo un operatore utilizzando Arrayanziché Tableed evitando Appendutilizzando un elenco e Apply:±0={{}};±n_:=Join@@Array[{##,n-+##}&@@@±#&,n,0]
Martin Ender

Cosa fa @@?
Cyoce,

Sostituisce la "testa" di un'espressione. Ad esempio, f@@g[a,b]valuta f[a,b]. Qui stiamo usando il fatto che un elenco come { { {1,1,1}, {2,1} } , { {1,2} }, { {3} } }invisibilmente ha la testa List; quindi Join@@{ { {1,1,1}, {2,1} } , { {1,2} }, { {3} } }valuta per Join@@List[ { {1,1,1}, {2,1} } , { {1,2} }, { {3} } ]valutare per Join[ { {1,1,1}, {2,1} } , { {1,2} }, { {3} } ]valutare per { {1,1,1}, {2,1}, {1,2}, {3} }.
Greg Martin,

3

Retina , 32 byte

Il conteggio dei byte presuppone la codifica ISO 8859-1.

.+
$*
+%1`1
!$'¶$`,!
!+
$.&
A`^,

Provalo online!

Spiegazione

Funziona in modo simile alla mia risposta CJam . Esaminiamo Nquelli di una lista e in ciascuna posizione prendiamo entrambi i rami della decisione binaria a) incrementiamo l'ultimo valore o b) iniziamo un nuovo valore a 1.

Fase 1

.+
$*

Converti l'input in unario.

Fase 2

+%1`1
!$'¶$`,!

Il +dice a Retina di eseguire questo stadio in un ciclo fino a quando l'uscita smette di cambiare. Gli %dice di dividere l'input in righe prima di applicare lo stage e di ricollegarli in seguito. Mettendo il %dopo il +, Retina si divide e si ricongiunge dopo ogni iterazione. Un'iterazione del palco prende una di quelle decisioni che ho citato e quindi biforca l'attuale serie di partizioni.

Il modo in cui funziona è che corrisponde a 1(ma solo al primo come indicato dalla parte 1anteriore del backtick) e lo sostituisce con !(che useremo come cifra unaria del nostro output), seguito dal rimanente 1s su questa riga (incrementa l'ultimo valore). Quindi su un'altra riga ( ) stampa il prefisso della riga corrente, seguito da ,!, che inserisce un separatore e quindi avvia il valore successivo in 1.

Fase 3

!+
$.&

Questo converte le esecuzioni !in numeri decimali sostituendoli con la loro lunghezza.

Fase 4

A`^,

E infine, notiamo che abbiamo generato il doppio delle linee che volevamo, e la metà di esse inizia con una ,(quelle in cui inizialmente abbiamo preso la decisione di dividere, anche se non c'era ancora nulla da dividere). Pertanto, scartiamo tutte le righe che iniziano con a ,.


3

Perl, 44 byte

Include +3 per -n(il codice utilizza $'e $0quindi non può essere eseguito come -eriga di comando)

Dai il numero alla partizione su STDIN:

partitions.pl <<< 4

partitions.pl

#!/usr/bin/perl -n
$_=$&-$_.",$_$'",do$0for/\d+/..$&-1;print

Se non ti dispiace spazi extra alla fine di una riga e una nuova riga in più funziona anche questa soluzione da 42 byte (esegui come perl -M5.010 partitions.pl):

#!/usr/bin/perl -n
$_=$`-$_." $_ $'",do$0for/\s/..$_-1;say

3

Julia, 113 Bytes

f(N)=unique(reduce(vcat,(map(x->[permutations(x)...],[vcat([1 for _=i+1:N],sum([1 for _=N-i:N-1])) for i=1:N]))))

Non-recursive solution

Explained:

  1. [vcat([1 for _=i+1:N],sum([1 for _=N-i:N-1])) for i=1:N] build a set of lists that sum to N, whose permutations will resemble the solution (e.g. for N=4: [[1,1,1,1],[1,1,2],[1,3],[4]])
  2. map(x->[permutations(x)...],) Calculate all permutations
  3. reduce(vcat,) combine them into a list of lists
  4. unique() filter duplicates

We require submissions to be full programs or functions, so in this case you'll have to take N as input. You can make a lambda function by prepending N-> at the cost of 3 bytes.
Alex A.

@AlexA. ah, sorry the f(N)= got lost at copying, I've had it in when counting bytes
nyro_0

2

MATL, 15 bytes

:"G:@Z^t!XsG=Y)

Try it online!

Explanation

Given input n, this computes the Cartesian power with increasing exponents k from 1 to n; and for each exponent k selects the tuples that have a sum equal to the input.

:       % Take input n implicitly and push range [1 2 ... n]
"       % For each k in that range
  G:    %   Push [1 2 ... n] again
  @     %   Push k
  Z^    %   Cartesian power. Gives 2D array, say A, with each k-tuple in a row.
  t     %   Duplicate
  !     %   Transpose
  Xs    %   Sum of each column. Gives a row vector
  G=    %   True for entries that equal the input
  Y)    %   Use as logical vector into the rows of array A
        % End implicitly
        % Display stack implicitly

1

Lua 214 203 182 bytes

function g(m, l, n,c)for i=1,m do if i+n < m then l[#l+1]=i;g(m,l,n+i,c+1)elseif i+n == m then l[#l+1]=i;print(unpack(l))end end for k=c,#l do l[k]=nil end end g(io.read()*1,{},0,0)

Ungolved version.

function g(m, l, n,c)
    for i=1,m do 
        if i+n < m then 
            l[#l+1]=i
            g(m,l,n+i,c+1)
        elseif i+n == m then 
            l[#l+1]=i
            print(unpack(l))
        end 
    end 
    for k=c,#l do 
        l[k]=nil 
    end 
end 
g(io.read()*1,{},0,0)

Found a stray whitespace and removed an unnecessary variable to safe 11 bytes. as it turns out, table.insert() is byte inefficient


1

PHP, 125 Bytes

for($i=$n=$argv[1];$i<=str_repeat(1,$n);$i++)if(array_sum($a=str_split($i))==$n&!strpos($i,"0"))$r[]=$a;echo json_encode($r);

-4 Bytes for print_r($r); instead of echo json_encode($r); for the output

a recursive solution with 250 Bytes

function f($n){global$a;foreach($a as$x)foreach(range(1,$n)as$y)$a[]=array_merge((array)$x,[$y]);if(--$n)f($n);}$a=range(1,$w=$argv[1]);f($w-1);foreach($a as$z)if(array_sum((array)$z)==$w)$c[join("-",(array)$z)]=$z;echo json_encode(array_values($c));

1

Prolog, 81 bytes + 6 bytes to call

L*L.
[H|T]*L:-H>1,M is H-1,[M,1|T]*L.
[H,K|T]*L:-H>1,M is H-1,N is K+1,[M,N|T]*L.

Try it online!
Call with [4]*L., repeat with ; until all solutions have been presented.

Alternatively, if repeatedly pressing ; is not okay (or should be added to the byte count), call with bagof(L,[4]*L,M). which adds 17 bytes for the call.


1

J, 30 26 bytes

#&1<@(+/;.1)~2#:@(+i.)@^<:

Works by splitting the list of unary n by using the binary values of 2n.

Try it online!

Explanation

#&1<@(+/;.1)~2#:@(+i.)@^<:  Input: n
                        <:  Decrement n
             2         ^    Compute 2^(n-1)
                 (   )@     Operate on that
                   i.         Make the range [0, 1, ..., 2^(n-1)-1]
                  +           Add 2^(n-1) to each in that range
              #:@           Convert each in that range to binary
#&1                         Make n copies of 1 (n in unary)
     (     )~               Operate over each row on RHS and unary n on LHS
        ;.1                   Chop unary n starting at each 1
      +/                        Reduce by addition on each chop
   <@                           Box the sums of each chop

0

Actually, 17 16 bytes

This answer is partially based on Luis Mendo's MATL answer. Golfing suggestions welcome. Try it online!

;╗R`╜R∙i`M`Σ╜=`░

Ungolfing

         Implicit input n.
;╗       Duplicate n and save a copy of n to register 0.
R        Take the range of [1..n].
`...`M   Map the following function over the range. Variable k.
  ╛R       Push n from register 0 and take the range [1..n] again.
  ∙        Take the k-th Cartesian power of the range.
  i        Flatten that product.
`...`░   Push values of the previous map where the following function returns a truthy value.
          Variable L.
  Σ        Push sum(L).
  ╜        Push n from register 0.
  =        Check if sum(L) == n.
         Implicit return.

0

Actually, 17 16 15 bytes

This is an interesting fork of Martin Ender's CJam answer (the one with the Cartesian product), with a difference in implementation that I thought was interesting. When one of Martin's strings start with an increment, the errors prevent that string from being evaluated. In Actually, the error is suppressed and the string is evaluated anyway. This ends up giving the compositions of every k in the range [1..n].

Rather than try to remove the extra compositions, I took the n-1th Cartesian power of "1u" appended a "1" to the beginning of each string. This trick gives only the compositions of n. It is, unfortunately, longer than Martin's answer.

Golfing suggestions welcome. Try it online!

D"1u"∙`1@Σ£ƒk`M

Ungolfing

         Implicit input n.
D        Decrement n.
"1u"∙    Take the (n-1)th Cartesian power of the string "1u".
          In Actually, 1 pushes 1 to the stack and u is increment.
`...`M   Map the following function over the Cartesian power. Variable s.
  1@       Push a 1 to be used later.
  Σ        Summing a list of chars joins the chars into one string.
  £ƒ       Turn s into a function and call it immediately on the 1 in the stack.
  k        Take the whole stack and wrap in a list. This is a composition of n.
         Implicit return.
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.