Trouver les ensembles de sommes

15

J'ai aimé lire ce site; c'est ma première question. Les modifications sont les bienvenues.

Étant donné les entiers positifs n et m , calculez toutes les partitions ordonnées de m en exactement n parties parties entières positives et imprimez-les délimitées par des virgules et des sauts de ligne. Toute commande est correcte, mais chaque partition doit apparaître exactement une fois.

Par exemple, étant donné m = 6 et n = 2, les partitions possibles sont des paires d'entiers positifs qui se résument à 6:

1,5
2,4
3,3
4,2
5,1

Notez que [1,5] et [5,1] sont des partitions ordonnées différentes. La sortie doit être exactement dans le format ci-dessus, avec une nouvelle ligne de fin facultative. (EDIT: l'ordre exact des partitions n'a pas d'importance). Les entrées / sorties se font via des E / S de code-golf standard .

Un autre exemple de sortie pour m = 7, n = 3:

1,1,5
1,2,4
2,1,4
1,3,3
2,2,3
3,1,3
1,4,2
2,3,2
3,2,2
4,1,2
1,5,1
2,4,1
3,3,1
4,2,1
5,1,1

Le plus petit code en octets après 1 semaine gagne.

Encore une fois, veuillez modifier si nécessaire.

Addenda:

@TimmyD a demandé quelle taille d'entrée entière le programme doit prendre en charge. Il n'y a pas de minimum strict au-delà des exemples; en effet, la taille de sortie augmente de façon exponentielle, grossièrement modélisée par: lines = e ^ (0,6282 n - 1,8273).

n | m | lines of output
2 | 1 | 1
4 | 2 | 2
6 | 3 | 6
8 | 4 | 20
10 | 5 | 70
12 | 6 | 252
14 | 7 | 924
16 | 8 | 3432
18 | 9 | 12870
20 | 10 | 48620
22 | 11 | 184756
24 | 12 | 705432
cuniculus
la source
Les réponses doivent-elles prendre en charge des entiers arbitrairement grands, ou une borne supérieure raisonnable comme 2 ^ 31-1 convient-elle?
AdmBorkBork
4
Le terme "ensembles" prête à confusion car l'ordre est important. Je pense que le terme que vous recherchez est des partitions ordonnées.
xnor
2
Bien qu'il ne soit pas nécessaire de changer, nous avons généralement un format de sortie plus lâche que celui-ci.
lirtosiast
J'ai modifié votre formulation pour autoriser les E / S via des arguments de fonction, des invites et d'autres méthodes d'E / S que nous considérons généralement comme acceptables.
lirtosiast
@TimmyD, la taille de la sortie augmente de façon plutôt explosive, de sorte qu'il n'est pas pratique d'essayer m et n après quelques centaines, sans parler de 2 ^ 31-1.
cuniculus

Réponses:

7

Pyth, 14 octets

V^SQEIqsNQj\,N

Essayez-le en ligne: démonstration ou suite de tests

Explication:

V^SQEIqsNQj\,N   implicit: Q = first input number
  SQ             create the list [1, 2, ..., Q]
    E            read another number
 ^               cartesian product of the list
                 this creates all tuples of length E using the numbers in SQ
V                for each N in ^:
     IqsNQ          if sum(N) == Q:
          j\,N         join N by "," and print
Jakube
la source
En outre 14 octets, approche différente: jjL\,fqsTQ^SQE.
PurkkaKoodari
6

Python 3, 77 octets

def f(n,m,s=''):[f(i,m-1,',%d'%(n-i)+s)for i in range(n)];m|n or print(s[1:])

Une fonction récursive qui construit chaque chaîne de sortie et l'imprime. Essaie chaque premier nombre possible, en revenant vers le bas pour trouver une solution avec la somme diminuée correspondante n, et un summand de moins m, et un préfixe de chaîne savec ce nombre. Si la somme requise et le nombre de termes sont égaux à 0, nous avons frappé la marque, donc nous imprimons le résultat, en coupant la virgule initiale. Ceci est vérifié comme m|nétant 0 (Falsey).

79 caractères dans Python 2:

def f(n,m,s=''):
 if m|n==0:print s[1:]
 for i in range(n):f(i,m-1,','+`n-i`+s)
xnor
la source
4

CJam, 22 octets

q~:I,:)m*{:+I=},',f*N*

