Dado um número positivo n , imprima todas as partições multiplicativas distintas de n em qualquer formato conveniente.
Uma partição multiplicativa de n é um conjunto de números inteiros, todos maiores que um, de modo que seu produto seja n . Por exemplo, 20 possui as seguintes partições multiplicativas distintas:
2 * 2 * 5
2 * 10
4 * 5
20
A ordem não importa, assim 2 * 2 * 5
como a mesma partição que 2 * 5 * 2
.
Exemplos:
1 -> {}
2 -> {2}
4 -> {2, 2}, {4}
20 -> {2, 2, 5}, {2, 10}, {4, 5}, {20}
84 -> {2, 2, 3, 7}, {2, 2, 21}, {2, 14, 3}, {2, 6, 7}, {2, 42}, {4, 3, 7}, {28, 3}, {4, 21}, {6, 14}, {12, 7}, {84}
Respostas:
Braquilog , 16 bytes
Esta é uma função (não um programa completo) que recebe um número positivo como entrada e gera todas as partições multiplicativas. (Eu também evitei usar quaisquer fatores de fatoração primários embutidos nesta solução, principalmente porque não tinha certeza de que eles ajudariam; eu poderia tentar uma solução mais pesada demais em algum momento.)
Experimente online! (Foi adicionado um código extra à função aqui para transformá-lo em um programa completo; se você fornecer a função mostrada acima diretamente ao TIO, ela executará a função, mas não imprimirá sua saída em nenhum lugar, o que é meio inútil como demonstração .)
Este programa realmente me decepciona, porque grande parte dele está contornando erros no intérprete Brachylog e deficiências em suas especificações, em vez de realmente resolver o problema; mas o intérprete é o que é. (Mesmo com um programa como esse, o intérprete usa muito mais memória do que logicamente deveria e trava devido à exaustão da memória, mas, felizmente, em pequenos problemas, consegue produzir primeiro a saída desejada.) Em uma hipotética "versão perfeita do Brachylog" você poderia escrever
~*.o.:{>1}a,
, o que seria 4 bytes mais curto, mas eu precisava adicionar restrições extras para ajudar um pouco o intérprete. (Eu realmente não gosto muito do Brachylog e preferiria o Prolog, mas ele precisava de dicas semelhantes para fazer o programa funcionar e eles demoram muito mais para escrever. Então é o Brachylog.)Explicação:
Como sempre, um programa Brachylog é um conjunto de restrições; por padrão, a primeira restrição restringe a entrada contra um desconhecido (que chamarei de A ), a segunda restrição restringe A contra um segundo B desconhecido , e assim por diante até chegarmos à saída. Alguns caracteres, como
{}
, podem alterar esse fluxo geral, portanto, uso um conjunto diferente de letras (por exemplo, X / Y ) para representar incógnitas em predicados aninhados.Ainda não está claro como o programa funciona, então vamos tentar simplificar um pouco as restrições. C , D , G , H e I são todos iguais (e iguais à saída). E e F também são os mesmos (e iguais à entrada). Portanto, nossas restrições se resumem a isso:
:{1<}a
precisa do argumento esquerdo para ter um comprimento restrito ou o intérprete entra em um loop infinito).Aliás, não especifiquei explicitamente que todos os elementos da saída são números inteiros, algo que pode parecer necessário; no entanto, o solucionador de restrições do Brachylog não pode lidar com não-números inteiros; portanto, produz convenientemente apenas as soluções que envolvem números inteiros.
Claramente, "o comprimento da saída é menor que a entrada" será verdadeiro sempre que a saída for uma partição multiplicativa da entrada (porque 2 x > x para todo x não negativo , ou seja, 2 x positivo ). Portanto, podemos desconsiderar essa restrição; existe apenas para fornecer ao intérprete Brachylog uma estratégia de trabalho para avaliar o programa. As outras restrições (que a saída é classificada, que seu produto é a entrada e que todos os seus elementos são maiores que 1) são a definição de uma partição multiplicativa e, portanto, essa função é basicamente apenas uma implementação direta da questão.
fonte
Braquilog 1, 14 bytes
Experimente online!
Braquilog 2,
1110 bytes, desafio de pós-datas de idiomasExperimente online!
Maltysen respondeu a essa pergunta em 17 bytes de Pyth, então criei uma solução Brachylog de 16 bytes que funcionava traduzindo a especificação da pergunta para Brachylog. Enquanto eu fazia isso, Dennis escreveu uma solução Jelly de 15 bytes. Então eu tive que descer para 14 bytes. Essa é uma função que aceita a entrada como argumento e retorna uma lista de todas as partições (em vez de um gerador, como na minha outra solução).
Algum tempo depois de escrever essa resposta, Dennis e eu conseguimos reduzir a solução Jelly de maneira cooperativa para 11 bytes. Acontece que há uma nova versão do Brachylog, com uma sintaxe de terser; ele é pós-datado, portanto não conta, mas pode gerenciar o total de 11 bytes muito logo que for lançado; revisões posteriores do idioma (inspiradas em outros desafios) podem chegar a 10, como pode ser visto aqui. Os dois programas são idênticos, com a única diferença sendo a sintaxe.
Ao contrário da minha outra solução, que não utilizava muito as "primitivas do golfe", mas afirmava o problema diretamente, ela ignora praticamente todo o poder das restrições de Brachylog e faz sua melhor impressão de geléia, escrevendo uma cadeia de restrições para a qual o argumento da esquerda já é conhecido (e, portanto, as restrições simplesmente agem como mônadas de geléia em vez de restrições completas). Portanto, ele usa o mesmo algoritmo da solução Pyth do @ Maltysen, que é provavelmente a maneira mais fácil de resolver isso usando as primitivas de golfe típicas. (Curiosamente, a solução "apenas indique o problema" em minha outra resposta seria mais curta se não fosse por bugs / deficiências no intérprete Brachylog, apesar da falta de uso de primitivas de golfe. Algum dia eu preciso escrever um "Brachylog aprimorado" para obter uma boa solução para esse tipo de problema; como os idiomas do golfe, o Brachylog é realmente muito detalhado.)
O programa consiste em um gerador e um invólucro em torno dele. Primeiro, aqui está uma explicação do gerador:
Isso quase resolve o problema, mas acabamos gerando muitas partições muitas vezes cada. Portanto, precisamos de um invólucro para desduplicar as soluções:
fonte
Mathematica, 61 bytes
Define um operador unário (recursivo)
±
que retorna a lista de partições.fonte
Pitão - 17 bytes
Toma todas as permutações da fatoração primária, depois particiona cada uma delas e depois produz todas as partições, mantendo apenas partições distintas.
Conjunto de Teste .
fonte
Python 2, 70 bytes
Produz uma lista de listas classificadas. Por exemplo
f(20)
é[[2, 2, 5], [2, 10], [4, 5], [20]]
.fonte
O(n)
e comparar com o concorrente Python 2 pode ser maisO(n^4)
estiloso - enquanto f (998) pode danificar a memória ou o hardware pode morrer dentro do prazo tempo de aproximadamente 80 dias com o outro algoritmo, este aqui converge após aprox. 7 mili segundos na minha máquina para produzir o resultado[[2, 499], [998]]
. IMO o problema poderia ser mais que, paraN > 998
oRecursionError: maximum recursion depth exceeded in comparison
pára acima Python 3 código ... golfe feliz :-)O(n^4)
é suficiente para o envio do meu Python2: D Considerando o caso de teste 998, meu código será executado 9 vezes e calculará a(n+r-1)! / r! / (n-1)!
quantidade de tuplas de cada vez, onder
cresce linearmente de 2 e n é9 - 2
. Mas ei, pelo menos você não precisa ajustar o limite de recursão ...Geléia ,
141311 bytesExperimente online!
Eu tinha quase certeza de que a solução Jelly @ Dennis poderia ser melhorada. Infelizmente, não consegui bater o recorde do Brachylog, mas consegui empatá-lo. Atualização : com a ajuda do @Dennis, ela melhorou agora; Eu acho que Jelly pega de volta a coroa.
Este programa é incrivelmente ineficiente, com desempenho de O (2 n 2 ) (é por isso que o caso de teste acima o mostra para a entrada 4). É concluído rapidamente em 4, muito lentamente em 5 e pode não ser praticamente possível executar para números maiores.
Curiosamente, o Brachylog foi aprimorado passando de uma solução que descreveu o problema (no qual Brachylog é bom) para uma solução que usou um algoritmo baseado em fatorar a entrada (no qual Jelly é bom); Enquanto isso, a solução Jelly foi aprimorada, afastando-se de seus pontos fortes e retornando a uma solução que apenas descreve o problema.
Explicação:
Como a saída de
Ḋx
é classificada, cada subsequência também deve ser classificada e, portanto, não precisamos classificá-las individualmente. Portanto, a parte "a mesma saída em ordens diferentes é uma duplicata" do problema e os "todos os valores na saída são> 1" parte do problema, resolvidos pela geração. Além disso, o que estamos fazendo basicamente aqui é "encontrar todas as listas para as quaisP=³
", o que fazemos (de uma maneira incrivelmente ineficiente) gerando todas as listas em questão e filtrando as incorretas.(Claramente, alguém precisa inventar um híbrido de Jelly e Brachylog, além de um solucionador de restrições realmente bom , para que possamos escrever algo ao longo das linhas de
{P=³}~
mais algum código de deduplicação e resolver o programa em um tamanho muito mais curto. a alguma distância, no entanto.)fonte
2r
Pode se tornarḊ
eP=³$$
pode se tornarP=¥
.P=¥
não funciona quando o tento no intérprete, embora não tenha muita certeza do porquê (logicamente, deve funcionar, e foi uma das coisas que tentei ao escrever a postagem; tentei novamente para ter certeza, definitivamente não faz o que eu esperava).Ḋ
faz, embora, então eu acho que não é o nosso único byte poupança :-)µ
com¹
, bem, comoµ
faz a gama repetiu o novo argumento esquerdo.³
em vez de¹
apenas para a variedade.)JavaScript (ES6),
7467 bytesResolva diretamente o problema de forma recursiva: para cada número m de 2 a n , pegamos cada partição de n / m com um elemento mínimo de m (para evitar partições duplicadas) e anexamos m . (Para qualquer m que não divida n , isso fornece a matriz vazia, pois nenhum arranjo de números inteiros se multiplica para um decimal.) Definimos um caso base da matriz vazia para 1 , a fim de evitar recursões infinitas.
fonte
Python2,
198191172180 bytesUm programa completo. Isso pode ser melhorado muito, então sugestões são muito bem-vindas!
Saídas do intervalo de 1 a 31 (inclusive):
fonte
4 -> {2, 2}, {4}
em questão, não vejo essa saída no seu log.int(math.log(n,2))
, o que causou isso. +2 bytes e funcionará. Obrigado!math
mas está usandomath.log
.len(bin(n))-2
é mais curto queint(math.log(n,2))
.Gelatina , 15 bytes
Experimente online!
fonte
Clojure, 91 bytes
Exemplo é executado:
O valor em si é retornado como um número único (não a
list
), outros são exibidos como listas. On
final poderia ser substituído por[n]
para torná-lo uma sequência também ou(list n)
para fazer uma lista.fonte
Wolfram Language (Mathematica) ,
585652 bytesExperimente online!
Adaptado da minha solução Mathematica para dividir divisores divisivos . Retorna uma
Sequence
das partições.fonte
J, 35 bytes
Baseado na solução para um desafio de fatoração com restrição de tempo.
Esta versão é muito mais ineficiente e funciona em tempo fatorial com base no número de fatores primos. Cria partições gerando números fatorádicos.
Experimente online! (Não tente grandes valores online!)
Explicação
fonte
D, 95 bytes
Apenas uma solução recursiva. Em
g(n,r)
,r
está a partição até o momento e aindan
é o valor a ser dividido em fatores. Para obter cada partição não ordenada apenas uma vez, ordenamos os fatores emr
ordem não crescente. O último elementor
começa com2
o menor fator possível e é substituído porn
cada cópia imediatamente antes de cada operação de saída.Para
n = 60
, a saída é a seguinte:Experimente online!
fonte
void g(T)(T n,T[]r){for(T i=r[0];i*i<=n;i++)n%i0:r;r.back=n;r.writeln;}g(n,[2])
std.stdio
estd.range
, a entrada não1
deve imprimir nada, não[1]
.D, 109 bytes
Experimente online!
fonte