Declaração de problema
Dado um conjunto de primos únicos e consecutivos (não necessariamente incluindo 2), gere os produtos de todas as combinações das primeiras potências desses primos - por exemplo, sem repetições - e também 1. Por exemplo, dado o conjunto {2, 3, 5, 7}, você produz {1, 2, 3, 5, 6, 7, 10, 14, 15, 21, 30, 35, 42, 70, 105, 210} porque:
1 = 1
2 = 2
3 = 3
5 = 5
6 = 2 x 3
7 = 7
10 = 2 x 5
14 = 2 x 7
15 = 3 x 5
21 = 3 x 7
30 = 2 x 3 x 5
35 = 5 x 7
42 = 2 x 3 x 7
70 = 2 x 5 x 7
105 = 3 x 5 x 7
210 = 2 x 3 x 5 x 7
Observe que, se a cardinalidade do seu conjunto de entradas for k, isso fornecerá 2 ^ k membros no seu conjunto de saída.
Regras / Condições
- Você pode usar qualquer idioma. Aponte para a menor contagem de caracteres do código-fonte.
- Sua solução deve ser um programa completo ou uma função completa. A função pode ser anônima (se o seu idioma suportar funções anônimas).
- Sua solução deve oferecer suporte a produtos de pelo menos 2 ^ 31. Não se preocupe em detectar ou manipular excesso de número inteiro se você receber números passados cujo produto é ótimo demais para representar. No entanto, indique os limites dos seus cálculos.
- Você pode aceitar uma lista ou um conjunto e produzir uma lista ou um conjunto. Você pode assumir que a entrada está classificada, mas não é necessário produzir uma saída classificada.
fundo
Quando ou por que isso é útil? Um local em que é muito útil é gerar uma tabela de multiplicadores para competir em paralelo em um algoritmo de fatoração inteiro conhecido como Fatoração de Formas Quadradas. Lá, cada multiplicador ímpar que você tenta diminui a probabilidade de o algoritmo falhar (para encontrar um fator) em aproximadamente 50% em semiprimes rígidos. Portanto, com o conjunto de primos geradores {3, 5, 7, 11}, que produz um conjunto de 16 multiplicadores de teste para correr em paralelo, o algoritmo falha aproximadamente 2 ^ –16 do tempo em semiprimes rígidos. Adicionar 13 à lista de números primos produz um conjunto de 32 multiplicadores de teste, reduzindo a chance de falha para aproximadamente 2 ^ –32, proporcionando uma melhoria drástica no resultado sem nenhuma despesa computacional adicional (porque mesmo com o dobro do multiplicador correndo em paralelo, em média, ainda encontra a resposta no mesmo número total de etapas).
fonte
1 0
bash --version
CJam, 13 bytes
Lê uma matriz (por exemplo,
[2 3 5 7]
) de STDIN. Experimente online.Uma função anônima teria a mesma contagem de bytes:
Exemplo de execução
Como funciona
fonte
Haskell, 22
a solução é uma função anônima:
exemplo de uso:
explicação:
(:[1])
é uma função que, dado um número,x
retorna a lista[x,1]
.mapM(:[1])
é uma função que, dada uma lista de números, mapeia a função(:[1])
sobre eles e retorna todas as formas possíveis para escolher um elemento de cada lista. por exemplo,mapM(:[1]) $ [3,4]
primeiro mapeia a função a ser obtida[[3,1] , [4,1]]
. então as opções possíveis são[3,4]
(escolhendo o primeiro número de ambos)[3,1]
[1,4]
e,[1,1]
portanto, ele retorna[[3,4],[3,1],[1,4],[1,1]]
.depois
map product
mapeia todas as opções e retorna seus produtos, que são a saída desejada.essa função é polimórfica em seu tipo, o que significa que pode operar em todos os tipos de números. você poderia inserir uma lista
Int
e o resultado seria uma lista de,Int
mas também poderia ser aplicado em uma lista do tipoInteger
e retorne uma lista deInteger
. isso significa que o comportamento de estouro não é especificado por essa função, mas pelo tipo de entrada (sistema de tipo expressivo de yay Haskell :))fonte
Integer
, que é um tipo inteiro ilimitado. Também háInt
um número inteiro de 32 bits, mas isso é apenas uma coisa herdada.Mathematica,
1817 bytesEssa é uma função anônima. Chame como
fonte
×@@@𝒫@#
deve ser imbatível.(*/@#~2#:@i.@^#)
16 caracteres de J;)Atualização: C (função f), 92
Mesmo em função, essa ainda é a entrada mais longa aqui. É a primeira vez que eu passo uma matriz de comprimento desconhecido como argumento de função em C e, aparentemente, não há como uma função C saber o comprimento de uma matriz passada para ela, pois o argumento é passado como um ponteiro ( independentemente da sintaxe usada). Portanto, um segundo argumento é necessário para indicar o comprimento.
Eu mantive a saída em stdout, porque configurar uma matriz inteira e retorná-la quase certamente seria mais longa.
Obrigado a Dennis pelas dicas.
Veja a função
f
(92 caracteres, excluindo espaços em branco desnecessários) nos programas de teste abaixo.Saída via printf
Saída via ponteiro de matriz
C (programa), 108
excluindo espaços em branco desnecessários.
Entrada da linha de comando, saída para stdout. C não vai ganhar aqui, mas talvez eu tente converter para uma função amanhã.
Basicamente, iteramos em todas as
1<<c
combinações de números primos, com cada biti/c
associado à presença ou ausência de um número primo específico no produto. O "loop interno"i%c
percorre os números primos, multiplicando-os de acordo com o valor dei/c.
Quandoi%c
atinge 0, o produto é emitido e, em seguida, definido como 1 para a próxima iteração "externa".curiosamente,
printf("%d ",p,p=1)
não funciona (sempre imprime um 1.) Essa não é a primeira vez que vejo um comportamento estranho quando um valor é usado em aprintf
e atribuído posteriormente no mesmo colchete. É possível, neste caso, que a segunda vírgula não esteja sendo tratada como um separador de argumentos, mas como um operador.Uso
fonte
-Wsequence-point
ou-Wall
, o GCC irá reclamar.c-=1
parac--
ou até mesmo usari=--c<<c
se você não se importa UB (parece para trabalhar com GCC). 2. Ambos os usos de||
podem ser substituídos por operadores ternários:p=i%c?p:!!printf("%d ",p)
ep*=(i/c>>i%c)&1?1:atoi(v[i%c+1])
c-=1
é um jogo de golfe tão básico que eu não deveria ter perdido, mas foi uma rápida correção de bug, porque esqueci que há uma string extra no argv (o nome do programa.)i=..c<<c
funciona no GCC / cygwin, mas deixei meu original programa como está e passou para uma função. Acabei de aprender quesizeof
não funciona em matrizes passadas como argumentos de função. Incorporei suas sugestões para operadores ternários na função. Eu fiquei com a saída stdout, pois não vejo uma maneira curta de retornar uma matriz.Haskell, 27 bytes
Esta é uma implementação Haskell da resposta CJam do @ sudo como uma função anônima. Não superará a incrível solução Haskell do @proud haskeller, mas eu a deixarei aqui de qualquer maneira.
Explicação:
foldr
obtém uma função binária, um valor e uma lista. Em seguida, ele substitui a cada célula contras na lista por uma aplicação da função, eo fim da lista pelo valor, como este:foldr f v [a,b,c] == f a (f b (f c v))
. Nosso valor é uma lista de um elemento que contém1
e a função binária éf = (=<<)(++).map.(*)
. Agora,f
pega um númeron
, cria uma função(n*)
que se multiplican
, cria uma funçãog = map(n*)
que aplica essa função a todos os elementos de uma lista e alimenta essa função(=<<)(++)
. Aqui,(++)
é a função de concatenação, e(=<<)
é ligamento monádico , que neste caso leva em(++)
eg
, e dá uma função que leva em uma lista, aplica-seg
para uma cópia e concatena os dois.Em resumo: comece com
[1]
e para cada númeron
na lista de entrada, faça uma cópia da lista atual, multiplique tudo porn
e adicione-a à lista atual.fonte
Python: 55 caracteres
Gera recursivamente os produtos escolhendo incluir ou excluir cada número por vez.
fonte
and
se você escrever a soma ao contrário?PARI / GP , 26 bytes
Versões mais longas incluem
(30 bytes) e
(31 bytes).
Observe que se a entrada fosse uma matriz de fatoração em vez de um conjunto, 18 bytes poderiam ser salvos usando-se
divisors
sozinhos. Mas converter um conjunto em uma matriz de fatoração parece levar mais de 18 bytes. (Eu posso fazê-lo em 39 bytes diretamente comov->concat(Mat(v~),Mat(vectorv(#v,i,1)))
ou 24 bytes multiplicando e realimentandov->factor(factorback(v))
, alguém pode fazer melhor?)fonte
Sábio -
3634Essencialmente, o mesmo que a solução de Martin Büttner , se bem entendi. Como mencionei em um comentário, posso postá-lo como resposta.
Esta é uma função anônima, que pode, por exemplo, ser chamada da seguinte maneira:
fonte
J (20)
Isso acabou mais do que eu esperava ou esperava. Ainda: mais curto que o haskel!
Uso:
Isso funciona para qualquer conjunto de números, não apenas números primos. Além disso, os números primos podem ter tamanho ilimitado, desde que a matriz tenha o postfix
x
:2 3 5 7x
fonte
*/@#~2#:@i.@^#
é uma alternativa para 14 bytes.05AB1E , 2 bytes
Experimente online!
Explicação
fonte
R, 56 bytes
Estou considerando aqui que s é o conjunto (e uma lista). Tenho certeza de que pode ser reduzido ainda mais. Eu verei.
fonte
PHP, 97 bytes
fonte