Énoncé du problème
Étant donné un ensemble de nombres premiers uniques consécutifs (ne comprenant pas nécessairement 2), générez les produits de toutes les combinaisons de premières puissances de ces nombres premiers - par exemple, pas de répétitions - et également 1. Par exemple, étant donné l'ensemble {2, 3, 5, 7}, vous produisez {1, 2, 3, 5, 6, 7, 10, 14, 15, 21, 30, 35, 42, 70, 105, 210} parce que:
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
Notez que si la cardinalité de votre jeu d'entrée est k, cela vous donnera 2 ^ k membres dans votre jeu de sortie.
Règles / Conditions
- Vous pouvez utiliser n'importe quelle langue. Visez le plus petit nombre de caractères du code source.
- Votre solution doit être soit un programme complet, soit une fonction complète. La fonction peut être anonyme (si votre langue prend en charge les fonctions anonymes).
- Votre solution doit pouvoir prendre en charge des produits jusqu'à au moins 2 ^ 31. Ne vous inquiétez pas de détecter ou de gérer un débordement d'entier si vous passez des nombres dont le produit est trop grand pour être représenté. Veuillez cependant indiquer les limites de vos calculs.
- Vous pouvez accepter une liste ou un ensemble et produire une liste ou un ensemble. Vous pouvez supposer que l'entrée est triée, mais vous n'êtes pas obligé de produire une sortie triée.
Contexte
Quand ou pourquoi est-ce utile? Il est très utile de générer une table de multiplicateurs pour faire la course en parallèle dans un algorithme de factorisation d'entier connu sous le nom de factorisation de formes carrées. Là, chaque multiplicateur impair que vous essayez diminue la probabilité que l'algorithme échoue (pour trouver un facteur) d'environ 50% sur les demi-durs durs. Ainsi, avec l'ensemble de génération de nombres premiers {3, 5, 7, 11}, qui produit un ensemble de 16 multiplicateurs d'essai pour faire la course en parallèle, l'algorithme échoue environ 2 ^ –16 du temps sur les demi-durs durs. L'ajout de 13 à la liste des nombres premiers produit un ensemble de 32 multiplicateurs d'essai, réduisant le risque d'échec à environ 2 ^ –32, ce qui donne une amélioration drastique des résultats sans frais de calcul supplémentaires (car même avec deux fois plus de multiplicateurs qui courent en parallèle, sur moyenne, il trouve toujours la réponse dans le même nombre total d'étapes).
la source
1 0
bash --version
CJam, 13 octets
Lit un tableau (par exemple,
[2 3 5 7]
) à partir de STDIN. Essayez-le en ligne.Une fonction anonyme aurait le même nombre d'octets:
Exemple d'exécution
Comment ça marche
la source
Haskell, 22
la solution est une fonction anonyme:
exemple d'utilisation:
explication:
(:[1])
est une fonction qui, étant donné un nombre,x
renvoie la liste[x,1]
.mapM(:[1])
est une fonction qui, à partir d'une liste de nombres, mappe la fonction(:[1])
sur eux et renvoie toutes les manières possibles de choisir un élément dans chaque liste. par exemple,mapM(:[1]) $ [3,4]
mappe d'abord la fonction à obtenir[[3,1] , [4,1]]
. alors les choix possibles sont[3,4]
(en choisissant le premier nombre des deux)[3,1]
[1,4]
et[1,1]
ainsi il revient[[3,4],[3,1],[1,4],[1,1]]
.puis des
map product
cartes sur tous les choix et retourne leurs produits, qui sont la sortie désirée.cette fonction est polymorphe dans son type, ce qui signifie qu'elle peut fonctionner sur tous les types de nombres. vous pouvez entrer une liste de
Int
et le résultat serait une liste deInt
mais pourrait également être appliqué sur une liste de typeInteger
et retourner une liste deInteger
. cela signifie que le comportement de débordement n'est pas spécifié par cette fonction mais par le type de l'entrée (yay Haskell's expressive type system :))la source
Integer
, qui est un type entier illimité. Il y a aussiInt
un entier 32 bits, mais c'est surtout juste une chose héritée.Mathematica,
1817 octetsC'est une fonction anonyme. Appelez ça comme
la source
×@@@𝒫@#
devrait être imbattable.(*/@#~2#:@i.@^#)
16 caractères en J;)Mise à jour: C (fonction f), 92
Même en tant que fonction, c'est toujours l'entrée la plus longue ici. C'est la première fois que je passe un tableau de longueur inconnue comme argument de fonction en C, et apparemment il n'y a aucun moyen pour une fonction C de connaître la longueur d'un tableau qui lui est passé, car l'argument est passé comme pointeur ( quelle que soit la syntaxe utilisée). Un deuxième argument est donc nécessaire pour indiquer la longueur.
J'ai gardé la sortie sur stdout, car configurer un tableau entier et le renvoyer serait presque certainement plus long.
Merci à Dennis pour les conseils.
Voir la fonction
f
(92 caractères hors espaces blancs inutiles) dans les programmes de test ci-dessous.Sortie via printf
Sortie via un pointeur de tableau
C (programme), 108
excluant les espaces inutiles.
Entrée depuis la ligne de commande, sortie vers la sortie standard. C ne va pas gagner ici, mais peut-être que j'essaierai de convertir en fonction demain.
Fondamentalement, nous parcourons toutes les
1<<c
combinaisons de nombres premiers, chaque biti/c
étant associé à la présence ou à l'absence d'un nombre premier particulier dans le produit. La "boucle interne"i%c
parcourt les nombres premiers, en les multipliant selon la valeur dei/c.
Lorsquei%c
atteint 0, le produit est sorti, puis défini sur 1 pour l'itération "externe" suivante.curieusement,
printf("%d ",p,p=1)
ne fonctionne pas (il imprime toujours un 1.) Ce n'est pas la première fois que je vois un comportement étrange lorsqu'une valeur est utilisée dans aprintf
et attribuée plus tard dans le même crochet. Il est possible dans ce cas que la deuxième virgule ne soit pas traitée comme un séparateur d'arguments, mais plutôt comme un opérateur.Usage
la source
-Wsequence-point
ou-Wall
, GCC se plaindra.c-=1
àc--
ou même utiliseri=--c<<c
si vous ne me dérange pas UB (il semble fonctionner avec GCC). 2. Les deux utilisations de||
peuvent être remplacées par des opérateurs ternaires:p=i%c?p:!!printf("%d ",p)
etp*=(i/c>>i%c)&1?1:atoi(v[i%c+1])
c-=1
est un golf de base, je n'aurais pas dû le manquer, mais c'était une correction rapide de bogue car j'avais oublié qu'il y avait une chaîne supplémentaire dans argv (le nom du programme.)i=..c<<c
fonctionne sur GCC / cygwin, mais j'ai laissé mon original programme tel quel et passe à une fonction. Je viens donc d'apprendre quesizeof
cela ne fonctionne pas sur les tableaux passés comme arguments de fonction. J'ai intégré vos suggestions d'opérateurs ternaires dans la fonction. Je suis resté avec la sortie vers stdout car je ne vois aucun moyen de retourner un tableau.Haskell, 27 octets
Il s'agit d'une implémentation Haskell de la réponse CJam de @ sudo en tant que fonction anonyme. Cela ne battra pas la formidable solution Haskell de @proud haskeller, mais je la déposerai quand même.
Explication:
foldr
prend une fonction binaire, une valeur et une liste. Ensuite , il remplace chaque cellule de contre dans la liste par une application de la fonction, et la fin de la liste par la valeur, comme ceci:foldr f v [a,b,c] == f a (f b (f c v))
. Notre valeur est une liste à un élément contenant1
, et la fonction binaire estf = (=<<)(++).map.(*)
. Maintenant,f
prend un nombren
, crée une fonction(n*)
qui multiplie parn
, en fait une fonctiong = map(n*)
qui applique cette fonction à tous les éléments d'une liste et alimente cette fonction(=<<)(++)
. Ici,(++)
est la fonction de concaténation, et(=<<)
est une liaison monadique , qui dans ce cas prend(++)
etg
, et donne une fonction qui prend dans une liste, s'appliqueg
à une copie de celui-ci, et concatène les deux.En bref: commencez par
[1]
, et pour chaque numéron
de la liste d'entrée, prenez une copie de la liste actuelle, multipliez tout parn
et ajoutez-la à la liste actuelle.la source
Python: 55 caractères
Génère récursivement les produits en choisissant d'inclure ou d'exclure chaque numéro tour à tour.
la source
and
si vous écrivez la somme dans l'autre sens?PARI / GP , 26 octets
Les versions plus longues incluent
(30 octets) et
(31 octets).
Notez que si l'entrée était une matrice de factorisation plutôt qu'un ensemble, 18 octets pouvaient être enregistrés en utilisant
divisors
seuls. Mais la conversion d'un ensemble en matrice de factorisation semble prendre plus de 18 octets. (Je peux le faire en 39 octets directementv->concat(Mat(v~),Mat(vectorv(#v,i,1)))
ou en 24 octets en multipliant et en refactorisantv->factor(factorback(v))
, quelqu'un peut-il faire mieux?)la source
Sauge -
3634Essentiellement, la même que la solution de Martin Büttner , si je comprends bien. Comme je l'ai mentionné dans un commentaire, je pourrais aussi bien l'afficher comme réponse.
Il s'agit d'une fonction anonyme, qui peut par exemple être appelée comme suit:
la source
J (20)
Cela s'est avéré plus long que ce que j'espérais ou espérais. Encore: plus court que haskel!
Usage:
Cela fonctionne pour tout ensemble de nombres, pas seulement pour les nombres premiers. De plus, les nombres premiers peuvent être de taille illimitée, tant que le tableau a le suffixe
x
:2 3 5 7x
la source
*/@#~2#:@i.@^#
est une alternative pour 14 octets.05AB1E , 2 octets
Essayez-le en ligne!
Explication
la source
R, 56 octets
Je considère ici que s est l'ensemble (et une liste). Je suis sûr que cela peut être encore plus court. Je verrai.
la source
PHP, 97 octets
la source