Essayez-le en ligne dans l' interpréteur CJam .

Comment ça fonctionne

q~                      Read and evaluate all input. Pushes n and m.
  :I                    Save m in I.
    ,:)                 Turn it into [1 ... I].
       m*               Push all vectors of {1 ... I}^n.
         {    },        Filter; for each vector:
          :+I=            Check if the sum of its elements equals I.
                        Keep the vector if it does.
                ',f*    Join all vectors, separating by commas.
                    N*  Join the array of vectors, separating by linefeeds.
Dennis
la source
3

Pyth, 20 18 octets

-2 octets par @Dennis!

jjL\,fqQlT{s.pM./E

Cela prend ncomme première ligne d'entrée et mcomme seconde.

Essayez-le ici .

lirtosiast
la source
3

Haskell, 68 octets

n#m=unlines[init$tail$show x|x<-sequence$replicate n[1..m],sum x==m]

Exemple d'utilisation:

*Main> putStr $ 2#6
1,5
2,4
3,3
4,2
5,1

Comment ça marche: sequence $ replicate n listcrée toutes les combinaisons d' néléments dessinés sous forme list. Nous prenons tous ces xd' [1..m]où l' sumégal m. unlineset init$tail$showproduire le format de sortie requis.

nimi
la source
3

Dyalog APL , 33 octets

{↑1↓¨,/',',¨⍕¨↑⍺{⍵/⍨⍺=+/¨⍵},⍳⍵/⍺}

Prend mcomme argument de gauche, ncomme argument de droite.

Près de la moitié (entre {et ) correspond à la mise en forme requise.

Adam
la source
2

Mathematica, 65 octets

StringRiffle[Permutations/@#~IntegerPartitions~{#2},"
","
",","]&

IntegerPartitionsfait la tâche. Le reste consiste simplement à ordonner les tuples et à formater le résultat.

LegionMammal978
la source
2

Python 3, 112

from itertools import*
lambda m,n:'\n'.join(','.join(map(str,x))for x in product(range(m),repeat=n)if sum(x)==m)

Je n'ai pas réussi un liner depuis un moment. :)

Morgan Thrapp
la source
1

Python 2.7, 174 170 152 octets

Grosse réponse. Au moins c'est lisible :)

import sys,itertools
m=int(sys.argv[1])
for k in itertools.product(range(1,m),repeat=int(sys.argv[2])):
    if sum(k)==m:print str(k)[1:-1].replace(" ","")
Gabriele D'Antona
la source
Vous pouvez supprimer les espaces autour >, après replaceet après la virgule.
Alex A.
1

Julia, 105 octets

f(m,n)=for u=∪(reduce(vcat,map(i->collect(permutations(i)),partitions(m,n)))) println("$u"[2:end-1])end

Il s'agit d'une fonction qui lit deux arguments entiers et écrit les résultats dans STDOUT avec un seul saut de ligne.

Non golfé:

function f(m::Integer, n::Integer)
    # Get the integer partitions of m of length n
    p = partitions(m, n)

    # Construct an array of all permutations
    c = reduce(vcat, map(i -> collect(permutations(i)), p))

    # Loop over the unique elements
    for u in unique(c)
        # Print the array representation with no brackets
        println("$u"[2:end-1])
    end
end
Alex A.
la source
0

Perl 6 , 54 octets

Si la sortie peut être une liste de listes

{[X] (1..$^m)xx$^n .grep: $m==*.sum} # 36 bytes
my &code = {[X] (1..$^m)xx$^n .grep: $m==*.sum}
say .join(',') for code 7,3;

La façon dont il est actuellement libellé, je dois ajouter un joindans le lambda.

{say .join(',')for [X] (1..$^m)xx$^n .grep: $m==*.sum} # 54 bytes
{...}( 7,3 );
1,1,5
1,2,4
1,3,3
1,4,2
1,5,1
2,1,4
2,2,3
2,3,2
2,4,1
3,1,3
3,2,2
3,3,1
4,1,2
4,2,1
5,1,1
Brad Gilbert b2gills
la source