O desafio é listar todas as partições ordenadas (composição (combinatória)) de um número inteiro positivo n
. Estas são as listas de números de 1
para n
cuja soma é n
. Por exemplo, dada entrada n = 4
, o resultado deve ser:
4
1, 3
3, 1
2, 2
2, 1, 1
1, 2, 1
1, 1, 2
1, 1, 1, 1
O resultado pode estar em qualquer ordem, mas deve conter cada partição ordenada uma vez. Isto significa que para n = 4
, [1, 1, 2]
, [1, 2, 1]
e [2, 1, 1]
deve ser parte do resultado.
Aqui está o meu próprio código JavaScript que consegue isso:
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);
});
}
Golfe, ES6 ( 169 167 119 109 109 105 89 85 bytes ):
n=>n?[].concat(...[...Array(n)].map((x,i)=>i+1).map(b=>m(n-b).map(a=>[b,...a]))):[[]]
Respostas:
Pitão,
76 bytesSolução de 7 bytes:
Pyth possui uma partição inteira integrada
./
, portanto, 5 dos 7 bytes estão recebendo os pedidos.Experimente online!
Explicação:
Solução de 6 bytes:
Se você tiver uma lista,
./
calculará com os pedidos; tudo o que resta é fazer os números das listas novamente.Experimente online!
Explicação:
fonte
Haskell, 37 bytes
O xnor salvou dois bytes.
fonte
f n=[a:x|a<-[1..n],x<-f$n-a]
é mais curto.given positive integer n ... numbers from 1 to n
)f 0=[[]]
só acontece de ser um caso base menor do quef 1=[[1]]
:)Python, 56 bytes
Uma solução recursiva: As partições ordenadas de
n
são uma partição de algumas menoresi
com0<=i<n
, seguidas pelo restanten-i
como o último elemento. Para um caso base,n=0
possui apenas a partição vazia.fonte
Python 2, 61 bytes
Este não é o mais curto, mas eu realmente gosto do método porque é muito estranho.
Gera e avalia recursivamente
2**(n-1)
cadeias de caracteres, comopara
n=4
. Essas cadeias são avaliadas para tuplas representando todas as partições. Entre quaisquer dois 1s existe um+
, juntando-os em um único número ou um,
, dividindo seções adjacentes.fonte
import re
lambda n:map(lambda n:map(len,re.finall('10*',bin(n))),range(1<<n-1,1<<n))
JavaScript (Firefox 30-57), 63 bytes
fonte
f=n=>n<2?[[1]]:f(n-1).map(([n,...a])=>r.push([1+n,...a],[1,n,...a]),r=[])&&r
.Mathematica, 40 bytes
O built-in do Mathematica para partições inteiras não fornece todas as partições ordenadas , portanto, temos que gerar todas as permutações possíveis de cada uma delas e achatar o resultado.
fonte
CJam ,
1714 bytesExperimente online!
Explicação
Sei que disse que usar o produto cartesiano é mais longo, mas acabei encontrando uma maneira de usá-lo com mais eficiência. Eu acho que as duas abordagens são interessantes por si só, então estou colocando-as em posts separados.
Isso ainda se baseia na idéia de que podemos escolher
n
tempos entre anexar1
a à partição atual ou incrementar o último elemento da partição atual. Nesta solução, fazemos isso gerando 2 n-1 programas diferentes que correspondem a essas diferentes opções.fonte
)
". Então eu adicioneied
e testei. +1 por abuso de erro criativo.Geléia ,
76 bytes-1 byte graças a @Dennis (converta de unário
ḅ1
, em vez de soma para cada um para cadaS€€
)TryItOnline
Quão?
fonte
Pure Bash, 51
Esta é uma porta da brilhante resposta do @ xnor , usando vários níveis de expansões do bash para alcançar o resultado desejado:
Ideone.
$a
contendo1
seguidos den-1
zeros.${a//0/{+,']\ $[}1'}
substitui cada0
no$a
com cópias da cadeia{+,']\ $[}1'
. Assim, n = 4, obtemos a string1{+,']\ $[}1'{+,']\ $[}1'{+,']\ $[}1'
$[
e pós-fixado com],
para fornecer$[1{+,']\ $[}1'{+,']\ $[}1'{+,']\ $[}1]
$[1+1+1+1], $[1+1+1] 1, $[1+1] $[1+1], $[1+1] 1 1,...
O uso cuidadoso de aspas, a barra invertida e a fuga
eval
garantem que as expansões ocorram na ordem correta.fonte
Ruby, 61 bytes
destroçado
uso
fonte
x<<i
é mais curto que[i]+x
..flatten(1)
não é.flatten 1
?Braquilog , 20 bytes
Experimente online!
Explicação
Essa é uma situação em que você acha que as linguagens declarativas se sairiam bem, mas, devido à sobrecarga
+
e dificuldade em escrever um predicado de soma que propague adequadamente as restrições, elas não o fazem.fonte
L
fique entre 1 e a entrada.+
também funciona em um único número inteiro, preciso forçar a inclusão.
em uma lista e##
, como+
também funciona em uma lista de listas, preciso impor que os elementos de.
são inteiros:#$a
.CJam , 19 bytes
Experimente online!
Explicação
O CJam não possui uma combinação combinatória útil para partições inteiras. Então, faremos isso manualmente. Para encontrar todas as partições ordenadas de um número inteiro
n
, podemos olhar para uma lista den
unidades e considerar todas as formas possíveis de inserir separadores. Em seguida, somaremos os1
s em cada seção. Exemplo paran = 3
:Tentei usar um produto cartesiano para gerar todos esses separadores, mas isso acabou em 21 bytes. Em vez disso, voltei a essa antiga técnica para gerar conjuntos de potência (isso é baseado em uma resposta antiga de Dennis, mas não consigo encontrá-la agora). A idéia é a seguinte: para gerar todas as partições, podemos começar de uma lista vazia. Às
n
vezes, podemos tomar uma decisão binária: anexamos a1
(corresponde a um separador no exemplo acima) ou incrementamos o último valor da lista (corresponde a não ter um separador). Para gerar todas as partições, simplesmente executamos as duas operações em cada etapa e mantemos todas as saídas possíveis para a próxima etapa. Acontece que no CJam, a adição e o incremento do primeiro elemento são mais curtos, mas o princípio permanece o mesmo:fonte
T-SQL, 203 bytes
Golfe:
Ungolfed:
Violino
fonte
Mathematica 10.0, 44 bytes
Uma tentativa sem usar os recursos internos da partição. De cada partição ordenada de tamanho k , são geradas duas partições sucessivas de k + 1 : uma anexando 1 e a outra incrementando o primeiro valor.
Uma maneira mais engraçada, mas infelizmente mais longa, de 2 bytes de implementar a mesma idéia:
fonte
MapAt
índice para -1.05AB1E ,
1412 bytesEconomizou 2 bytes graças a Adnan
Explicação
Experimente online!
A solução correspondente é 2 bytes mais curta no 2sable .
2sable , 10 bytes
Experimente online!
fonte
—
vez deiy,
:).Haskell, 41 bytes
Não é a solução mais curta da Haskell, mas eu gosto que ela não use
[..]
intervalos. Em vez disso, calcula recursivamente as partiçõesn
como as partiçõesn-1
com um novo 1 no início ou o primeiro valor mais alto. Isso torna explícito o porquê2^(n-1)
deles.fonte
Mathematica, 53 bytes
Não supera a resposta de Martin Ender, que usa a
IntegerPartitions
função interna (e as internas são totalmente boas para mim). (Também não supera a resposta do feersum, que não vi até muito tarde.) Mas eu queria praticar uma função recursiva no golfe.Gera recursivamente todas as composições, gerando todos os números finais possíveis
j
e depois chamando a si próprio#-j
onde#
está a entrada.fonte
Array
vez deTable
e evitando oAppend
usando uma lista eApply
:±0={{}};±n_:=Join@@Array[{##,n-+##}&@@@±#&,n,0]
@@
faz?f@@g[a,b]
avalia comof[a,b]
. Aqui estamos usando o fato de que uma lista como{ { {1,1,1}, {2,1} } , { {1,2} }, { {3} } }
invisivelmente tem cabeçaList
; entãoJoin@@{ { {1,1,1}, {2,1} } , { {1,2} }, { {3} } }
avaliada comoJoin@@List[ { {1,1,1}, {2,1} } , { {1,2} }, { {3} } ]
avalia paraJoin[ { {1,1,1}, {2,1} } , { {1,2} }, { {3} } ]
avaliada como{ {1,1,1}, {2,1}, {1,2}, {3} }
.Retina , 32 bytes
A contagem de bytes assume a codificação ISO 8859-1.
Experimente online!
Explicação
Isso funciona de maneira semelhante à minha resposta CJam . Passamos por uma lista
N
e, em cada posição, tomamos os dois ramos da decisão binária a) incrementamos o último valor ou b) iniciamos um novo valor em 1.Estágio 1
Converta a entrada para unário.
Etapa 2
O
+
instrui o Retina a executar esse estágio em um loop até que a saída pare de mudar. Ele%
diz para dividir a entrada em linhas antes de aplicar o palco e juntá-las novamente depois. Ao colocar o%
depois do+
, o Retina se divide e volta a se juntar a cada iteração. Uma iteração do estágio toma uma dessas decisões que mencionei e, assim, bifurca o conjunto atual de partições.Como ele realmente funciona é que ele corresponde a
1
(mas apenas o primeiro, conforme indicado1
na frente do backtick), e o substitui por!
(o qual usaremos como o dígito unário de nossa saída), seguido pelos1
s restantes nesta linha (isso incrementa o último valor). Em outra linha (¶
), imprime o prefixo da linha atual, seguida por,!
, que insere um separador e inicia o próximo valor em1
.Etapa 3
Isso converte as execuções de
!
números inteiros decimais, substituindo-as pelo comprimento.Etapa 4
E, finalmente, percebemos que geramos o dobro de linhas que queríamos, e metade delas começa com uma
,
(aquelas em que tomamos a decisão de dividir inicialmente, mesmo que ainda não houvesse nada para dividir). Portanto, descartamos todas as linhas que começam com a,
.fonte
Perl, 44 bytes
Inclui +3 para
-n
(o código usa$'
e,$0
portanto, não pode ser executado como um-e
linha de comando)Atribua um número à partição no STDIN:
partitions.pl
Se você não se importa com espaços extras no final de uma linha e uma nova linha extra, essa solução de 42 bytes também funciona (execute como
perl -M5.010 partitions.pl
):fonte
Julia, 113 bytes
Solução não recursiva
Explicado:
[vcat([1 for _=i+1:N],sum([1 for _=N-i:N-1])) for i=1:N]
crie um conjunto de listas somadas a N, cujas permutações se parecerão com a solução (por exemplo, para N = 4: [[1,1,1,1], [1,1,2], [1,3], [4 ]])map(x->[permutations(x)...],)
Calcular todas as permutaçõesreduce(vcat,)
combiná-los em uma lista de listasunique()
filtrar duplicatasfonte
N
como entrada. Você pode criar uma função lambda acrescentandoN->
um custo de 3 bytes.f(N)=
perdi-me ao copiar, eu já tive isso ao contar bytesMATL , 15 bytes
Experimente online!
Explicação
Dada a entrada
n
, isso calcula a potência cartesiana com expoentes crescentesk
de1
paran
; e para cada expoentek
seleciona as tuplas que possuem uma soma igual à entrada.fonte
Lua
214203182 bytesVersão não resolvida.
Encontrou um espaço em branco disperso e removeu uma variável desnecessária para 11 bytes seguros. Acontece que table.insert () é byte ineficiente
fonte
PHP, 125 bytes
-4 bytes para em
print_r($r);
vez deecho json_encode($r);
para a saídauma solução recursiva com 250 bytes
fonte
Prolog, 81 bytes + 6 bytes para chamar
Experimente online!
Ligue com
[4]*L.
, repita com;
até que todas as soluções tenham sido apresentadas.Como alternativa, se pressionar repetidamente
;
não estiver ok (ou deve ser adicionado à contagem de bytes), a chamadabagof(L,[4]*L,M).
adicionará 17 bytes à chamada.fonte
J ,
3026 bytesFunciona dividindo a lista de n unário usando os valores binários de 2 n .
Experimente online!
Explicação
fonte
Na realidade,
1716 bytesEsta resposta é parcialmente baseada na resposta MATL de Luis Mendo . Sugestões de golfe são bem-vindas. Experimente online!
Ungolfing
fonte
Na verdade,
171615 bytesEsta é uma bifurcação interessante da resposta CJam de Martin Ender (aquela com o produto cartesiano), com uma diferença na implementação que achei interessante. Quando uma das cadeias de caracteres de Martin começa com um incremento, os erros impedem que essa cadeia seja avaliada. Na verdade, o erro é suprimido e a sequência é avaliada de qualquer maneira. Isso acaba dando as composições de todos
k
na faixa[1..n]
.Em vez de tentar remover as composições extras, tomei o
n-1
poder cartesiano de"1u"
anexar um"1"
a ao início de cada corda. Esse truque fornece apenas as composições den
. Infelizmente, é mais longo que a resposta de Martin.Sugestões de golfe são bem-vindas. Experimente online!
Ungolfing
fonte