Ihre Aufgabe ist es, ein Programm oder eine Funktion zu schreiben, die ein bestimmtes Rechteck mit Primzahlen füllen kann. Das width
und height
des Rechtecks ist die Eingabe. Die Ausgabe muss eine Liste von height
Zeichenfolgen sein, die aus width
Ziffern und Leerzeichen bestehen. Jede horizontale (von links nach rechts) und vertikale (von oben nach unten) Ziffernfolge (durch Leerzeichen oder Rechteckrahmen begrenzt) der Länge 2 oder höher muss eine Primzahl sein. Jede Primzahl darf nur einmal verwendet werden. Führende Nullen sind nicht erlaubt. Eine nachfolgende neue Zeile ist in der Ausgabe optional.
Beispiel:
With input (5, 3) a valid output would be:
11 13
7 0
173
which scores 11, 13, 173, 17, 103 for a total of 5 points.
Ergebnis:
Die Größe des zu bewertenden Rechtecks ist 80, 60
. Jede horizontale oder vertikale Primzahl der Länge 2 oder mehr im Rechteck erhält einen Punkt. Die Antwort mit den meisten Punkten gewinnt. Bei einem Gleichstand gewinnt die früheste Antwort.
Regeln:
- Standardlücken sind verboten.
- Ihr Programm darf nicht für die
80, 60
Größe ausgelegt sein. Wenn ich vermute, dass eine Antwort für diese Größe optimiert ist, behalte ich mir das Recht vor, die Größe des Rechtecks auf zu ändern100, 100
. - Die verwendeten Primzahlen müssen echte Primzahlen sein (keine probabilistischen oder Pseudoprimes). Ihr Programm berechnet oder überprüft möglicherweise Zahlen zur Laufzeit oder lässt sie fest codieren. Die Methode zum Auffinden der Primzahlen ist kein wichtiger Teil der Herausforderung.
- Ihre Antwort sollte den Ausgabetext und Ihren Code enthalten. Wenn Ihr Programm zu groß ist, können Sie nur einen Kernalgorithmus-Code mit einer kleinen Erklärung einfügen.
Bearbeiten: Klargestellt, dass echte Primzahlen benötigt werden. Maximale Rechteckgröße hinzugefügt.
Bearbeiten 2: Klargestellt, welcher Code gepostet werden muss.
quelle
Antworten:
Clingo mit Python,
160016891740 PrimzahlenAnsatz
Ich erstelle ein riesiges Constraint-Zufriedenheitsproblem und löse es mit einem industrietauglichen Erfüllbarkeitslöser. Viel Magie steckt darin, relativ schnell Erfüllbarkeitslöser zu entwickeln (obwohl das Problem im Allgemeinen NP-vollständig ist), aber zum Glück muss ich mich nicht um diesen Teil kümmern.
Insbesondere lege ich die Positionen der Ziffern in einem Muster fest, das für ein dichtes Packen von 4- und 5-stelligen Zahlen mit gelegentlichen 2- und 3-stelligen Zahlen an der Grenze ausgelegt ist, und füge Einschränkungen hinzu, die besagen, dass jede Zahl eine unterschiedliche Primzahl ist. Die aktuelle Packung verwendet einen großen Teil aller vierstelligen Primzahlen (854 von 1061).
Code
Verwendung
Warnung: Bei 80 × 60 dauert dies ungefähr 8 Minuten und benötigt 3 GB Speicher. Möglicherweise möchten Sie mit kleineren Größen beginnen, wenn Sie nur möchten, dass es ausgeführt wird.
Ausgabe (80 × 60, 1740 Primzahlen):
quelle
Smalltalk, 1098 Primzahlen
Zuallererst eine schöne, schwierige Frage - wie der Mangel an bisher nicht trivialen Antworten zeigt.
Ich hatte eine Lösung, die bei der Arbeit kochte, musste aber auf das lange Wochenende warten, um Zeit zu haben, es etwas aufzuräumen. Trotzdem ist es ziemlich "schwer", entschuldigen Sie die Länge dieser Antwort - zum Glück ist dies keine Code-Golf-Frage. Es gab viele kleine Probleme auf dem Weg, aber ich bin mir ziemlich sicher, dass es jetzt fehlerfrei ist, obwohl es viel Raum für Verbesserungen und Feinabstimmungen gibt.
Sprache
Meine bevorzugte Sprache für diese Art von Dingen ist Smalltalk - das überlegene Debugging und die Fähigkeit, Code zu testen, übertrifft alles, was ich weiß. Außerdem können auch Nicht-Programmierer es lesen und die Grundlagen der Vorgänge verstehen. Ich habe den folgenden Code auf den interessanten Teil beschränkt, da ich dachte, der Ansatz und die Ergebnisse wären interessanter als der Kesselcode, aber hier wird eine Datei mit dem vollständigen Code eingefügt , wenn jemand ihn ausprobieren möchte (einfach speichern) als ein
*.st
und Datei in einem Dateibrowser in Pharo). Ich habe Pharo 4.0 verwendet, das FOSS ist und von pharo.org für Win / Mac / Linux heruntergeladen werden kann . Auch gerne den vollständigen Code hier einfügen, aber ich habe das "sollte den Ausgabetext und Ihren Code enthalten" als Vorschlag genommen - lass es mich wissen, wenn ich falsch liege.Ansatz
Also, dachte ich, was wäre, wenn Sie in der Mitte beginnen könnten, so viele lange Primzahlen wie möglich in die Schachtel stopfen und sich von dort aus nach außen arbeiten könnten? Beginnen wir mit einem
Box
Objekt, das eine Anzahlmatrix
von Zeichen enthält, undStuffer
versuchen es dann mit einem Objekt zu füllen, indem wirInsertion
für jeden Punkt in der Matrix und für jede Primzahl (beginnend mit den langen) die besten (ein anderes Objekt) finden. Pharo hat netteMatrix
undPoint
Klassen mit einer Reihe nützlicher Methoden (obwohl die Matrixmethode der Verwendung der Zeilennotation im Vergleich zur Verwendung der xy-Koordinaten von Punkten etwas verwirrend sein kann, wenn Sie nicht vorsichtig sind).Die grundlegenden Schritte meines Algorithmus sind:
Stuffer
Instanz für bestimmte Dimensionen.Konfigurierbar:
Für die unten stehende Matrix habe ich 80x60 verwendet, Primzahlen unter 20.000 (da die kombinierte Länge von diesen knapp unter 10.000 Zeichen liegt, dh das Maximum für eine gefüllte, jedoch ungültige Box von 100x100), und nach einigen Experimenten die folgende Bewertung für das
each
Einfügen :Wo
accidentalPrimes
werden die senkrechten Primzahlen "versehentlich" beim Einfügen zwischen benachbarten Primzahlen erzeugt undnumberOfOverlaps
wie viele Zeichen werden überschrieben (z. B. beim Hinzufügen eines3
am Ende des11
Einfügens113
) ? Ich hatte es anfangs mehr gewichtetaccidentalPrimes
, bekam aber ein paar mehr Primzahlen in der Box, wenn ich es so machte - nicht ganz sicher warum (zögern Sie nicht zu testen / zu optimieren).Ergebnis
Diese Matrix enthält 1098 Primzahlen, was einer "Belastung" von etwa 70% entspricht.
Dies sind die Primzahlen (
box primesUsed asSortedCollection printString
):Wie Sie sehen, werden einige der "zufälligen" Primzahlen ziemlich lang ... 20 Stellen für die längste. :-)
Einzelheiten
Um zu verstehen, wie es funktioniert, finden Sie hier die Ausgabe der ersten Schritte - erst Einfügen
19997
(wenn Sie in die Mitte der großen Matrix schauen, sehen Sie auch19997
dort) und dann in der Liste, wo im 5x5 Platz ist box (>
bedeutet, dass die Einfügung nach rechts geht,v
bedeutet, dass die Einfügung nach unten geht; alles in{}
wird versehentlich mit Strichen versehen:In der unmittelbar darüber liegenden Einfügung wird die Box zu einer 7x7-Box und wird mit dem 5x5-Inhalt gefüllt, bevor die nächste Einfügung erfolgt. Ich berechne auch die an dieser Stelle verwendeten Primzahlen neu, da einige durch Überschreiben "freigesetzt" werden (
11
wurde eingefügt, dann aber von überschrieben113
).Code
Hier sind die wichtigsten Teile des Codes:
Stuffer-Klasse
Klasse Seite
Instanzseite
Box-Klasse
Instanzseite
Sammlung
Oh, und der Einfachheit halber habe ich der Instanzseite von eine Methode hinzugefügt
Collection
:Laufen es
Um meinen Code auszuführen, muss ich nur den folgenden Code in einem Arbeitsbereich ("Spielplatz" in Pharo) oder in einem beliebigen Textbereich auswählen und im Kontextmenü "Ausführen":
Der Rest des Codes ist relativ langweilig.
Wie gesagt, Raum für Verbesserungen, aber bei 80x60 dauert jeder Durchlauf mehr als 3 Minuten auf meinem Computer. Klar, Leistung war nicht mein Anliegen, aber es gibt eine Menge Primzahlen herumfliegen. Das war sicher eine interessante Herausforderung. :-)
quelle
Javascript, Punktzahl 659
Mit ziemlicher Sicherheit nicht optimal.
Ergebnisse für 30x30:
Und für den 60x60 Fall:
quelle