Die Herausforderung besteht darin, alle geordneten Partitionen (Zusammensetzung (Kombinatorik)) einer bestimmten positiven ganzen Zahl aufzulisten n
. Dies sind die Nummernlisten von 1
bis zu n
deren Summe n
. Zum Beispiel n = 4
sollte das Ergebnis bei einer gegebenen Eingabe sein:
4
1, 3
3, 1
2, 2
2, 1, 1
1, 2, 1
1, 1, 2
1, 1, 1, 1
Das Ergebnis kann in beliebiger Reihenfolge vorliegen, muss jedoch jede geordnete Partition einmal enthalten. Dies bedeutet , dass für n = 4
, [1, 1, 2]
, [1, 2, 1]
und [2, 1, 1]
muß alle Teile des Ergebnisses sein.
Hier ist mein eigener JavaScript-Code, der dies erreicht:
function range(n) {
for (var range = [], i = 0; i < n; range.push(++i));
return range;
}
function composition(n) {
return n < 1 ? [[]] : range(n).map(function(i) {
return composition(n - i).map(function(j) {
return [i].concat(j);
});
}).reduce(function(a, b) {
return a.concat(b);
});
}
Golf, ES6 ( 169 167 119 109 105 89 85 Byte ):
n=>n?[].concat(...[...Array(n)].map((x,i)=>i+1).map(b=>m(n-b).map(a=>[b,...a]))):[[]]
Antworten:
Pyth,
76 Bytes7 Byte Lösung:
In Pyth ist eine Ganzzahlpartition integriert
./
, sodass 5 der 7 Bytes die Reihenfolge erhalten.Probieren Sie es online!
Erläuterung:
6 Byte Lösung:
Wenn Sie eine Liste haben,
./
wird mit Bestellungen berechnet; Alles was bleibt ist, die Listen erneut zu nummerieren.Probieren Sie es online!
Erläuterung:
quelle
Haskell, 37 Bytes
xnor sparte zwei Bytes.
quelle
f n=[a:x|a<-[1..n],x<-f$n-a]
kürzer ist.given positive integer n ... numbers from 1 to n
f 0=[[]]
Zufällig ist es ein kürzerer Basisfall alsf 1=[[1]]
:)Python, 56 Bytes
Eine rekursive Lösung: Die geordneten Teilungen
n
sind eine Partition von einigen kleinereni
mit0<=i<n
, durch den Rest gefolgtn-i
als letztes Element. In einem Basisfall istn=0
nur die Partition leer.quelle
Python 2, 61 Bytes
Dies ist nicht die kürzeste, aber ich mag die Methode wirklich, weil sie so seltsam ist.
Generiert rekursiv und wertet
2**(n-1)
Strings wiefür
n=4
. Diese Zeichenfolgen werden zu Tupeln ausgewertet, die alle Partitionen darstellen. Zwischen zwei Einsen befindet sich entweder eine+
, die sie zu einer einzigen Zahl zusammenfügt, oder eine,
, die benachbarte Abschnitte aufteilt.quelle
import re
lambda n:map(lambda n:map(len,re.finall('10*',bin(n))),range(1<<n-1,1<<n))
JavaScript (Firefox 30-57), 63 Byte
quelle
f=n=>n<2?[[1]]:f(n-1).map(([n,...a])=>r.push([1+n,...a],[1,n,...a]),r=[])&&r
.Mathematica, 40 Bytes
Die in Mathematica integrierte Funktion für ganzzahlige Partitionen gibt nicht alle geordneten Partitionen an. Wir müssen daher alle möglichen Permutationen für jede dieser Partitionen generieren und dann das Ergebnis reduzieren.
quelle
CJam ,
1714 BytesProbieren Sie es online!
Erläuterung
Ich wusste, dass die Verwendung des kartesischen Produkts länger dauert, fand aber schließlich einen Weg, es effizienter zu nutzen. Ich denke, dass beide Ansätze für sich genommen interessant sind, also setze ich sie in separate Posts.
Dies basiert immer noch auf der Idee, dass wir
n
zwischen dem Anhängen eines1
an die aktuelle Partition oder dem Inkrementieren des letzten Elements der aktuellen Partition wählen können . In dieser Lösung erzeugen wir dazu 2 n-1 verschiedene Programme, die diesen verschiedenen Auswahlen entsprechen.quelle
)
" beginnt . Also habe ich hinzugefügted
und getestet. +1 für kreativen Missbrauch von Fehlern.Gelee ,
76 Bytes-1 Byte dank @Dennis (von unary konvertieren
ḅ1
, anstatt Summe für jeden für jedenS€€
)TryItOnline
Wie?
quelle
Pure Bash, 51
Dies ist eine Portierung von @ xnors brillanter Antwort , die mehrere Stufen von Bash-Erweiterungen verwendet, um das gewünschte Ergebnis zu erzielen:
Ideone.
$a
die1
gefolgt vonn-1
Nullen ist.${a//0/{+,']\ $[}1'}
ersetzt jeden0
in$a
Kopien der Zeichenfolge{+,']\ $[}1'
. Also n = 4 bekommen wir den String1{+,']\ $[}1'{+,']\ $[}1'{+,']\ $[}1'
$[
und mit nachfixiert],
zu geben$[1{+,']\ $[}1'{+,']\ $[}1'{+,']\ $[}1]
$[1+1+1+1], $[1+1+1] 1, $[1+1] $[1+1], $[1+1] 1 1,...
Sorgfältiger Umgang mit Anführungszeichen, Backslash und
eval
Sicherstellung, dass die Erweiterungen in der richtigen Reihenfolge erfolgen.quelle
Ruby, 61 Bytes
ungolfed
Verwendung
quelle
x<<i
ist kürzer als[i]+x
..flatten(1)
ist nicht.flatten 1
?Brachylog , 20 Bytes
Probieren Sie es online!
Erläuterung
Dies ist eine Situation, in der man denken würde, dass deklarative Sprachen gut funktionieren würden, aber aufgrund der Überlastung
+
und der schwierigen Schreibweise eines Summierungsprädikats, das Einschränkungen richtig propagiert, tun sie dies nicht.quelle
L
sein zwischen 1 und Eingang.+
auch eine einzelne Ganzzahl bearbeitet wird, muss erzwungen.
werden, eine Liste mit zu sein##
, und da+
auch eine Liste mit Listen bearbeitet wird, muss erzwungen werden, dass die Elemente von.
Ganzzahlen mit sind:#$a
.CJam , 19 Bytes
Probieren Sie es online!
Erläuterung
In CJam ist keine nützliche Kombinatorik für ganzzahlige Partitionen integriert. Also machen wir das manuell. Um alle geordneten Partitionen einer Ganzzahl zu finden
n
, können wir uns eine Liste von Partitionen ansehenn
und überlegen, wie Trennzeichen eingefügt werden können. Dann werden wir die1
s in jedem Abschnitt summieren . Beispiel fürn = 3
:Ich habe versucht, mit einem kartesischen Produkt alle diese Trennzeichen zu generieren, aber das ergab 21 Byte. Stattdessen bin ich auf diese alte Technik zur Stromerzeugung zurückgegangen (diese basiert auf einer alten Antwort von Dennis, aber ich kann sie derzeit nicht finden). Die Idee ist: Um alle Partitionen zu generieren, können wir von einer leeren Liste ausgehen. Dann
n
können wir mal eine binäre Entscheidung treffen: Entweder wir hängen ein an1
(entspricht einem Trennzeichen im obigen Beispiel) oder wir erhöhen den letzten Wert der Liste (entspricht dem Fehlen eines Trennzeichens). Um alle Partitionen zu generieren, führen wir einfach beide Operationen bei jedem Schritt durch und behalten alle möglichen Ausgaben für den nächsten Schritt. Es stellt sich heraus, dass in CJam das Voranstellen und Inkrementieren des ersten Elements kürzer ist, das Prinzip jedoch dasselbe bleibt:quelle
T-SQL, 203 Bytes
Golf gespielt:
Ungolfed:
Geige
quelle
Mathematica 10.0, 44 Bytes
Ein Versuch, ohne partitionsbezogene Builtins zu verwenden. Aus jeder geordneten Partition der Größe k werden zwei Nachfolgepartitionen von k + 1 erzeugt: eine durch Voranstellen von 1 und die andere durch Inkrementieren des ersten Werts.
Ein lustigerer, aber leider 2 Bytes längerer Weg, die gleiche Idee umzusetzen:
quelle
MapAt
Index auf -1 ändern müsste .05AB1E ,
1412 Bytes2 Bytes gespart dank Adnan
Erläuterung
Probieren Sie es online!
Die entsprechende Lösung ist in 2sable 2 Byte kürzer .
2sable , 10 Bytes
Probieren Sie es online!
quelle
—
anstelle voniy,
:) verwenden.Haskell, 41 Bytes
Nicht die kürzeste Haskell-Lösung, aber ich mag, dass sie keine
[..]
Bereiche verwendet. Stattdessen werden die Partitionen von rekursivn
als die Partitionen vonn-1
entweder mit einer neuen 1 am Anfang oder mit dem ersten Wert eins höher berechnet. Dies macht deutlich, warum es2^(n-1)
von ihnen gibt.quelle
Mathematica, 53 Bytes
Die Antwort von Martin Ender, der die eingebaute
IntegerPartitions
Funktion verwendet, ist unschlagbar (und die eingebauten Funktionen sind für mich völlig in Ordnung). (Es schlägt auch nicht die Antwort von feersum, die ich erst zu spät gesehen habe.) Aber ich wollte eine rekursive Golffunktion üben.Generiert rekursiv alle Kompositionen, indem alle möglichen endgültigen Zahlen generiert
j
und sich dann selbst anfragt,#-j
wo#
die Eingabe ist.quelle
Array
anstelle von einen Operator definierenTable
und dies vermeiden,Append
indem Sie eine Liste verwenden undApply
:±0={{}};±n_:=Join@@Array[{##,n-+##}&@@@±#&,n,0]
@@
das?f@@g[a,b]
zu ausf[a,b]
. Hier verwenden wir die Tatsache, dass eine Liste wie{ { {1,1,1}, {2,1} } , { {1,2} }, { {3} } }
unsichtbar Kopf hatList
; soJoin@@{ { {1,1,1}, {2,1} } , { {1,2} }, { {3} } }
wertet aus,Join@@List[ { {1,1,1}, {2,1} } , { {1,2} }, { {3} } ]
um zuJoin[ { {1,1,1}, {2,1} } , { {1,2} }, { {3} } ]
bewerten, um zu bewerten{ {1,1,1}, {2,1}, {1,2}, {3} }
.Retina , 32 Bytes
Die Anzahl der Bytes setzt die Kodierung nach ISO 8859-1 voraus.
Probieren Sie es online!
Erläuterung
Das funktioniert ähnlich wie bei meiner CJam-Antwort . Wir gehen eine Liste durch
N
und an jeder Position nehmen wir beide Zweige der binären Entscheidung a) erhöhen den letzten Wert oder b) beginnen einen neuen Wert bei 1.Bühne 1
Konvertieren Sie die Eingabe in Unary.
Stufe 2
Das
+
weist Retina an, diese Phase in einer Schleife auszuführen, bis sich der Ausgang nicht mehr ändert. Das%
weist es an, die Eingabe vor dem Anwenden der Bühne in Zeilen aufzuteilen und diese anschließend wieder zusammenzufügen. Durch das Setzen der%
nach dem+
, spaltet sich Retina nach jeder Iteration auf und kehrt wieder zurück. Eine Iteration der Stufe trifft eine dieser Entscheidungen, die ich erwähnt habe, und teilt dadurch die aktuelle Menge von Partitionen auf.Wie es tatsächlich funktioniert, stimmt es mit einem überein
1
(aber nur mit dem ersten, wie durch das1
vor dem Backtick angegeben) und ersetzt es durch!
(das wir als unäre Ziffer unserer Ausgabe verwenden), gefolgt von dem verbleibenden1
s in dieser Zeile (dies erhöht den letzten Wert). Dann wird in einer anderen Zeile (¶
) das Präfix der aktuellen Zeile gedruckt, gefolgt von,!
einem Trennzeichen, und der nächste Wert beginnt bei1
.Stufe 3
Dadurch werden die Läufe von
!
in Dezimalzahlen konvertiert, indem sie durch ihre Länge ersetzt werden.Stufe 4
Und schließlich stellen wir fest, dass wir doppelt so viele Zeilen generiert haben, wie wir wollten, und die Hälfte von ihnen beginnt mit einem
,
(die, bei denen wir ursprünglich die Entscheidung getroffen haben, zu teilen, obwohl es danach noch nichts zu teilen gab). Aus diesem Grund verwerfen wir alle Zeilen, die mit einem beginnen,
.quelle
Perl, 44 Bytes
Beinhaltet +3 für
-n
(Code wird verwendet$'
und$0
kann daher nicht als-e
Befehlszeile ausgeführt werden)Partition auf STDIN nummerieren:
partitions.pl
Wenn Sie keine zusätzlichen Leerzeichen am Ende einer Zeile und einen zusätzlichen Zeilenumbruch beachten, funktioniert diese 42-Byte-Lösung auch (ausgeführt als
perl -M5.010 partitions.pl
):quelle
Julia, 113 Bytes
Nicht rekursive Lösung
Erklärt:
[vcat([1 for _=i+1:N],sum([1 for _=N-i:N-1])) for i=1:N]
Erstellen Sie eine Reihe von Listen, die sich zu N addieren, deren Permutationen der Lösung ähneln (z. B. für N = 4: [[1,1,1,1], [1,1,2], [1,3], [4 ]])map(x->[permutations(x)...],)
Berechnen Sie alle Permutationenreduce(vcat,)
Kombiniere sie zu einer Liste von Listenunique()
Duplikate filternquelle
N
Eingaben vornehmen. Sie können eine Lambda-Funktion erstellen, indem SieN->
3 Byte voranstellen .f(N)=
, dass ich mich beim Kopieren verlaufen habe. Ich hatte es beim Zählen von BytesMATL , 15 Bytes
Probieren Sie es online!
Erläuterung
Bei gegebener Eingabe
n
berechnet dies die kartesische Potenz mit zunehmenden Exponentenk
von1
bisn
; undk
wählt für jeden Exponenten die Tupel aus, deren Summe der Eingabe entspricht.quelle
Lua
214203182 BytesUngelöste Version.
Es wurde ein verirrtes Leerzeichen gefunden und eine unnötige Variable entfernt, um 11 Byte zu sparen. Wie sich herausstellt, ist table.insert () byte-ineffizient
quelle
PHP, 125 Bytes
-4 Bytes für
print_r($r);
stattecho json_encode($r);
für die Ausgabeeine rekursive Lösung mit 250 Bytes
quelle
Prolog, 81 Bytes + 6 Bytes zum Aufrufen
Probieren Sie es online!
Rufen Sie mit an
[4]*L.
, wiederholen Sie mit,;
bis alle Lösungen präsentiert wurden.Alternativ, wenn wiederholtes Drücken
;
nicht in Ordnung ist (oder zur Byteanzahl hinzugefügt werden sollte), rufen Sie auf,bagof(L,[4]*L,M).
wodurch 17 Bytes für den Anruf hinzugefügt werden .quelle
J ,
3026 BytesArbeitet durch Teilen der Liste von unären n unter Verwendung der Binärwerte von 2 n .
Probieren Sie es online!
Erläuterung
quelle
Eigentlich
1716 BytesDiese Antwort basiert teilweise auf Luis Mendos MATL-Antwort . Golfvorschläge sind willkommen. Probieren Sie es online!
Ungolfing
quelle
Eigentlich
171615 BytesDies ist eine interessante Abzweigung von Martin Enders CJam-Antwort (die mit dem kartesischen Produkt), mit einem Unterschied in der Implementierung, den ich interessant fand. Wenn eine von Martins Zeichenfolgen mit einem Inkrement beginnt, verhindern die Fehler, dass diese Zeichenfolge ausgewertet wird. In Actually wird der Fehler unterdrückt und der String trotzdem ausgewertet. Dies führt dazu, dass die Kompositionen von jedem
k
im Bereich angegeben werden[1..n]
.Anstatt zu versuchen, die zusätzlichen Kompositionen zu entfernen, habe ich die
n-1
kartesische Potenz von"1u"
a"1"
an den Anfang jeder Saite angehängt . Dieser Trick gibt nur die Kompositionen vonn
. Es ist leider länger als Martins Antwort.Golfvorschläge sind willkommen. Probieren Sie es online!
Ungolfing
quelle