최대 n의 크기의 제곱을 포함 할 가장 작은 사각형 영역


19

이것은 OEIS 시퀀스 A038666에 적용되는 일반적인 유형의 시퀀스 질문입니다 . 즉, 다음 중 하나를 수행하십시오.

  • 우주의 더위가 죽을 때까지 입력을받지 않거나 A038666을 출력하십시오.
  • 양의 정수를 입력 으로 받아들이고 A038666 의 번째 항 또는 첫 항을 출력하십시오 . ( 1- 인덱싱 대신 0 사용하는 경우 물론 출력해야합니다 .110 입력시 합니다.)

A038666의 일 기간은 크기의 비 중첩 사각형 포함 사각형 중 적어도 영역입니다 1×1,2×2,× 사용하는 경우 1 -indexing.

예:

1×1 ~ 4×4 크기의 겹치지 않는 사각형을 포함 할 수있는 가장 작은 면적의 직사각형의 크기 는 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

따라서 (4)=7×5=35 ( 1 indexed)입니다.

유사하게, 크기의 비 중첩 사각형 함유 최소 면적의 직사각형 1×1 통해 17×17 치수를 갖는 39×46 , 그래서 (17)=39×46=1794 ( 1 -indexed 참조).

답변:


10

자바 스크립트 (ES6), 172 바이트

@JonathanAllan이 제안한 느리지 만 짧은 버전 제안 (원래 답변에 4 바이트 저장) :

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)

온라인으로 사용해보십시오!


원래 답변,  209 183 178  바이트

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)

온라인으로 사용해보십시오!

댓글

도우미 기능

에스0

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

주요 기능

우리는 시작합니다=1 합니다.

(,h)×h=1×1× (실제로 가장 큰 것으로 시작) 해당 영역 서로 겹치지 마십시오.

(엑스,와이)[ ] .

+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
h테스트를 정의 하고 a%w<1재귀 TIO 테일로 이동 하지 않음으로써 6 *을 절약하십시오 . 물론 속도가 훨씬 느립니다. (* 최소한-저는 JavaScript 전문가가 아닙니다!)
Jonathan Allan

@JonathanAllan 감사합니다. :) 실제로, 나는 a%w<1단지 대체 할 수 있는지 궁금합니다.1 . 나중에 다시 확인해야합니다.
Arnauld

0

파이썬 2 (PyPy) , 250 236 바이트

msh210 의 제안 덕분에 -14 바이트 .

시퀀스의 1 번째 인덱스 n 번째 항을 출력합니다.

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

온라인으로 사용해보십시오! n> 4의 경우 시간이 오래 걸립니다. 로컬에서 최대 n = 7까지 결과를 확인했습니다.


작동 방식에 대한 설명을 포함시켜 주시겠습니까? 또한 7 번이 아닌 한 번에 공백을 들여 쓰기하여 바이트를 면도 할 수 있다고 생각합니다 (두 번째 들여 쓰기). (실제로 두 for줄이 한 줄에있을 수 있으며 한 번만 들여 쓰기
만하면된다고 생각합니다

1
@ msh210 "7 공백"은 실제로 탭입니다. 파이썬 2에서는 공백을 먼저 누른 다음 탭을 들여 쓸 수 있습니다. 불행히도 두 개의 for 루프를 한 줄에 넣는 것은 잘못된 구문입니다.
ArBo

1
@ msh210 for 루프를 결합하는 다른 방법을 찾았습니다. 온라인에서만 가능한 7 개의 공간. 캐치에 감사드립니다. 나는 내일 설명을 쓰려고 노력할 것이다
ovs
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.