Trova l'area del rettangolo più piccolo per contenere quadrati di dimensioni fino a n


19

Questa è una domanda di sequenza del solito tipo, applicata alla sequenza OEIS A038666 . Cioè, effettuate una delle seguenti operazioni:

  • Accettate nessun input o nessun input e output A038666 fino alla morte per calore dell'universo.
  • Accettare un intero positivo come input e output n esimo termine A038666 o suoi primi termini. (Se si utilizza 0 - anziché 1 -indexing, ovviamente è necessario eseguire l'output anche in input.)n0110

Il n esimo termine della A038666 è la zona meno tra i rettangoli che contengono quadrati non sovrapposti di dimensioni 1×1,2×2,n×n se si sta utilizzando 1 -indexing.

Esempio:

Il rettangolo dell'area più piccola che può contenere quadrati non sovrapposti di dimensioni da 1×1 a 4×4 ha dimensioni 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

Pertanto, a(4)=7×5=35 ( 1 indicizzato).

Allo stesso modo, il rettangolo di area minima contenente quadrati non sovrapposti di dimensioni da 1×1 a 17×17 ha dimensioni 39×46 , quindi a(17)=39×46=1794 ( 1 indicizzato).

Risposte:


10

JavaScript (ES6), 172 byte

Suggerimento versione più lenta ma più breve suggerito da @JonathanAllan (salvando anche 4 byte nella risposta originale):

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)

Provalo online!


Risposta originale,  209 183 178  174 byte

Restituisce il N ° termine della successione, 1-indicizzati.

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)

Provalo online!

Commentate

Funzione di aiuto

Definiamo innanzitutto una funzione di supporto S che richiama una funzione di richiamata c da n a 0 (entrambi inclusi) e si interrompe non appena una chiamata restituisce un valore di verità.

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

Funzione principale

Iniziamo con UN=1 .

(w,h)w×h=UN1×1n×n

(X,Y)Wl[ ]

UNUN+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
Risparmia 6 * non definendo he spostando il test per a%w<1la coda del TIO ricorsione . Certo è molto più lento. (* almeno - non sono un esperto JavaScript!)
Jonathan Allan

@JonathanAllan Grazie. :) In realtà, mi chiedo se a%w<1potrebbe essere sostituito con solo 1. Dovrò ricontrollarlo più tardi.
Arnauld

0

Python 2 (PyPy) , 250 236 byte

-14 byte grazie ai suggerimenti di msh210 .

Emette l'ennesimo termine indicizzato della sequenza.

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

Provalo online! Per n> 4, ciò richiede molto tempo. Ho verificato il risultato fino a n = 7 localmente.


Ti dispiacerebbe includere una spiegazione di come funziona? Inoltre, immagino che tu possa radere byte indentando uno spazio alla volta anziché sette (per il secondo rientro). (In effetti, penso che forse le due forrighe possano essere su una riga e devi solo rientrare una volta.)
msh210

1
@ msh210 i "7 spazi" sono in realtà una scheda, poiché in Python 2 puoi rientrare prima con uno spazio, poi con una scheda. Mettere i due per i loop su una riga sarebbe purtroppo una sintassi non valida.
ArBo

1
@ msh210 Ho trovato un modo diverso di combinare quelli per i loop. Quei 7 spazi erano solo in linea, grazie per la cattura. Proverò a scrivere una spiegazione domani
ovs
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.