Encuentre el área del rectángulo más pequeño para contener cuadrados de tamaños hasta n

19

Esta es una pregunta de secuencia del tipo habitual, como se aplica a la secuencia OEIS A038666 . Es decir, realice una de las siguientes acciones:

  • No acepte ninguna entrada o ninguna, y envíe A038666 hasta la muerte por calor del universo.
  • Aceptar un número entero positivo como entrada, y la salida de la º plazo de A038666 o sus primeros términos. (Si se utiliza - en lugar de -indexing, entonces por supuesto que también tiene a la salida de entrada.)nortenorte0 0110

El º período de A038666 es la menor área entre los rectángulos que contienen los cuadrados no superpuestas de tamaños si estás usando -indexing.norte1×1,2×2,n×norte1

Ejemplo:

El rectángulo de área más pequeña que puede contener cuadrados no superpuestos de tamaños a tiene dimensiones :1×14 4×4 47 7×5 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

Por lo tanto, ( -indexado).un(4 4)=7 7×5 5=351

Del mismo modo, el rectángulo de área mínima que contiene cuadrados no superpuestos de tamaños a tiene dimensiones , por lo que ( -indexado).1×117×17 39×46un(17)=39×46=17941

msh210
fuente

Respuestas:

10

JavaScript (ES6), 172 bytes

Sugerencia de versión más lenta pero más corta sugerida por @JonathanAllan (también guarda 4 bytes en la respuesta original):

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)

Pruébalo en línea!


Respuesta original,  209183178174  bytes

Devuelve el norte º término de la secuencia, 1-indexados.

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)

Pruébalo en línea!

Comentado

Función auxiliar

Primero definimos una función auxiliar S que invoca una función de devolución de llamada C para norte a 0 0 (ambos incluidos) y se detiene tan pronto como una llamada devuelve un valor verdadero.

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

Función principal

Comenzamos con UN=1 .

Para cada par (w,h) tal que w×h=UN , intentamos insertar todos los cuadrados de tamaño 1×1 a norte×norte (en realidad comenzando con el más grande) en el área correspondiente, de tal manera que No se superpongan entre sí.

Llevamos un registro de la lista de cuadrados con su posición (X,Y) y su ancho W en l[ ] .

O devolvemos UN si se encontró un acuerdo válido, o lo intentamos nuevamente con UN+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
Arnauld
fuente
2
Ahorre 6 * al no definir hy mover la prueba a%w<1a la cola del TIO de recursión . Por supuesto que es mucho más lento. (* al menos, ¡no soy un experto en JavaScript!)
Jonathan Allan
@ JonathanAllan Gracias. :) En realidad, me pregunto si a%w<1podría ser reemplazado por solo 1. Tendré que comprobarlo más tarde.
Arnauld
0

Python 2 (PyPy) , 250 236 bytes

-14 bytes gracias a las sugerencias de msh210 .

Emite el enésimo término indexado 1 de la secuencia.

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

Pruébalo en línea! Para n> 4, esto lleva mucho tiempo. He verificado el resultado hasta n = 7 localmente.

ovs
fuente
¿Le importaría incluir una explicación de cómo funciona? Además, me imagino que puede reducir bytes al sangrar un espacio a la vez en lugar de siete (para la segunda sangría). (De hecho, creo que tal vez las dos forlíneas pueden estar en una línea, y solo necesita sangrar una vez.)
msh210
1
@ msh210 los "7 espacios" son, de hecho, una pestaña, ya que en Python 2 puede sangrar primero con un espacio, luego con una pestaña. Desafortunadamente, poner los dos bucles for en una línea sería una sintaxis no válida.
ArBo
1
@ msh210 Encontré una forma diferente de combinarlos para bucles. Esos 7 espacios donde solo están en línea, gracias por la captura. Voy a tratar de escribir una explicación mañana
ovs