Betrachten Sie ein Array A
von Länge n
. Das Array enthält nur positive ganze Zahlen. Zum Beispiel A = (1,1,2,2)
. Definieren wir f(A)
als die Summe aller nicht leeren zusammenhängenden Subarrays vonA
. In diesem Fall f(A) = {1,2,3,4,5,6}
. Die zu erzeugenden Schritte f(A)
sind wie folgt:
Die Subarrays von A
sind (1), (1), (2), (2), (1,1), (1,2), (2,2), (1,1,2), (1,2,2), (1,1,2,2)
. Ihre jeweiligen Summen sind 1,1,2,2,2,3,4,4,5,6
. Die Menge, die Sie aus dieser Liste erhalten, ist daher {1,2,3,4,5,6}
.
Aufgabe
Bei einer Menge von Summen S
in sortierter Reihenfolge, die nur positive ganze Zahlen und eine Arraylänge enthält n
, besteht Ihre Aufgabe darin, mindestens ein Array X
so auszugeben, dass f(X) = S
.
Zum Beispiel, wenn S = {1,2,3,5,6}
und n = 3
dann eine gültige Ausgabe ist X = (1,2,3)
.
Wenn es kein solches Array gibt, sollte X
Ihr Code einen konstanten Wert ausgeben.
Beispiele
Eingabe:, n=4, S = (1, 3, 4, 5, 6, 8, 9, 10, 13)
mögliche Ausgabe:X = (3, 5, 1, 4)
Eingabe:, n=6, S = (2, 3, 4, 5, 7, 8, 9, 10, 12, 14, 17, 22)
mögliche Ausgabe:X = (5, 3, 2, 2, 5, 5)
Eingabe:, n=6, S = (2, 4, 6, 8, 10, 12, 16)
mögliche Ausgabe:X = (4, 2, 2, 2, 2, 4)
Eingabe:, n=6, S = (1, 2, 3, 4, 6, 7, 8, 10, 14)
mögliche Ausgabe:X = (4, 2, 1, 1, 2, 4)
Input: n=10, S = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 14, 15, 16, 17, 18, 19, 20, 23, 24, 25)
möglicher Ausgang: X = (1, 1, 3, 1, 2, 1, 2, 5, 4, 5)
.
Input: n=15, S = (1, 2, 3, 4, 6, 7, 8, 9, 10, 11, 13, 14, 15, 16, 17, 18, 20, 21, 22, 23, 24, 25, 26, 27, 28, 30, 31)
möglicher Ausgang: X = (1, 2, 1, 3, 3, 1, 3, 3, 1, 3, 3, 1, 2, 1, 3)
.
Eingabe- und Ausgabeformat
Ihr Code kann Eingaben und Ausgaben in jedem leicht lesbaren Format annehmen, das Sie für bequem halten. Bitte zeigen Sie die Ausgabe des Tests jedoch an den Beispielen in der Frage.
Laufzeit
Sie müssen in der Lage sein, den Code für alle Beispiele in der Frage vollständig auszuführen. Es sollte im Prinzip für n
bis zu 1 korrekt sein, 15
aber Sie müssen nicht nachweisen, dass es für alle Eingaben schnell genug ist.
Antworten:
Schale , 20 Bytes
Probieren Sie es online!
Gibt eine Lösung oder eine leere Liste zurück, falls diese nicht vorhanden ist. Der letzte Testfall (
n=15
) endet mit TIO in 3,8 Sekunden.Erläuterung
Das Programm besteht aus zwei Teilen. Im ersten Teil (
¡
und rechts davon) konstruieren wir eine unendliche Liste, derenk
th-Element eine Liste ist, die alle Längenlistenk
enthält, deren Slice-Summen in sindS
. Wir tun dies induktiv, ausgehend von den 1-Element-Slices vonS
und bei jedem Schritt vor jedem ElementS
in jeder Liste und unter Beibehaltung derjenigen, deren Präfixsummen in sindS
. Im zweiten Teil (!
und links davon) nehmen wirn
das dritte Element der Liste, das Längenlistenn
enthält. Von diesen wählen wir die erste aus, deren Scheibensummen tatsächlich jedes Element von enthaltenS
.Ersetzen wir im Code zunächst
o
undȯ
(die zwei und drei Funktionen zu einer zusammensetzen) aus Gründen der Klarheit durch Klammern.Es gibt einige Teile, die näher erläutert werden müssen. In diesem Programm
⁰¹
verweisen beide hochgestellten Zeichen auf das erste ArgumentS
. Wennα
es sich jedoch um eine Funktion handelt,α¹
bedeutet dies "Anwendenα
aufS
" und⁰α
"S
An das zweite Argument vonα
" anschließen. Die Funktion¦
prüft, ob das erste Argument alle Elemente des zweiten enthält (Multiplizitäten werden gezählt). DiesS
sollte auch das zweite Argument sein.Im ersten Teil kann die verwendete Funktion
¡
als interpretiert werdenS(f~Λ€∫)(×:)¹
. Der KombinatorS
verhält sich soSαβγ -> (αγ)(βγ)
, das heißt, wir können ihn vereinfachen(f~Λ€∫¹)(×:¹)
. Der zweite Teil×:¹
wird "S
durch Voranstellen gemischt", und sein Ergebnis wird an den ersten Teil übergeben. Der erste Teilf~Λ€∫¹
funktioniert so. Die Funktionf
filtert eine Liste nach einer Bedingung, die in diesem Fall lautet~Λ€∫¹
. Es erhält eine Liste von ListenL
, so haben wir~Λ€∫¹L
. Der Kombinator~
verhält sich wie~αβγδε -> α(βδ)(γε)
folgt: Das erste Argument wird an übergebenβ
, das zweite anγ
, und die Ergebnisse werden mit kombiniertα
. Das heißt, wir habenΛ(€¹)(∫L)
. Der letzte Teil∫L
ist nur die kumulative Summe vonL
,€¹
ist eine Funktion, die die Mitgliedschaft einchecktS
,Λ
Nimmt eine Bedingung (hier€¹
) und eine Liste (hier∫L
) und prüft, ob alle Elemente diese erfüllen. Einfach ausgedrückt, filtern wir die Ergebnisse der Mischung danach, ob ihre kumulativen Summen alle in sindS
.quelle
Ruby , 135 Bytes
Probieren Sie es online!
Verwenden Sie eine Breitensuche. n = 10 funktioniert mit TIO, n = 15 dauert länger als eine Minute, funktioniert aber auf meinem Computer.
Rubin , 147 Bytes
Probieren Sie es online!
Optimierte Version, arbeitet mit TIO für n = 15 (~ 20 Sek.)
Tatsächlich ist dies der Beginn eines Non-Brute-Force-Ansatzes. Ich hoffe, jemand wird daran arbeiten und eine vollständige Lösung finden.
Erste Ideen:
Was uns zur nächsten Optimierung bringt:
Ruby , 175 Bytes
Probieren Sie es online!
~ 8,5 Sekunden bei TIO. Nicht schlecht...
... und so weiter (umzusetzen)
quelle
Haskell,
117111 Bytes6 Bytes gespart dank @nimi!
Probieren Sie es online!
f
r
i
n
s
Wenn
n
Null (Golf bisn<1
) ist, muss die Liste fertig sein, also prüfen wir, ob alle Werte gesehen wurden. Wenn nicht, geben wir eine leere Liste zurück, um anzugeben, dass keine Lösungen vorliegen. Anderenfalls geben wir eine Singleton-Liste zurück, die eine leere Liste enthält, der die ausgewählten Elemente vorangestellt werden. Dieser Fall hätte auch mit den zusätzlichen Gleichungen behandelt werden könnenWenn
n
nicht Null ist, kehren wir zurückDies ist die Liste von (1) Listen, aus denen das erste Element (2)
s
und der Rest (5) aus dem rekursiven Aufruf stammt, unter der Bedingung (4), dass alle neuen Summen vorhanden sinds
. Die neuen Summen werden in (3) berechnet - Notiz,t
die aus einer Singleton-Liste gezogen wird, ein hässlicher Golf-Hack für das, was in Haskell idiomatisch wärelet t=y:map(y+)i
. Der rekursive Aufruf (5) erhält als neuerr
Satz den alten ohne die Elemente, die in den neuen Summen erscheinent
.Die Hauptfunktion
&
ruft die Hilfsfunktion auf und sagt, dass wir noch alle Werte sehen müssen (r=s
) und dass es noch keine Summen gibt (i=[]
).Für sieben weitere Bytes können wir die Berechnung einschränken, um nur das erste Ergebnis (falls vorhanden) zu erhalten, das viel schneller ist und alle Testfälle in weniger als 2 Sekunden verarbeitet.
Probieren Sie es online! (Dies ist die erste Ergebnisvariante der alten Version)
quelle
map
, ich habe nur versucht ,<$>
aber das brauchte zusätzlichen Pars ... @Anush Ich habe keine Ahnung , für eine Polynomzeit LösungSauber , 177 Bytes
Probieren Sie es online!
Dauert auf meinem Computer für den
n=15
Testfall ungefähr 40 Sekunden , bei TIO tritt jedoch eine Zeitüberschreitung auf.Sauber , 297 Bytes
Probieren Sie es online!
Diese enthält einige Optimierungen, die von GB vorgenommen wurden , sowie einige meiner eigenen. Ich denke, einige von ihnen können allgemeiner gestaltet werden, daher füge ich eine Erklärung hinzu, sobald dies erledigt ist.
Auf meinem Computer dauert es ungefähr 10 Sekunden, auf TIO 40 Sekunden.
quelle
@mention
du hast morgen, wenn sie auf sind, leider keine Zeit heute.Python 3 , 177 Bytes
Probieren Sie es online!
(einige Zeilenumbrüche / Leerzeichen hinzugefügt, um zu vermeiden, dass Leser den Code scrollen müssen)
Ein direkter Port meiner Jelly-Antwort (mit einigen Änderungen, siehe Abschnitt "Anmerkung" unten)
Ergebnis des lokalen Laufs:
Ich habe gehört, dass
itertools
das ausführlich ist, aber meine bestecombinations
Implementierung ist noch ausführlicher:Hinweis .
a[p//n:p%n+1]
dauert etwa 2x länger, spart jedoch einige Bytes.combinations
Rückgabe eines Iterators ist dies speicherfreundlicher.quelle
Gelee , 35 Bytes
Probieren Sie es online!
Lokal ausführen: (n = 15 benötigt mehr als 1 GB RAM)
(Eigentlich habe ich die UTF8-codierte Version ausgeführt, die mehr als 35 Bytes benötigt, aber das Ergebnis ist trotzdem dasselbe.)
Diese Lösung verwendet Kurzschluss, um die Laufzeit zu reduzieren.
Ohne Kurzschluss dauert dieser Code ungefähr( | S| -2n - 2) ×( n36+ n2Logn2) Operationen, die ausgewertet werden ( 26-215 - 2) ×( 1536+ 152Log152) ≈5,79× 109 Aufgrund der Ineffizienz von Python und Jelly dauert es jedoch ewig, bis der Vorgang abgeschlossen ist. Dank des Kurzschlusses kann es viel früher beendet werden.
Erläuterung
Wir stellen fest, dass die Summe aller nicht leeren Präfixe in der Eingabe vorhanden ist und sich strikt erhöht. Wir können auch annehmen, dass das größte und zweitgrößte Element eine Präfixsumme ist.
Daher können wir alle Möglichkeiten zur Auswahl in Betracht ziehenn - 2 verschiedene Elemente von zuerst | S| -2 Elemente (es gibt ( | S| -2n - 2) solche Listen), berechnen die aufeinanderfolgenden Unterschiede, um die Elemente wiederzugewinnen; dann überprüfe, ob es naiv gültig ist (hol alles)n2 Subarrays, berechnen die Summe, eindeutig. Die Gesamtlänge der Subarrays beträgt ungefährn36 )
Ungetestet (sollte aber die gleiche Leistung haben)
Jelly , 32 Bytes
Probieren Sie es online!
Ineffizientere Version (ohne Kurzschluss):
Gelee , 27 Bytes
Probieren Sie es online!
Für den n = 15-Test werden bis zu 2 GB RAM benötigt und nicht nach ~ 37 Minuten beendet.
hinweis :
Ẇ§
kann durch ersetzt werdenÄÐƤẎ
. Es kann effizienter sein.quelle
APL (NARS), Zeichen 758, Bytes 1516
Die Funktion G in G x (mit Hilfe der H-Funktion) würde alle Permutationen von x finden. Die Funktion d in xdy ermittelt, ob das Array y nach dem Array exercise x einen booleschen Wert zurückgibt. Die Funktion F in x F y würde das Array r der Länge x zurückgeben, so dass ydr wahr ist (= 1) Ein wenig lang wie die Implementierung, aber es ist dieser, der alle Fälle im Test kürzer berechnet ... Der letzte Fall für n = 15 dauert es nur 20 sekunden ... ich muss sagen, dass nicht viele lösungen gefunden werden, es wird nur eine lösung (endlich scheint es so) in kürzerer zeit zurückgegeben (nicht erkundeter test für verschiedene eingaben ...) 16 + 39 + 42 + 8 + 11 + 11 + 18 + 24 + 24 + 54 + 11 + 12 + 7 + 45 + 79 + 69 + 12 + 38 + 26 + 72 + 79 + 27 + 15 + 6 + 13 (758)
quelle