Weitere Informationen finden Sie in diesem Video . Unter A276523 finden Sie eine entsprechende Sequenz.
Das Mondrian Puzzle (für eine ganze Zahl n
) ist das folgende:
Passen Sie nicht kongruente Rechtecke in ein n*n
quadratisches Raster ein. Was ist der kleinstmögliche Unterschied zwischen dem größten und dem kleinsten Rechteck?
Denn 6
der optimale Unterschied für M(6)
ist5
und kann wie demonstriert werden:
___________
| |S|_______|
| | | L |
| |_|_______|
| | | |
| |_____|___|
|_|_________| (fig. I)
Das größte Rechteck (L) hat eine Fläche von 2 * 4 = 8
und das kleinste Rechteck (S) hat eine Fläche von 1 * 3 = 3
. Daher ist der Unterschied 8 - 3 = 5
.
Beachten Sie, dass derzeit keine optimalen Lösungen für n > 44
gefunden wurden.
Ihre Aufgabe ist es, ein Programm zu erstellen, das ein Mondrian-Gitter generiert, das eine (nicht optimale) Lösung mit einer Ganzzahl enthält n
.
Sie werden mit den Zahlen von 100 bis 150 getestet. Ihre Punktzahl für jeden Test ist die Differenz zwischen dem größten und dem kleinsten Rechteck. Ihre Gesamtpunktzahl ist die Summe Ihrer Punkte für alle Tests von 100 bis 150.
Sie müssen Ihre Ausgabe folgendermaßen präsentieren:
{number}
{grid}
Wo number
ist die Punktzahl (der Unterschied zwischen der größten und der kleinsten) und grid
ist entweder:
- Eine mehrzeilige Zeichenfolge oder
- Eine zweidimensionale Liste.
Das Gitter MUSS deutlich zeigen, wo ein Rechteck beginnt und endet.
Regeln:
- Ihr Programm muss in Ihre Antwort passen.
- Ihr Programm muss auf einem modernen Laptop innerhalb einer Stunde einen Wert für eine beliebige Zahl zwischen 100 und 150 ausgeben.
- Ihr Programm muss
n
jedes Mal, wenn es ausgeführt wird, dieselbe Lösung für eine Ganzzahl generieren . - Sie müssen einen Link zu den Ausgaben aller 51 Lösungen bereitstellen (mit Pastebin, Github Gist ... wirklich alles).
- Für Ihre Lösung müssen mindestens zwei Rechtecke im quadratischen Raster vorhanden sein.
quelle
Antworten:
Piet, 9625
(Es funktioniert endlich!)
Die Leute haben es verlangt, also hier ist es. Dies ist eine äußerst naive Lösung (im Wesentlichen die gleiche wie die losen oberen Schranken auf der OEIS-Seite): Sie unterteilt jedes Quadrat in nur zwei Rechtecke.
Diese Übersicht enthält die Details in zwei Dateien:
?
ist also die Eingabeaufforderung, unmittelbar gefolgt von der Ausgabebewertung und dann dem Raster.Erläuterung
Dieses Programm verwendet eine einzelne Nummer
N
als Eingabe. Wenn die Zahl ungerade ist, ist die Punktzahl die Zahl; Wenn gerade, ist die Punktzahl doppelt so hoch wie die Zahl.Nach der Ausgabe der Partitur wird der Rest der linken Seite des Programms damit verbracht, den Stapel mit fünf Losen der folgenden Informationen zu füllen:
N
)_
oder Leerzeichen)|
)Die rechte Seite des Programms nimmt jeden Satz von vier Werten und druckt diesen Teil des Rasters aus.
quelle
C 6108
Dies verwendet eine rekursive (wirklich iterative) Version der minimalen Lösung. Anstatt das Quadrat in zwei Rechtecke zu unterteilen, von denen eines etwas größer als die Hälfte der Fläche ist, wird es in N Rechtecke unterteilt. Das erste Rechteck ist also etwas größer als
1/N
die Gesamtfläche. Nehmen Sie dann den Rest, spaltet das Programm ein Rechteck ab, das etwas größer ist als1/(N-1)
der Rest und so weiter, bis es nur noch den Rest als letztes Rechteck annimmt. Die Rechtecke werden im Uhrzeigersinn vom Rest abgeschnitten, also zuerst oben, dann rechts usw.Da dies eine sehr direkte Methode anstelle der Suche in einem weiten Bereich ist, dauert es etwa 25 Sekunden (auf einem Himbeer-Pi), bis 74 Lösungen für die jeweilige Problemgruppe gefunden wurden.
Ich beabsichtige, diese Ergebnisse zu verwenden, um einen Suchalgorithmus für einen differenzierteren Ansatz besser zu informieren.
Die Ausgabe gibt die Punktzahl und sowohl eine (ASCII-) Zeichnung als auch Koordinaten für die Eckpunkte der Rechtecke an. Die Eckpunkte befinden sich im Uhrzeigersinn, beginnend mit der oberen linken Ecke des betreffenden Rechtecks.
Entwickelt mit gcc 4.9.2-10.
Ergebnisse unter https://github.com/JaySpencerAnderson/mondrian
Code:
quelle
C - 2982
Dieses Programm implementiert eine Suche durch eine breite Ergebnismenge. Der wichtige Teil bei der praktischen Umsetzung dieser Suche bestand darin, frühzeitig zu scheitern und / oder keine schlechten Wege einzuschlagen.
Dadurch wird eine Reihe von Rechtecken generiert, die für die Lösung berücksichtigt werden sollen. Die Menge der erzeugten Rechtecke vermeidet solche mit Abmessungen, die nicht nützlich wären. Wenn das Programm beispielsweise versucht, die Lösung für ein 128x128-Quadrat zu finden, das in 8 Rechtecke unterteilt ist, wird ein Rechteck mit 128x16 generiert. Es wird nicht generiert, dass 120x17 ist, da es keine Aussicht auf ein generierendes Rechteck gibt, das 8 breit ist, um die Lücke am Ende von 120 auszufüllen.
Die anfängliche Strategie zum Platzieren von Rechtecken besteht darin, sie auf der Innenseite des Umfangs des Quadrats zu platzieren (Buildedge-Funktion). Auf diese Weise erhält der Algorithmus an jeder Ecke eine ziemlich schnelle Rückmeldung, ob ein Problem mit der gewählten Sequenz vorliegt. Beim Platzieren von Rechtecken überwacht die Logik ständig, ob Lücken im Raum entstehen, die für ein Rechteck zu eng sind. Nachdem der Perimeter erfolgreich ausgefüllt wurde, wird die Strategie dahingehend geändert, dass versucht wird, den verbleibenden Platz mit den verbleibenden Rechtecken abzugleichen (Match-Funktion).
Eine andere Sache, die von Interesse sein könnte, ist, dass dies Transaktionen mit Rollback für die Stapel von Rechtecken implementiert.
Dieses Programm versucht nicht, die bestmögliche Anpassung zu finden. Es erhält ein Budget (64) und wird beendet, wenn es die erste Lösung findet. Wenn es keine Lösung findet, erhöhen wir das Budget (um 16) und versuchen es erneut. Die benötigte Zeit (auf einem Dell-Laptop mit einem I7-Prozessor) reichte von weit unter einer Minute bis zu 48 Minuten für 150 auf einer Seite (149 auf einer Seite dauerte weniger als 2 Minuten). Alle 51 Lösungen verwendeten 11 Rechtecke. Die Punktzahl der 51 Lösungen lag zwischen 41 und 78. Die Gründe, warum ich 11 Rechtecke verwendete, waren, dass die Punktzahl niedriger war als bei weniger Rechtecken und es so aussah, als würden 12 Rechtecke viel mehr als die zugewiesene Stunde in Anspruch nehmen.
Die Lösungen und der Code finden Sie unter https://github.com/JaySpencerAnderson/mondrian . Das sind die beiden my4 * -Dateien.
Übrigens, wenn Sie dies zu "my4" kompilieren und es wie folgt ausführen: "./my4 -h", wird es Ihnen Verwendung geben. Wenn Sie möchten, dass es funktioniert, versuchen Sie es mit "./my4 -l 50 -n 8". Wenn Sie "#if 0" in "#if 1" ändern, wird der verbleibende Platz auf dem Bildschirm gerendert. Wenn Sie dies ändern möchten, um die Rechtecke zu rendern, suchen Sie die Stelle, an der der Code "graph (space, side)" ausführt, und ändern Sie diese stattdessen in "graph (callstack, side)". Ich würde auch vorschlagen, das anfängliche Budget von 64 auf 32 zu ändern, wenn Sie mit Lösungen für Quadrate mit einer Breite von etwa 50 herumspielen möchten. Die Lösung für kleinere Quadrate hat eine bessere Punktzahl mit einem kleineren Budget.
Das folgende Programm ist funktionsfähig. Überprüfen Sie Github auf den vollständigen Code (mit Verwendung, Kommentaren usw.).
quelle