N boyutuna kadar kareler içeren en küçük dikdörtgenin alanını bulun


19

Bu, OEIS sekansı A038666'ya uygulandığı haliyle, normal tipte bir sekans sorusudur . Yani, aşağıdakilerden birini yapın:

  • Hiçbir girişi veya herhangi bir girişi kabul etmeyin ve evrenin ısı ölümüne kadar A038666 çıktısını alın.
  • Pozitif giriş olarak bir tam sayı, ve çıkış kabul n A038666 ya da ilk th terimi n açısından. (Kullanılıyorsa 0 - yerine 1 -Dizin ardından elbette ki de çıkışa sahip 1üzerindeki 0girdi.)

n A038666 inci dönem boyutlarının örtüşmeyen kareler içeriyor dikdörtgenler arasında en az alandır 1×1,2×2,n×n kullandığınız takdirde 1 -Dizin.

Misal:

1×1 ila 4×4 boyutlarında üst üste binmeyen kareler içerebilen en küçük alanlı dikdörtgen 7×5 boyutlarına sahiptir :

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

Bu nedenle, a(4)=7×5=35 ( 1 indeksli).

Benzer şekilde, 1×1 ila 17×17 boyutlarında üst üste binmeyen kareler içeren en az alanlı dikdörtgen 39 × 46 boyutlarına sahiptir39×46 , bu nedenle a(17)=39×46=1794 ( 1 indeksli).

Yanıtlar:


10

JavaScript (ES6), 172 bayt

@JonathanAllan tarafından önerilen daha yavaş ama daha kısa sürüm önerisi (ayrıca orijinal yanıtta 4 bayt tasarrufu):

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)

Çevrimiçi deneyin!


Orijinal cevap,  209183178174  bayt

İade N inci dizisinin terimi, 1-endekslendi.

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)

Çevrimiçi deneyin!

Yorumlananlar

Yardımcı işlevi

Önce bir yardımcı işlev tanımlamak S , bir geri çağrı işlevi çağırır c için n için 0 (her ikisi de dahil) ve bir arama döndüğü anda bir truthy değeri durur.

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

Ana işlev

A=1 ile başlıyoruz .

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

(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
hTesti tanımlamayın ve a%w<1özyineleme TIO'sunun kuyruğuna taşıyarak 6 * kaydedin . Tabii ki çok daha yavaş. (* en azından - JavaScript uzmanı değilim!)
Jonathan Allan

@JonathanAllan Teşekkürler. :) Aslında, a%w<1sadece yerine koymak olabilir merak ediyorum 1. Daha sonra tekrar kontrol etmem gerekecek.
Arnauld

0

Piton 2 (PyPy) , 250 236 bayt

Msh210'un önerileri sayesinde -14 bayt .

Dizinin 1 dizinli n terimini çıktılar.

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

Çevrimiçi deneyin! N> 4 için bu çok zaman alır. Yerel olarak n = 7 sonucunu doğruladım.


Nasıl çalıştığına dair bir açıklama eklemeyi düşünür müsünüz? Ayrıca, yedi yerine bir boşluğu girerek baytları tıraş edebileceğinizi düşünüyorum (ikinci girinti için). (Aslında, belki de iki forsatır bir satırda olabilir ve sadece bir kez girinti yapmanız gerekir.)
msh210

1
@ msh210 "7 boşluk" aslında bir sekmedir, Python 2'de önce bir boşlukla sonra bir sekme ile girintili olabilirsiniz. İkisini döngüler için bir satıra koymak maalesef geçersiz sözdizimi olacaktır.
ArBo

1
@ msh210 Bunları döngüler için birleştirmenin farklı bir yolunu buldum. Sadece 7 hatta sadece on line, yakalamak için teşekkürler. Bir açıklama yarın yazmaya çalışacağım
ovs
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.