Wenn eine Zahl n> 77 gegeben ist , schreiben Sie ein Programm oder eine Funktion, die eine Menge eindeutiger positiver Ganzzahlen findet, so dass die Summe der Menge n und die Summe der Kehrwerte der Menge 1 entspricht.
Beispiel für 80:
80 = 2 + 4 + 10 + 15 + 21 + 28 ⟶ 1/2 + 1/4 + 1/10 + 1/15 + 1/21 + 1/28 = 1
Ihr Programm oder Ihre Funktion muss (theoretisch) für n <2 32 funktionieren und ist nicht für Gleitkomma-Rundungsfehler entschuldigt. Beachten Sie, dass es für alle n> 77 Lösungen gibt .
Kürzester Code in Bytes gewinnt.
Es gibt einen Bonus-Anreiz: Ich werde der kleinsten Lösung, die für jedes n funktioniert und log (n) ausführt, eine Prämie gewähren . Für kleine n muss es schnell sein (nach meinem Ermessen bestimmt). Ja, das ist möglich.
O(log n)
Algorithmus verrät .Antworten:
Mathematica, 54 Bytes
Ungefähr so ineffizient wie es nur geht, aber es löst sich
n = 78
in ungefähr 9 Sekunden.Das Ergebnis wird als Liste in einer Singleton-Liste zurückgegeben, z. B .:
quelle
Python 3,
73061995 BytesDiese Lösung läuft in log (n) Komplexität (soweit ich das beurteilen kann).
Sie können testen, dass
f(2**32 - 1)
fast sofort ausgeführt wirdIch habe dieses Papier für eine Berechnungsmethode verwendet. Mit dieser Methode gibt es einen massiven Datenblock für die vorbestimmten Werte für n von 78 bis 334 ohne die geraden Zahlen nach 168. Ich wollte diese Daten in etwas Kleines verwandeln und kannte daher keine guten Komprimierungsalgorithmen machte meine eigene.
Ich habe es so komprimiert, dass eine Liste mit Regeln zum Ersetzen von Zeichenfolgen erstellt wurde. Ich habe eine Methode entwickelt, bei der die Zeichenfolge-Ersetzungsregel gefunden wurde, die den größten Teil des Inhalts unter Berücksichtigung der Definition der Regel reduziert. Ich habe dies dann rekursiv angewendet, bis ich keine Regeln mehr erstellen konnte (ich habe die Zeichen gz und AZ verwendet). Die Zeichenfolge, durch die ich ersetzen wollte, war eine durch Kommas getrennte Liste der Hexadezimalwerte für jede der Zahlen. Im Nachhinein mag es nicht die klügste Wahl gewesen sein, sie in ihre Hex-Werte umzuwandeln. Es wäre wahrscheinlich kürzer, sie in Dezimalzahlen zu belassen, da Hex nur für die 3-stelligen Zahlen speichern würde, aber eine 0 für einstellige Zahlen hinzufügen würde.
In der Zeile, in der ich c setze, sehen Sie die Liste der Ersetzungsregeln und den Text, in dem sie ausgeführt werden. Die Regeln müssen auch in umgekehrter Reihenfolge angewendet werden, da einige Regeln Zeichen enthalten, die aus anderen Regeln erstellt wurden.
Es gibt auch zahlreiche Stellen in diesem Code, an denen ich möglicherweise die Syntax einschränken könnte, z. B. die Liste der Listen in eine einzige Liste umzuwandeln und dann mit einer anderen Methode auf die Regeln zuzugreifen, durch die der Text ersetzt wird
quelle
n=218
Ausgänge[2]
ist das zu erwarten ??Haskell, 93 Bytes
Schrecklich langsam 1, aber es läuft in konstantem Speicher. Triviale Lösung: Überprüfen Sie alle Untersequenzen von
[2..n]
auf Summe und Summe der Reziprozitäten.Die Rückgabe aller Lösungen anstelle einer Lösung ist 3 Byte kürzer: Entfernen Sie einfach die
!!0
(Achtung: Die Laufzeit bleibt immer außerhalb der Diagramme).1 Die Laufzeit hängt davon ab, wie früh das Ergebnis in der Liste der Teilsequenzen erscheint. Haskells Faulheit stoppt die Suche, wenn die erste Übereinstimmung gefunden wird. Beim Kompilieren läuft
p 89
(result[3,4,6,9,18,21,28]
:) auf meinem (4 Jahre alten) Laptop in 35s. Andere Werte, auch kleinere, können Stunden dauern.quelle
Julia, 77 Bytes
Dies ist eine ineffiziente Lambda-Funktion, die eine Ganzzahl akzeptiert und ein Ganzzahl-Array zurückgibt. Um es aufzurufen, weisen Sie es einer Variablen zu.
Wir bekommen die Partitionen der ganzen Zahl mit
partitions
. Anschließend filtern wir die Partitionsmenge nur nach Partitionen mit eindeutigen Elementen, deren Reziprokwerte sich zu 1 summieren. Um sicherzustellen, dass kein Rundungsfehler auftritt, verwenden wir JuliasRational
Typ, um die Reziprokwerte zu erstellen .filter
Gibt einen Iterator zurück, also müssen wircollect
ihn in ein Array einfügen. Dies gibt uns ein Array von Arrays (mit nur einem einzigen Element), so dass wir die erste Verwendung erhalten können[1]
.Wenn ich ineffizient sage, meine ich das auch so. Das Ausführen dieses Befehls für n = 80 dauert auf meinem Computer 39,113 Sekunden und weist 13,759 GB Speicher zu.
quelle