Znajdź zestawy sum

15

Lubię czytać tę stronę; to jest moje pierwsze pytanie. Zmiany są mile widziane.

Biorąc pod uwagę dodatnie liczby całkowite n i m , oblicz wszystkie uporządkowane partycje m na dokładnie n części dodatnich liczb całkowitych i wydrukuj je rozdzielone przecinkami i znakami nowej linii. Każda kolejność jest w porządku, ale każda partycja musi pojawić się dokładnie raz.

Na przykład, biorąc pod uwagę m = 6 i n = 2, możliwe partycje są parami liczb całkowitych dodatnich, które sumują się do 6:

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

Zauważ, że [1,5] i [5,1] to różne uporządkowane partycje. Dane wyjściowe powinny być dokładnie w powyższym formacie, z opcjonalnym końcowym znakiem nowej linii. (EDYCJA: Dokładna kolejność partycji nie ma znaczenia). Wejścia / wyjścia są realizowane przez standardowe we / wy Code-golf .

Kolejny przykładowy wynik dla 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

Najmniejszy kod w bajtach po 1 tygodniu wygrywa.

Ponownie edytuj w razie potrzeby.

Uzupełnienie:

@ TimmyD zapytał, jaki rozmiar liczby całkowitej jest obsługiwany przez program. Nie ma twardego minimum poza przykładami; w rzeczywistości rozmiar wyjściowy rośnie wykładniczo, z grubsza modelowany przez: linie = 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
źródło
Czy odpowiedzi muszą obsługiwać dowolnie duże liczby całkowite, czy też odpowiednia jest górna granica, taka jak 2 ^ 31-1?
AdmBorkBork,
4
Termin „zestawy” jest mylący, ponieważ kolejność ma znaczenie. Myślę, że szukany termin to uporządkowane partycje.
xnor
2
Chociaż zmiana nie jest konieczna, zwykle mamy luźniejszy format wyjściowy niż ten.
lirtosiast
Zmieniłem twoje sformułowanie, aby umożliwić I / O poprzez argumenty funkcji, monity i inne metody I / O, które zwykle uważamy za dopuszczalne.
lirtosiast
@ TimmyD, wielkość wyjściowa rośnie dość gwałtownie, więc nie jest praktyczne wypróbowanie m i n przeszłość kilkuset, nie mówiąc już 2 ^ 31-1.
cuniculus,

Odpowiedzi:

7

Pyth, 14 bajtów

V^SQEIqsNQj\,N

Wypróbuj online: pakiet demonstracyjny lub testowy

Wyjaśnienie:

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
źródło
Również 14 bajtów, inne podejście: jjL\,fqsTQ^SQE.
PurkkaKoodari,
6

Python 3, 77 bajtów

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

Funkcja rekurencyjna, która buduje każdy ciąg wyjściowy i drukuje go. Próbuje każdej możliwej pierwszej liczby, powtarzając w dół, aby znaleźć rozwiązanie z odpowiednią zmniejszoną sumąn i jednym mniejszym sumowaniemm prefiksem łańcucha so tej liczbie. Jeśli zarówno wymagana suma, jak i liczba wyrażeń są równe 0, trafiliśmy w znak, więc wypisujemy wynik, odcinając początkowy przecinek. Jest to sprawdzane jako m|n0 (Falsey).

79 znaków w Pythonie 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
źródło
4

CJam, 22 bajty

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

Wypróbuj online w interpretatorze CJam .

Jak to działa

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
źródło
3

Pyth, 20 18 bajtów

-2 bajty @Dennis!

jjL\,fqQlT{s.pM./E

Pobiera to njako pierwszy wiersz danych wejściowych im jako drugi.

Wypróbuj tutaj .

lirtosiast
źródło
3

Haskell, 68 bajtów

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

Przykład użycia:

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

Jak to działa: sequence $ replicate n listtworzy wszystkie kombinacje nelementów rysowanych w formie list. Bierzemy wszystkie takie, xw [1..m]których sumrówna się m. unlinesi init$tail$showwygeneruj wymagany format wyjściowy.

nimi
źródło
3

Dyalog APL , 33 bajty

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

Przyjmuje mjako lewy argumentn jako prawy argument.

Prawie połowa (między {i ) dotyczy wymaganego formatowania.

Adám
źródło
2

Mathematica, 65 bajtów

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

IntegerPartitionswykonuje zadanie. Reszta to po prostu zamówić krotki i sformatować wynik.

LegionMammal978
źródło
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)

Od jakiegoś czasu nie zarządzałem 1 linijką. :)

Morgan Thrapp
źródło
1

Python 2.7, 174 170 152 bajtów

Gruba odpowiedź. Przynajmniej jest czytelny :)

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
źródło
Możesz usunąć spacje wokół >, po replacei po przecinku.
Alex A.,
1

Julia, 105 bajtów

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

Jest to funkcja, która odczytuje dwa argumenty liczb całkowitych i zapisuje wyniki do STDOUT z pojedynczym wierszem końcowym.

Nie golfowany:

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.
źródło
0

Perl 6 , 54 bajtów

Jeśli wynikiem może być lista list

{[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;

W obecnym brzmieniu muszę dodać znak joinlambda.

{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
źródło