Suchen Sie den Bereich des kleinsten Rechtecks, der Quadrate mit einer Größe von bis zu n enthält


19

Dies ist eine Sequenzfrage des üblichen Typs, wie sie auf die OEIS-Sequenz A038666 angewendet wird . Führen Sie also einen der folgenden Schritte aus:

  • Akzeptiere keine oder irgendeine Eingabe und gib A038666 aus, bis die Hitze des Universums stirbt.
  • Akzeptieren Sie eine positive Ganzzahl als Eingabe und geben Sie den n ten Term von A038666 oder seine ersten n Terme aus. (Wenn Sie 0 anstelle von 1 verwenden, müssen Sie natürlich auch 1bei der 0Eingabe ausgeben .)

Der n te Term von A038666 ist der kleinste Bereich unter den Rechtecken, die nicht überlappende Quadrate der Größen 1×1,2×2,n×n wenn Sie die 1 Indexierung verwenden.

Beispiel:

Das kleinste Rechteck, das nicht überlappende Quadrate der Größe 1×1 bis 4×4 hat die Abmessungen 7×5 :

4 4 4 4 3 3 3
4 4 4 4 3 3 3
4 4 4 4 3 3 3
4 4 4 4 2 2 1
x x x x 2 2 x

Daher ist ein(4)=7×5=35 ( 1 indiziert).

In ähnlicher Weise hat das kleinste Rechteck, das nicht überlappende Quadrate der Größen 1×1 bis 17×17 enthält, die Abmessungen 39×46 , so dass ein(17)=39×46=1794 ( 1 indiziert) ist.

Antworten:


10

JavaScript (ES6), 172 Byte

Langsamerer, aber kürzerer Versionsvorschlag von @JonathanAllan (außerdem 4 Byte in der ursprünglichen Antwort einsparen):

f=(n,A,S=(n,c)=>n>=0?c(n)||S(n-1,c):0)=>S(A,w=>(F=(l,n)=>n?S(w-n,x=>S(A/w-n,y=>l.some(([X,Y,W])=>X<x+n&X+W>x&Y<y+n&Y+W>y)?0:F([...l,[x,y,n]],n-1))):A%w<1)([],n))?A:f(n,-~A)

Probieren Sie es online!


Ursprüngliche Antwort,  209 183 178  174 Bytes

Gibt den N ten Term der Sequenz zurück, der 1-indiziert ist.

f=(n,A,S=(n,c)=>n>=0?c(n)||S(n-1,c):0)=>S(A,w=>A%w?0:(F=(l,n)=>n?S(w-n,x=>S(A/w-n,y=>l.some(([X,Y,W])=>X<x+n&X+W>x&Y<y+n&Y+W>y)?0:F([...l,[x,y,n]],n-1))):1)([],n))?A:f(n,-~A)

Probieren Sie es online!

Kommentiert

Hilfsfunktion

Wir definieren zuerst eine Hilfsfunktion S die eine Rückruffunktion c für n bis 0 (beide eingeschlossen) aufruft und stoppt, sobald ein Aufruf einen Wahrheitswert zurückgibt.

S = (n, c) =>               // n = integer, c = callback function
  n >= 0 ?                  // if n is greater than or equal to 0:
    c(n) ||                 //   invoke c with n; stop if it's truthy
    S(n - 1, c)             //   or go on with n - 1 if it's falsy
  :                         // else:
    0                       //   stop recursion and return 0

Hauptfunktion

Wir beginnen mit EIN=1 .

(w,h)w×h=EIN1×1n×n in dem entsprechenden Bereich (tatsächlich mit dem größten beginnend), in eine Weise, dass sie nicht überlappen.

(X,Y.)Wl[ ] .

EINEIN+1

f = ( n,                    // n = input
      A ) =>                // A = candidate area (initially undefined)
S(A, w =>                   // for w = A to w = 0:
  A % w ?                   //   if w is not a divisor of A:
    0                       //     do nothing
  : (                       //   else:
    F = (l, n) =>           //     F = recursive function taking a list l[] and a size n
      n ?                   //       if n is not equal to 0:
        S(w - n, x =>       //         for x = w - n to x = 0
          S(A / w - n, y => //           for y = A / w - n to y = 0:
            l.some(         //             for each square in l[]
            ([X, Y, W]) =>  //             located at (X, Y) and of width W:
              X < x + n &   //               test whether this square is overlapping
              X + W > x &   //               with the new square of width n that we're
              Y < y + n &   //               trying to insert at (x, y)
              Y + W > y     //
            ) ?             //             if some existing square does overlap:
              0             //               abort
            :               //             else:
              F([ ...l,     //               recursive call to F:
                  [x, y, n] //                 append the new square to l[]
                ],          //
                n - 1       //                 and decrement n
              )             //               end of recursive call
          )                 //           end of iteration over y
        )                   //         end of iteration over x
      :                     //       else (n = 0):
        1                   //         success: stop recursion and return 1
    )([], n)                //     initial call to F with an empty list of squares
) ?                         // end of iteration over w; if it was successful:
  A                         //   return A
:                           // else:
  f(n, -~A)                 //   try again with A + 1

2
Sparen Sie 6 *, indem Sie hden Test für nicht definieren und a%w<1an das Ende der Rekursions- TIO verschieben . Natürlich ist es viel langsamer. (* zumindest - ich bin kein JavaScript-Experte!)
Jonathan Allan

@ JonathanAllan Danke. :) Eigentlich frage ich mich, ob a%w<1mit nur ersetzt werden könnte 1. Ich muss das später noch einmal überprüfen.
Arnauld

0

Python 2 (PyPy) , 250 236 Byte

-14 Bytes dank der Vorschläge von msh210 .

Gibt den 1-indizierten n-ten Term der Sequenz aus.

n=input()
r=range
k=n*-~n*(n-~n)/6
m=k*k
for Q in r(m):
 P={0}
 for X in r(n,0,-1):P|=([x for x in[{(x+a,y+b)for a in r(X)for b in r(X)}for x in r(Q%k-X+1)for y in r(Q/k-X+1)]if not x&P]+[{0}])[0]
 if len(P)>k:m=min(Q%k*(Q/k),m)
print m

Probieren Sie es online! Für n> 4 nimmt dies viel Zeit in Anspruch. Ich habe das Ergebnis lokal auf n = 7 überprüft.


Würde es Ihnen etwas ausmachen, eine Erklärung der Funktionsweise beizufügen? Ich stelle mir auch vor, Sie können Bytes rasieren, indem Sie statt sieben Leerzeichen nacheinander einrücken (für den zweiten Einzug). (Tatsächlich denke ich, dass sich die beiden forZeilen möglicherweise in einer Zeile befinden und Sie nur einmal
einrücken

1
@ msh210 Die "7 Leerzeichen" sind in der Tat ein Tabulator, da Sie in Python 2 zuerst mit einem Leerzeichen und dann mit einem Tabulator einrücken können. Die beiden for-Schleifen in eine Zeile zu setzen, wäre leider eine ungültige Syntax.
ArBo

1
@ msh210 Ich habe einen anderen Weg gefunden, diese for-Schleifen zu kombinieren. Diese 7 Felder waren nur online, danke für den Fang. Ich werde versuchen , eine Erklärung morgen zu schreiben
ovs
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.