Das Einheitsquadrat kacheln

8

Hintergrund

Durch Erweitern und Löschen von Begriffen kann die folgende Identität leicht angezeigt werden:

Geben Sie hier die Bildbeschreibung ein

Es ist jedoch ein offenes Problem, ob alle 1 / n-mal-1 / (n + 1) Rechtecke das Einheitsquadrat kacheln können.

Die Aufgabe

Ihr Programm sollte auf bequeme Weise eine positive ganze Zahl N als Eingabe verwenden und alle 1 / n-mal-1 / (n + 1) offenen Rechtecke mit n zwischen 1 und N einschließlich in das Einheitsquadrat packen, sodass sich keine zwei überlappen .

Für jedes Rechteck müssen Sie die folgenden Ganzzahlen der Reihe nach generieren:

  • 1, wenn die horizontalen Kanten länger als die vertikalen Kanten sind, sonst 0
  • Der Zähler und Nenner der x-Koordinate der unteren linken Ecke
  • Der Zähler und der Nenner der y-Koordinate der unteren linken Ecke

Beachten Sie, dass wir das Einheitsquadrat als (0, 1) x (0, 1)x-Werte von links nach rechts und y-Werte von unten nach oben annehmen .

Die endgültige erwartete Ausgabe ist die Verkettung dieser Ganzzahlen für jedes Rechteck in der Reihenfolge der Erhöhung von n in einem beliebigen geeigneten Format (z. B. gedruckt auf stdout oder als von einer Funktion zurückgegebene Liste).

Beispiel für Ein- und Ausgabe

Eingang:

3

Ausgabe:

0 0 1 0 1 1 1 2 0 1 1 1 2 1 3

Dies wird wie folgt analysiert:

0 (0/1, 0/1)  1 (1/2, 0/1)  1 (1/2, 1/3)

Wertung

Dies ist eine Code-Golf-Herausforderung, daher gewinnt die Antwort mit den wenigsten Bytes. Ihr Algorithmus sollte jedoch auch einigermaßen effizient sein. Es sollte in der Lage sein, N<=100in insgesamt etwa 10 Minuten für alle zu laufen .

Ihre Lösung muss für alle gültige Lösungen liefern N<=100, aber nachweislich vollständige Algorithmen sind auch dann willkommen, wenn sie nicht die kürzesten sind.

user1502040
quelle
Gibt es eine Obergrenze für den größten Wert von $ N $, für den unser Algorithmus garantiert funktionieren muss, da dies ein offenes Problem ist?
Greg Martin
@ GregMartin Sie sollten Ihr Programm für N von 1 bis 20 erfolgreich ausführen. Brownie-Punkte, wenn Ihr Algorithmus nachweislich entweder erfolgreich ist oder die Vermutung widerlegt.
user1502040
Für N ≤ 20 kann die Ausgabe einfach fest codiert werden ... ist es Ihre Absicht, dies zuzulassen? Es gibt einen einfachen veröffentlichten Algorithmus, der mindestens N = 1.000.000.000 erlaubt ....
Greg Martin
OK, ich habe den Schwellenwert von 20 auf 100 geändert.
user1502040
Oh, meine Güte. Ich habe noch keine Summe bis unendlich gelernt, daher verstehe ich das überhaupt nicht.
Matthew Roh

Antworten:

2

Haskell, 263 262 Bytes

import Data.Ratio;f m=let{(#)n z|n>m=[[]]|True=[a:y|(a,j)<-[((o,x,y),[c|c<-(u&w,h-v,x,g):(w-u,h&v,a,y):z,c/=b])|b@(w,h,x,y)<-z,(o,u,v)<-[(o,1%(n+1-o),1%(n+o))|o<-[0,1]],(a,g)<-[(x+u,y+v)|u<=w,v<=h],let(&)p q|w>h=p|True=q],y<-(n+1)#j]}in(1#[(1%1,1%1,0%1,0%1)])!!0

Dies folgt dem in Paulhus 1997, Ein Algorithmus zum Packen von Quadraten , doi: 10.1006 / jcta.1997.2836 beschriebenen Algorithmus . Die wichtigste Beobachtung in der Arbeit, die empirisch, wenn nicht theoretisch verifiziert wird, ist, dass der Bereich, der nach dem Platzieren eines Rechtecks ​​in einer Box übrig bleibt, in zwei Unterboxen aufgeteilt werden kann, deren Füllung dann wiederum als unabhängig angesehen werden kann.

Anstatt das Unterfeld mit der kleinsten Breite zu finden, in das das nächste Rechteck passt, führt der Code eine Suche über alle möglichen Unterfelder durch. in der Praxis bedeutet dies keine nennenswerte Verlangsamung für n <100.

Die Ausgabe erfolgt in Form einer Liste von Einträgen als Tupel, wobei die Bruchmarkierung %noch enthalten ist. Die Ganzzahlen in der formatierten Ausgabe sind in der gewünschten Reihenfolge, aber genau genommen wäre eine Nachbearbeitung erforderlich, um nur die Liste der Ganzzahlen zu erstellen.

Probelauf:

*Main> f 5 (0,0 % 1,0 % 1),(0,1 % 2,0 % 1),(0,1 % 2,1 % 2),(0,3 % 4,1 % 2),(1,1 % 2,5 % 6)

Bearbeiten: Ein fehlerhaftes Leerzeichen nach a wurde entfernt let.

halfflat
quelle