ค้นหาพื้นที่ของสี่เหลี่ยมที่เล็กที่สุดที่จะมีสี่เหลี่ยมที่มีขนาดไม่เกิน n


19

นี่คือคำถามที่ลำดับของชนิดที่ปกตินำไปใช้เป็นOEIS ลำดับ A038666 นั่นคือทำอย่างใดอย่างหนึ่งต่อไปนี้:

  • ยอมรับว่าไม่มีสิ่งใดป้อนเข้าและเอาท์พุท A038666 จนกว่าความร้อนจากจักรวาลจะตาย
  • ยอมรับเป็นจำนวนเต็มบวกเป็นอินพุตและเอาต์พุตระยะเวลาของ A038666 TH หรือครั้งแรกแง่ (ถ้าใช้ - แทนที่จะเป็น -exexing แน่นอนว่าคุณต้องเอาท์พุทด้วยอินพุต)nn0110

คำที่ของ A038666 เป็นพื้นที่ที่น้อยที่สุดในบรรดาสี่เหลี่ยมที่มีสี่เหลี่ยมที่ไม่ทับซ้อนกันของขนาดถ้าคุณใช้ -exexingn1×1,2×2,n×n1

ตัวอย่าง:

สี่เหลี่ยมผืนผ้าพื้นที่ที่เล็กที่สุดซึ่งสามารถมีสี่เหลี่ยมที่ไม่ซ้อนทับกันของขนาดถึงมีขนาด :1×14×47×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

ดังนั้น ( -exexed)a(4)=7×5=351

ในทำนองเดียวกันสี่เหลี่ยมผืนผ้าที่มีพื้นที่น้อยที่สุดที่ประกอบด้วยสี่เหลี่ยมที่ไม่ซ้อนทับกันของขนาดถึงมีขนาดดังนั้น ( -exexed)1×117×17 39×46a(17)=39×46=17941

คำตอบ:


10

JavaScript (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  174 ไบต์

ส่งคืนคำที่Nลำดับของลำดับที่มีดัชนี 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)

ลองออนไลน์!

แสดงความคิดเห็น

ฟังก์ชั่นตัวช่วย

ก่อนอื่นเรากำหนดฟังก์ชันผู้ช่วยSซึ่งเรียกใช้ฟังก์ชันการเรียกกลับcสำหรับnถึง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

ฟังก์ชั่นหลัก

เราเริ่มต้นด้วย= 1A=1

สำหรับแต่ละคู่(w,h)เช่นนั้นw×h=Aเราพยายามแทรกสี่เหลี่ยมทั้งหมดที่มีขนาด1×1ถึงn×n (อันที่จริงเริ่มต้นด้วยขนาดที่ใหญ่ที่สุด) ในพื้นที่ที่สอดคล้องกันในลักษณะที่พวกเขา อย่าทับซ้อนกัน

เราติดตามรายการของช่องสี่เหลี่ยมที่มีตำแหน่งของพวกเขา(X,Y)ของพวกเขาและความกว้างWในl[ ] ]

เราทั้งสองกลับถ้าจัดที่ถูกต้องพบหรือลองอีกครั้งกับ+ 1AA+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
บันทึก 6 * โดยไม่ได้กำหนดhและการเคลื่อนย้ายการทดสอบสำหรับa%w<1การเรียกซ้ำหางของที่TIO แน่นอนว่ามันช้ากว่ามาก (* อย่างน้อย - ฉันไม่ใช่ผู้เชี่ยวชาญ JavaScript!)
Jonathan Allan

@JanathanAllan ขอบคุณ :) ที่จริงผมสงสัยว่าอาจถูกแทนที่ด้วยเพียงa%w<1 1ฉันจะต้องตรวจสอบอีกครั้งในภายหลัง
Arnauld

0

Python 2 (PyPy) , 250 236 ไบต์

-14 ไบต์ขอบคุณคำแนะนำของmsh210

เอาต์พุตคำที่ n ที่มีดัชนี 1 ของลำดับ

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 ในเครื่อง


คุณจะนึกถึงคำอธิบายว่ามันทำงานอย่างไร? นอกจากนี้ฉันคิดว่าคุณสามารถโกนไบต์ด้วยการเยื้องหนึ่งช่องว่างในเวลาแทนที่จะเป็นเจ็ด (สำหรับการเยื้องครั้งที่สอง) (อันที่จริงแล้วฉันคิดว่าบางทีทั้งสองforบรรทัดสามารถเป็นหนึ่งบรรทัดได้และคุณจะต้องเยื้องหนึ่งครั้งเท่านั้น)
msh210

1
@ msh210 "7 ช่องว่าง" เป็นแท็บจริง ๆ เช่นเดียวกับใน Python 2 คุณสามารถเยื้องก่อนด้วยช่องว่างแล้วใช้แท็บ การวางทั้งสองสำหรับลูปในหนึ่งบรรทัดจะเป็นไวยากรณ์ที่ไม่ถูกต้องอย่างน่าเสียดาย
ArBo

1
@ msh210 ฉันพบวิธีที่แตกต่างในการรวมเหล่านั้นเข้ากับลูป 7 ช่องว่างที่อยู่บนบรรทัดเท่านั้นขอขอบคุณสำหรับการจับ ผมจะพยายามที่จะเขียนคำอธิบายในวันพรุ่งนี้
OVS
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.