Gozinta-Ketten
(Inspiriert von Project Euler # 606 )
Eine Gozinta-Kette für n ist eine Folge, {1,a,b,...,n}
bei der jedes Element das nächste korrekt teilt. Zum Beispiel gibt es acht verschiedene Gozinta-Ketten für 12:
{1,12}, {1,2,12}, {1,2,4,12}, {1,2,6,12}, {1,3,12}, {1,3,6,12}, {1,4,12} and {1,6,12}.
Die Herausforderung
Schreiben Sie ein Programm oder eine Funktion, die eine positive Ganzzahl ( n > 1
) akzeptiert und alle eindeutigen Gozinta-Ketten für die angegebene Zahl ausgibt oder zurückgibt.
- Reihenfolge in den Ketten ist wichtig (aufsteigend), Reihenfolge der Ketten nicht.
- Wenn es keine Chance gibt, können Sie kein eingebautes System verwenden, das die Herausforderung löst.
- Das ist Code-Golf .
Bearbeiten: Entfernen 1
als mögliche Eingabe.
code-golf
sequence
arithmetic
Regenschirm
quelle
quelle
[[1]]
würde ich sagen, dass wenn[1,1]
ein Gozinta von1
dann[1,1,12]
ein Gozinta von12
so ist, wie es ist,[1,1,1,12]
und jetzt können wir nicht mehr "alle zurück ..."2|4
wird gelesen "zwei geht in vier" aka "zwei gozinta vier".Antworten:
Python 3 ,
6865 BytesEdit: -3 Bytes dank @notjagan
Probieren Sie es online!
Erläuterung
Jede Gozinta-Kette besteht aus der Nummer
x
am Ende der Kette mit mindestens einem Teiler links davon. Für jeden Divisork
vonx
den Ketten[1,...,k,x]
unterscheiden. Wir können daher für jeden Divisork
alle seine unterschiedlichen Gozinta-Ketten finden undx
an deren Ende anhängen , um alle unterschiedlichen Gozinta-Ketten mitk
direkt links von zu erhaltenx
. Dies erfolgt rekursiv , bisx = 1
wo[[1]]
zurückgegeben wird, da alle gozinta Ketten mit 1 beginnen, was bedeutet , die Rekursion haben die Talsohle erreicht.Der Code wird aufgrund des Verständnisses der Python-Liste so kurz, dass eine doppelte Iteration möglich ist. Dies bedeutet, dass die in gefundenen Werte
f(k)
für alle verschiedenen Teiler derselben Liste hinzugefügt werden könnenk
.quelle
Schale , 13 Bytes
Ein etwas anderer Ansatz als der von H.PWiz , wenn auch immer noch mit roher Gewalt. Probieren Sie es online!
Erläuterung
Die Grundidee ist, alle
[1,...,n]
Teilsequenzen zu verketten und das Ergebnis in Teillisten aufzuteilen, in denen jedes Element das nächste teilt. Von diesen behalten wir diejenigen, die mit beginnen1
, endenn
und keine Duplikate enthalten. Dies geschieht mit der eingebauten Funktion "rangify"…
. Dann bleibt es, Duplikate zu verwerfen.quelle
Gelee ,
98 BytesProbieren Sie es online!
Verwendet eine ähnliche Technik wie meine Japt-Antwort und läuft daher bei größeren Testfällen sehr schnell.
Wie es funktioniert
quelle
Mathematica, 77 Bytes
Bildet eine Stelle,
Graph
an der die ScheitelpunkteDivisors
der Eingabe#
sind und die Kanten die richtige Teilbarkeit darstellen, und findet dannAll
Pfade vom Scheitelpunkt1
zum Scheitelpunkt#
.quelle
Gelee , 12 Bytes
Ein monadischer Link, der eine Ganzzahl akzeptiert und eine Liste mit Ganzzahllisten zurückgibt.
Probieren Sie es online!
Wie?
Wir möchten, dass alle sortierten Listen eindeutiger Ganzzahlen zwischen eins und N so sind, dass die erste eine Eins ist, die letzte N ist und sich alle Paare teilen. Der Code erreicht diesen Filter, indem er überprüft, ob die paarweisen Teilungskriterien über die Potenzmenge des fraglichen Bereichs erfüllt sind, aber nur diejenigen auswählt, deren maximale inkrementelle Differenzsummen (die beide mit eins beginnen und mit N enden) eine Summe von inkrementellen Differenzen von N-1, andere haben weniger).
quelle
<slice>2<divisible>\<each>
: PƝ
anstelle von '2' für 11 Bytes verwenden .Japt , 17 Bytes
Online testen!
Seltsamerweise war das Generieren der Ausgabe als String viel einfacher als das Generieren als Array von Arrays ...
Erläuterung
quelle
¬
Trick fertig ! : p¬
ist einer der Gründe, warum ich eine Reihe von Funktionen implementiert habe, die im Grunde genommen "do X ohne Argumente oder Y mit wahrheitsgemäßen Argumenten" lauten: PMathematica, 60 Bytes
Verwendet die ohne Papiere Multi arg Form
Divisible
, woDivisible[n1,n2,...]
Renditen ,True
wennn2∣n1
,n3∣n2
und so weiter, und ausFalse
anderen Gründen . Wir nehmen die gesamteSubsets
ListeDivisors
der Eingaben#
und geben dann dieCases
der Form zurück{1,___,#}
,Divisible
dieTrue
für dieReverse
d-Folge von Teilern gilt.quelle
Divisible
ist es im Grunde genommen eine eingebaute Funktion, um eine Gozinta-Kette zu verifizieren?Haskell, 51 Bytes
Finden Sie rekursiv Gozinta-Ketten der richtigen Teiler und hängen Sie an
n
.Probieren Sie es online!
quelle
1
. Können1
Sie 10 Byte einsparen, indem Sie diesen Fall entfernen, da wir gemeinsam eine Ausnahme beschlossen haben?1
ist kein Sonderfall für diesen Algorithmus, sondern wird als Basisfall für die Rekursion benötigt. Die zweite definierende Gleichung kann für sich genommen nur die leere Liste zurückgeben.[[1]]
als Basis.Haskell (Lambdabot),
9285 BytesBenötigt Lambdabot Haskell da
guard
erfordertControl.Monad
importiert werden. Die Hauptfunktion ist eine anonyme Funktion, von der mir gesagt wurde, dass sie zulässig ist und ein paar Bytes abschneidet.Vielen Dank an Laikoni für das Speichern von sieben Bytes.
Erläuterung:
Monaden sind sehr praktisch.
Dies ist unsere rekursive Funktion, die die gesamte eigentliche Arbeit erledigt.
x
ist die Zahl, über die wir akkumulieren (das Produkt der Divisoren, die im Wert verbleiben), undy
ist die nächste Zahl, die wir versuchen sollten, darin zu dividieren.Wenn
x
gleich,y
dann sind wir mit der Rekursion fertig. Verwenden Sie es einfachx
als Ende der aktuellen Gozinta-Kette und senden Sie es zurück.Haskell Golf-Ismus für "True". Das heißt, dies ist der Standardfall.
Wir arbeiten jetzt in der Listenmonade. Innerhalb der Listenmonade haben wir die Möglichkeit, mehrere Entscheidungen gleichzeitig zu treffen. Dies ist sehr hilfreich, wenn Sie durch Erschöpfung "alles Mögliche" für etwas finden. In der
guard
Anweisung heißt es: "Betrachten Sie die folgende Auswahl nur, wenn eine Bedingung erfüllt ist." Berücksichtigen Sie in diesem Fall nur die folgende Auswahl, wenny
dividiert wirdx
.Wenn
y
sich teiltx
, haben wir die Wahly
, die Gozinta-Kette zu ergänzen. In diesem Fall rufen Sie rekursiv(#)
beginnendy = 2
mitx
gleich aufx / y
, da wir "herausrechnen" möchten, wasy
wir gerade zur Kette hinzugefügt haben. Unabhängig vom Ergebnis dieses rekursiven Aufrufs multiplizieren Sie dann die Werte, indem Sie die Gozinta-Kette offiziell ausklammerny
und ergänzeny
.Betrachten Sie auch die folgende Auswahl. Dies addiert einfach die beiden Listen, aber wir können uns das monadisch so vorstellen, als ob wir "wählen, ob wir dieses Ding oder dieses andere Ding machen".
Die andere Möglichkeit besteht darin, einfach weiter zu rekursieren und den Wert nicht zu verwenden
y
. Wenny
sich nicht teilt,x
ist dies die einzige Option. Wenn dies dery
Fall ist,x
wird diese Option ebenso wie die andere Option verwendet und die Ergebnisse werden kombiniert.Dies ist die Hauptfunktion von gozinta. Es beginnt die Rekursion, indem es
(#)
mit seinem Argument aufruft . A1
wird jeder gozinta-Kette vorangestellt, weil die(#)
Funktion niemals eine in die Ketten einfügt .quelle
mod x y==0
kann auf gekürzt werdenmod x y<1
. Da anonyme Funktionen erlaubt sind, kann Ihre Hauptfunktion als frei geschrieben werdenmap(1:).(#2)
.Haskell,
10710095 BytesVielleicht gibt es eine bessere Kündigungsbedingung (probiert so etwas wie
aber es ist länger). Die Überprüfung auf
1
erscheint sinnvoll, da das Löschen von Wiederholungen1
oder Duplikaten (nub
nicht inPrelude
) mehr Bytes umfasst.Probieren Sie es online aus.
quelle
(>>=h)
für(concatMap h)
u
...JavaScript (Firefox 30-57), 73 Byte
Günstigerweise
n%0<1
ist falsch.quelle
Gelee , 17 Bytes
Probieren Sie es online!
quelle
1
ist jedoch unerwartet. Ich habe es nicht geschafft, ein endgültiges Ergebnis für zu finden1
, aber ich nahm an, es war[[1]]
. Ich kann nicht sicher sagen, dass[1,1]
das falsch ist, außer dass alle anderen Ergebnisse aufsteigende Sequenzen sind. Gedanken?;€
mit;Q¥€
).Mathematica, 104 Bytes
quelle
FreeQ[...]
kann werdenAnd@@BlockMap[#∣#2&@@#&,#,2,1]
Developer
PartitionMap :: nlen: - Meldungstext nicht gefunden - >> `warum ist das so?BlockMap
Verwendet dieDeveloper`PartitionMap
Funktion intern. Da es sich jedoch um eine Entwicklerfunktion handelt, werden keine Fehlermeldungen angezeigt. Der Fehler wird durch die Listen mit 1 oder 0 Elementen verursacht, mit denen Sie keine 2-Partitionen erstellen können.Mathematica, 72 Bytes
Erläuterung
Finde alle Teiler der Eingabe.
Generieren Sie alle Untergruppen dieser Liste.
Wählen Sie alle Fälle aus, die dem Muster entsprechen ...
Beginnend mit 1 und endend mit
<input>
...und erfüllt die Bedingung ...
Das linke Element teilt das rechte Element für alle 2-Partitionen der Liste, Offset 1.
quelle
TI-BASIC, 76 Bytes
Erläuterung
Ich könnte weitere 5 Bytes einsparen, wenn es erlaubt ist, mit einem Fehler statt ordnungsgemäß zu beenden, indem die Ans> 1-Prüfung und die Schleifenbedingung entfernt werden. Aber ich bin nicht sicher, ob das erlaubt ist.
quelle
Mathematica
8677 BytesBrute Force nach Definition.
Ich wünschte, es gäbe eine kürzere Möglichkeit, einen paarweisen Vergleich von Elementen einer Liste durchzuführen.
Vielen Dank an @Jenny_mathy und @JungHwanMin für die Vorschläge zur Einsparung von 9 Bytes
quelle
FreeQ[#∣#2&@@@Partition[#,2,1],1>2]&]
(als zweites Argument) können Sie zu 82 BytesAnd@@BlockMap[#∣#2&@@#&,#,2,1]
Schale ,
1716 Bytes-1 Byte, danke an Zgarb
Probieren Sie es online!
quelle
50
den Eingang eingegeben und es ist abgelaufen. Was ist der Kern Ihres Ansatzes?o`:⁰:1
kann sein`Je1⁰
PHP
147141Bearbeitet, um einen redundanten Test zu entfernen
Erklärt:
15 Zeichen Boilerplate :(
Initialisieren Sie die Ergebnismenge auf,
[[1]]
da jede Kette mit 1 beginnt. Dies führt auch zur Unterstützung von 1 als Eingabe.Für jede Zahl von 2 bis
$i
werden wir jede Kette in unserer Menge um die aktuelle Zahl verlängern, wenn dies möglich ist. Fügen Sie dann die verlängerte Kette zu unserer Ergebnismenge hinzu.Filtern Sie unsere Zwischenketten heraus, die es nicht geschafft haben
$i
10 Zeichen Boilerplate :(
quelle
Mathematica
Die Antwort wird für weitere Anrufe zwischengespeichert.
quelle