Étant donné un nombre positif n , sortez toutes les partitions multiplicatives distinctes de n dans n'importe quel format pratique.
Une partition multiplicative de n est un ensemble d'entiers, tous supérieurs à un, de sorte que leur produit est n . Par exemple, 20 a les partitions multiplicatives distinctes suivantes:
2 * 2 * 5
2 * 10
4 * 5
20
L'ordre n'a pas d'importance, tout 2 * 2 * 5
comme la même partition 2 * 5 * 2
.
Exemples:
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}
Réponses:
Brachylog , 16 octets
C'est une fonction (pas un programme complet) qui prend un nombre positif en entrée et en génère toutes les partitions multiplicatives. (J'ai également évité d'utiliser des facteurs de factorisation principaux dans cette solution, principalement parce que je n'étais pas sûr qu'ils aideraient; je pourrais essayer une solution plus lourde à un moment donné.)
Essayez-le en ligne! (Un code supplémentaire a été ajouté autour de la fonction ici pour en faire un programme complet; si vous fournissez directement la fonction illustrée ci-dessus à TIO, il exécutera la fonction mais n'imprimera sa sortie nulle part, ce qui est en quelque sorte inutile comme démonstration .)
Ce programme me déçoit vraiment, car il fonctionne en grande partie autour des bogues de l'interpréteur Brachylog et des déficiences dans ses spécifications, plutôt que de résoudre réellement le problème; mais l'interprète est ce que c'est. (Même avec le programme comme celui-ci, l'interpréteur utilise beaucoup plus de mémoire qu'il ne devrait logiquement, et se bloque en raison de l'épuisement de la mémoire, mais heureusement, sur de petits problèmes, il parvient à produire la sortie souhaitée en premier.) Dans une hypothétique "version parfaite de Brachylog" vous pourriez simplement écrire
~*.o.:{>1}a,
, ce qui serait 4 octets plus court, mais j'avais besoin d'ajouter des contraintes supplémentaires pour aider l'interprète à sortir un peu. (Je n'aime pas vraiment Brachylog, et je préfère m'en tenir à Prolog, mais il avait besoin de conseils similaires pour faire fonctionner le programme et ils sont beaucoup plus longs à écrire. Donc c'est Brachylog.)Explication:
Comme d'habitude, un programme Brachylog est un ensemble de contraintes; par défaut, la première contrainte contraint l'entrée contre une inconnue (que j'appellerai A ), la deuxième contrainte contraint A contre une deuxième inconnue B , et ainsi de suite jusqu'à ce que nous atteignions la sortie. Certains caractères, tels que
{}
, peuvent modifier ce flux général, donc j'utilise un autre jeu de lettres (par exemple X / Y ) pour représenter les inconnues dans les prédicats imbriqués.On ne sait toujours pas comment fonctionne le programme, alors essayons de simplifier un peu les contraintes. C , D , G , H et I sont tous identiques (et égaux à la sortie). E et F sont également identiques (et égaux à l'entrée). Nos contraintes se résument donc à ceci:
:{1<}a
besoin que son argument de gauche ait une longueur contrainte, ou bien l'interprète entre dans une boucle infinie).Soit dit en passant, je n'ai pas explicitement spécifié que tous les éléments de la sortie sont des entiers, ce qui peut sembler être requis; cependant, le solveur de contraintes de Brachylog ne peut pas gérer les non-entiers, il ne produira donc que les solutions qui impliquent des entiers.
De toute évidence, "la longueur de la sortie est plus petite que l'entrée" va être vraie chaque fois que la sortie est une partition multiplicative de l'entrée (car 2 x > x pour tous les x non négatifs , c'est-à-dire 2 x positifs ). Nous pouvons donc ignorer cette contrainte; il n'est là que pour donner à l'interprète Brachylog une stratégie de travail pour évaluer le programme. Les autres contraintes (que la sortie soit triée, que son produit soit l'entrée et que ses éléments soient tous supérieurs à 1) sont la définition d'une partition multiplicative, et donc cette fonction n'est fondamentalement qu'une implémentation directe de la question.
la source
Brachylog 1, 14 octets
Essayez-le en ligne!
Brachylog 2,
1110 octets, défi de postdates de langueEssayez-le en ligne!
Maltysen a répondu à cette question en 17 octets de Pyth, donc j'ai trouvé une solution Brachylog de 16 octets qui a fonctionné en traduisant la spécification de la question en Brachylog. Pendant que je faisais cela, Dennis a écrit une solution Jelly de 15 octets. J'ai donc dû descendre à 14 octets. Il s'agit d'une fonction qui prend l'entrée en argument et renvoie une liste de toutes les partitions (plutôt qu'un générateur, comme avec mon autre solution).
Quelque temps après avoir écrit cette réponse, Dennis et moi avons réussi à réduire la solution Jelly à 11 octets. Il s'avère qu'il existe une nouvelle version de Brachylog, avec une syntaxe terser; il est postérieur au défi, donc ne compte pas vraiment, mais il pourrait gérer à peu près le total de 11 octets dès sa sortie; les révisions ultérieures de la langue (inspirées d'autres défis) peuvent aller jusqu'à 10, comme on le voit ici. Les deux programmes sont identiques, la seule différence étant la syntaxe.
Contrairement à mon autre solution, qui n'utilisait pas beaucoup les "primitives de golf" mais énonçait plutôt le problème directement, celle-ci ignore à peu près toute la puissance des contraintes Brachylog et fait plutôt sa meilleure impression Jelly, écrivant une chaîne de contraintes pour laquelle l'argument de gauche est déjà connu (et donc les contraintes agissent simplement comme des monades Jelly plutôt que des contraintes à part entière). Il utilise donc le même algorithme que la solution Pyth de @ Maltysen, qui est probablement le moyen le plus simple de résoudre ce problème en utilisant des primitives de golf typiques. (Fait intéressant, la solution "juste énoncer le problème" dans mon autre réponse serait plus courte si ce n'était pour les bugs / déficiences de l'interpréteur Brachylog, malgré son manque d'utilisation des primitives de golf. Un jour, j'ai besoin d'écrire un "Brachylog amélioré" afin d'obtenir une bonne solution pour ce type de problème; comme les langues de golf vont, Brachylog est vraiment très bavard.)
Le programme se compose d'un générateur et d'un wrapper autour de lui. Tout d'abord, voici une explication du générateur:
Cela résout presque le problème, mais nous finissons par générer de nombreuses partitions plusieurs fois chacune. Nous avons donc besoin d'un wrapper pour dédupliquer les solutions:
la source
Mathematica, 61 octets
Définit un opérateur unaire (récursif)
±
qui renvoie la liste des partitions.la source
Pyth - 17 octets
Prend toutes les permutations de la factorisation principale, puis partitionne chacune puis produit toutes les partitions, puis ne conserve que des partitions distinctes.
Suite de tests .
la source
Python 2, 70 octets
Affiche une liste de listes triées. Par exemple
f(20)
est[[2, 2, 5], [2, 10], [4, 5], [20]]
.la source
O(n)
et la comparaison avec le concurrent Python 2 pourrait être plus deO(n^4)
style - tandis que f (998) pourrait faire sauter la mémoire ou le matériel pourrait mourir pendant l'exécution temps d'environ 80 jours avec l'autre algorithme, celui-ci converge ici après env. 7 milli secs sur ma machine pour donner le résultat[[2, 499], [998]]
. OMI le problème pourrait être plus que pourN > 998
lesRecursionError: maximum recursion depth exceeded in comparison
arrêts le code Python 3 ci-dessus ... bon golf :-)O(n^4)
c'est encore suffisant pour ma soumission Python2: D En considérant le cas de test 998, mon code s'exécutera 9 fois et calculera la(n+r-1)! / r! / (n-1)!
quantité de tuples à chaque fois, oùr
croît linéairement à partir de 2, et n l'est9 - 2
. Mais bon, au moins vous n'avez pas à modifier la limite de récursivité ...Gelée ,
141311 octetsEssayez-le en ligne!
J'étais assez sûr que la solution Jelly de @ Dennis pourrait être améliorée. Malheureusement, je n'ai pas réussi à battre le record de Brachylog, mais j'ai réussi à égaler. Mise à jour : Avec l'aide de @Dennis, c'est amélioré maintenant; Je suppose que Jelly reprend la couronne.
Ce programme est incroyablement inefficace, avec des performances O (2 n 2 ) (c'est pourquoi le scénario de test ci-dessus le montre pour l'entrée 4). Il se termine rapidement sur 4, très lentement sur 5, et peut ne pas être pratiquement possible de fonctionner pour de plus grands nombres.
Fait intéressant, le Brachylog a été amélioré en passant d'une solution décrivant le problème (auquel Brachylog est bon) à une solution utilisant un algorithme basé sur la factorisation de l'entrée (où Jelly est bon); pendant ce temps, la solution Jelly a été améliorée en s'éloignant de ses points forts et en revenant à une solution qui ne fait que décrire le problème.
Explication:
Étant donné que la sortie de
Ḋx
est triée, chaque sous-séquence doit également être triée, et nous n'avons donc pas à les trier individuellement. Ainsi, la «même sortie dans des ordres différents est une partie en double» du problème, et la partie «toutes les valeurs de la sortie sont> 1» du problème, est résolue par la génération. En dehors de cela, ce que nous faisons essentiellement ici est de "trouver toutes les listes pour lesquellesP=³
", ce que nous faisons (de manière incroyablement inefficace) en générant toutes les listes en question, puis en filtrant les mauvaises.(De toute évidence, quelqu'un doit aller inventer un hybride de Jelly et Brachylog, plus un très bon solveur de contraintes, afin que nous puissions écrire quelque chose dans le sens de
{P=³}~
plus un peu de code de déduplication, et résoudre le programme dans une longueur beaucoup plus courte. Cela pourrait être à une certaine distance, cependant.)la source
2r
Peut devenirḊ
, etP=³$$
peut devenirP=¥
.P=¥
ne fonctionne pas lorsque je l'essaie dans l'interpréteur, bien que je ne sache pas vraiment pourquoi (logiquement, cela devrait fonctionner, et c'est l'une des choses que j'ai essayées lors de la rédaction du message; je l'ai juste réessayé pour m'assurer, il ne fait définitivement pas ce à quoi je m'attendais).Ḋ
le fait, donc je suppose qu'il y a notre économie sur un octet :-)µ
par¹
, carµ
la plage répétée devient le nouvel argument de gauche.³
plutôt que¹
juste pour la variété.)JavaScript (ES6),
7467 octetsRésout directement le problème récursivement: pour chaque entier m de 2 à n , nous prenons chacune des partitions de n / m avec un élément minimum de m (pour éviter les partitions en double) et ajoutons m . (Pour tout m qui ne divise pas n , cela donne le tableau vide, car aucun arrangement d'entiers ne se multiplie en décimal.) Nous définissons un cas de base du tableau vide pour 1 afin d'éviter une récursion infinie.
la source
Python2,
198191172 172180 octetsUn programme complet. Cela pourrait être beaucoup amélioré, donc les suggestions sont les bienvenues!
Sorties de la plage 1 à 31 (inclus):
la source
4 -> {2, 2}, {4}
en question, je ne vois pas une telle sortie dans votre journal.int(math.log(n,2))
, ce qui a causé cela. +2 octets et cela fonctionnera. Merci!math
mais utilisezmath.log
.len(bin(n))-2
est plus court queint(math.log(n,2))
.Gelée , 15 octets
Essayez-le en ligne!
la source
Clojure, 91 octets
L'exemple s'exécute:
La valeur elle-même est renvoyée sous la forme d'un nombre unique (pas un
list
), d'autres sortent sous forme de listes. Len
à la fin pourrait être remplacé par[n]
pour en faire une séquence également, ou(list n)
pour en faire une liste.la source
Wolfram Language (Mathematica) ,
585652 octetsEssayez-le en ligne!
Adapté de ma solution Mathematica aux diviseurs diviseurs diviseurs . Renvoie une
Sequence
des partitions.la source
J, 35 octets
Basé sur la solution à un défi de factorisation limité dans le temps.
Cette version est beaucoup plus inefficace et fonctionne en temps factoriel en fonction du nombre de facteurs premiers. Crée des partitions en générant des nombres factoriels.
Essayez-le en ligne! (N'essayez pas de grandes valeurs en ligne!)
Explication
la source
D, 95 octets
Juste une solution récursive. Dans
g(n,r)
,r
est la partition jusqu'à présent, etn
est la valeur qui reste à diviser en facteurs. Pour obtenir chaque partition non ordonnée une seule fois, nous trions les facteurs dansr
un ordre non croissant. Le dernier élément der
commence2
comme le facteur le moins possible et est remplacé parn
dans chaque copie juste avant chaque opération de sortie.Pour
n = 60
, la sortie est la suivante:Essayez-le en ligne!
la source
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
etstd.range
, la saisie1
ne doit rien imprimer, non[1]
.D, 109 octets
Essayez-le en ligne!
la source