Trouvez l'aire du plus petit rectangle pour contenir des carrés de tailles jusqu'à n


19

Il s'agit d'une question de séquence du type habituel, telle qu'elle est appliquée à la séquence OEIS A038666 . Autrement dit, effectuez l'une des opérations suivantes:

  • N'acceptez aucune ou aucune entrée, et sortez A038666 jusqu'à la mort thermique de l'univers.
  • Acceptez un entier positif en entrée et sortez le n ème terme de A038666 ou ses n premiers termes. (Si vous utilisez0 - au lieu de1 indexation, alors bien sûr, vous devez également sortir1en0entrée.)

Le n ème terme de A038666 est la plus petite aire parmi les rectangles qui contiennent des carrés non superposés de tailles 1×1,2×2,n×n si vous utilisez l'indexation1 .

Exemple:

Le rectangle de plus petite surface pouvant contenir des carrés non superposés de tailles 1×1 à 4×4 a des dimensions 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

Par conséquent, a(4)=7×5=35 ( 1 indexé).

De même, le rectangle de moindre surface contenant des carrés non superposés de tailles 1×1 à 17×17 a des dimensions 39×46 , donc a(17)=39×46=1794 ( 1 indexé).

Réponses:


10

JavaScript (ES6), 172 octets

Suggestion de version plus lente mais plus courte suggérée par @JonathanAllan (économisant également 4 octets dans la réponse d'origine):

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)

Essayez-le en ligne!


Réponse originale,  209 183 178  174 174 octets

Renvoie le N ème terme de la séquence, indexé sur 1.

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)

Essayez-le en ligne!

Commenté

Fonction d'assistance

Nous définissons d'abord une fonction d'assistance S qui appelle une fonction de rappel c pour n à 0 (toutes deux incluses) et s'arrête dès qu'un appel renvoie une valeur véridique.

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

Fonction principale

Nous commençons avec A=1 .

(w,h)w×h=A1×1n×n (en fait commençant par le plus grand) dans la zone correspondante, de telle manière qu'ils ne se chevauchent pas.

(X,Y)Wl[ ]

AA+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
Économisez 6 * en ne définissant pas het en ne déplaçant pas le test a%w<1vers la fin du TIO de récursivité . Bien sûr, c'est beaucoup plus lent. (* au moins - je ne suis pas un expert JavaScript!)
Jonathan Allan

@JonathanAllan Merci. :) En fait, je me demande si a%w<1pourrait être remplacé par juste 1. Je vais devoir vérifier cela plus tard.
Arnauld

0

Python 2 (PyPy) , 250 236 octets

-14 octets grâce aux suggestions de msh210 .

Génère le nième terme indexé 1 de la séquence.

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

Essayez-le en ligne! Pour n> 4, cela prend beaucoup de temps. J'ai vérifié le résultat jusqu'à n = 7 localement.


Pourriez-vous inclure une explication de son fonctionnement? En outre, j'imagine que vous pouvez raser les octets en indentant un espace à la fois au lieu de sept (pour la deuxième indentation). (En fait, je pense que peut-être les deux forlignes peuvent être sur une seule ligne, et vous n'avez besoin de mettre en retrait qu'une seule fois.)
msh210

1
@ msh210 les "7 espaces" sont en fait un onglet, comme en Python 2 vous pouvez d'abord mettre en retrait avec un espace, puis avec un onglet. Mettre les deux boucles for sur une seule ligne serait malheureusement une syntaxe invalide.
ArBo

1
@ msh210 J'ai trouvé une façon différente de combiner celles des boucles. Ces 7 espaces étaient uniquement en ligne, merci pour la capture. J'essaierai d'écrire une explication demain
ovs
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.