ปัญหาการบรรจุเลื่อน


11

เอลฟ์ของซานต้าต้องการความช่วยเหลือในการพิจารณาว่าของขวัญชุดปัจจุบันของพวกเขาจะเข้ากับซานต้า เขียนโปรแกรมสั้นที่สุดที่เป็นไปได้ในภาษาที่คุณเลือกเพื่อช่วยพวกเขาออก

ข้อ จำกัด

  • เลื่อนของซานต้าวัดกว้าง 6 ฟุตยาว 12 ฟุตและลึก 4 ฟุต
  • ของขวัญอาจมีความเปราะบางดังนั้นจึงไม่สามารถวางซ้อนกันได้
  • คุณสามารถหมุนและพลิกของขวัญได้ตามที่คุณต้องการ แต่ซานต้าเป็นหุ่นยนต์ที่ครอบงำจิตใจดังนั้นการหมุนจะทวีคูณ 90 องศา
  • ข้อกำหนดด้านสุขภาพและความปลอดภัยในขั้วโลกเหนือกำหนดว่าของขวัญต้องอยู่สูงกว่า 1 ฟุตไม่สูงเกิน 1 ฟุต (ดังนั้นพวกเขาอาจไม่สูงเกิน 5 ฟุต)

อินพุต

อินพุตจะเปิดSTDINและจะเป็นจำนวนเต็มหนึ่งตัวซึ่งแสดงถึงจำนวนของของขวัญในแบตช์ตามด้วยรายการมิติข้อมูลของของขวัญ - 1 การนำเสนอต่อบรรทัด 3 มิติ (ฟุต) คั่นด้วยช่องว่าง

ตัวอย่าง:

1
6 12 5

6
1 12 3
1 12 4
1 12 1
1 12 5
1 12 3
1 12 5

1
4 3 13

1
6 12 6

เอาท์พุต

ผลลัพธ์ควรเป็นคำว่า 'ใช่' หากของขวัญสามารถบรรจุลงในเลื่อนหรือ 'ไม่' หากไม่สามารถทำได้

เอาต์พุตสำหรับตัวอย่างด้านบน:

YES

YES

NO

NO

สคริปต์ทดสอบ

ก่อนหน้านี้ฉันได้ทำการทดสอบสคริปต์ที่เขียนโดยJoeyและVenteroเพื่อสร้างแบบทดสอบสำหรับงานนี้: -

การใช้งาน: ./test [your program and its arguments]

รางวัล

แต่ละรายการที่ฉันสามารถตรวจสอบว่าตรงตามข้อกำหนดผ่านการทดสอบและเห็นได้ชัดว่ามีความพยายามในการเล่นกอล์ฟบางอย่างจะได้รับ upvote จากฉัน (ดังนั้นโปรดให้คำแนะนำการใช้งานพร้อมคำตอบของคุณ) ทางออกที่สั้นที่สุดภายในสิ้นปี 2011 จะได้รับการยอมรับในฐานะผู้ชนะ


เราได้รับอนุญาตให้หมุนเวียนของขวัญหรือไม่? พลิกด้านข้างของพวกเขา? หมุนมุมด้วยมุมที่ไม่ใช่มุม 90 °
Ilmari Karonen

@IlmariKaronen ใช่คุณสามารถหมุนของขวัญให้เป็นแนวใดก็ได้ตามที่คุณต้องการ ฉันคิดว่าคณิตศาสตร์ที่เกี่ยวข้องกับกล่องใส่อุปกรณ์ในมุมที่ไม่ใช่ 90 หลายตัวจะซับซ้อนเกินไปใช่ไหม ฉันถือว่าการหมุน 90 องศาสำหรับการทดสอบเท่านั้น
Gareth

@IlmariKaronen เมื่อคิดต่อไปฉันคิดว่าฉันต้องกำจัดการหมุนทวีคูณของ 90 องศาเพื่อหลีกเลี่ยงคำถามที่ซับซ้อนเกินไปและเพื่อให้แน่ใจว่าการทดสอบให้คำตอบที่ถูกต้อง ฉันจะเพิ่มข้อ จำกัด พิเศษ
Gareth

ทำไมตัวอย่าง 3 a ไม่เมื่อตัวอย่าง 1 เป็นใช่ 6x12x5 นั้นใหญ่กว่า 6x12x4 ดังนั้นอนุญาตให้โผล่ออกมาด้านบนได้หรือไม่ ในกรณีใดเหตุใด 3 จึงไม่เป็นเช่นนั้นก็สามารถทะลุด้านบนได้
Skizz

1
@Skizz: มันเป็นประโยคที่สับสน แต่ดูข้อ จำกัด ที่สี่: ของขวัญอาจติด 1 ฟุตออกจากด้านบน ดังนั้นความลึกที่มีประสิทธิภาพของเลื่อนคือ 5ft ไม่ใช่ 4ft
Ilmari Karonen

คำตอบ:


3

Haskell, 312 318ตัวอักษร

import Data.List
s(ξ:υ:_,λ:σ:η:_)(x:y:_,l:w:_)=(ξ+λ<=x||ξ>=x+l||υ+σ<=y||υ>=y+w)&&ξ+λ<7&&υ+σ<13&&η<6
y p l=[(v,r):l|v<-[[x,y,0]|x<-[0..5],y<-[0..11]],r<-permutations p,all(s(v,r))l]
main=do
 n<-readLn
 p<-mapM(fmap(map read.words).const getLine)[1..n]
 putStr.r$foldr((=<<).y)[[([9,0],[0..])]]p
r[]="NO"
r _="YES"

ด้วยเหตุผลบางอย่างที่ฉันไม่เข้าใจอย่างสมบูรณ์ในขณะนี้การทดสอบ # 9 และ # 16 ของคุณไม่เสร็จในเวลาที่เหมาะสม แต่คุณไม่ได้พูดอะไรเกี่ยวกับการแสดงใช่ไหม?


373 383ตัวอักษร

รุ่นนี้ทำงานได้เร็วกว่ามากสำหรับตัวอย่าง: ตรวจสอบก่อนว่ามันเป็นไปไม่ได้เพียงเพราะพื้นที่มีขนาดเล็กเกินไปและจากนั้นจะเริ่มด้วยพัสดุที่ใหญ่ที่สุดแทนที่จะใส่เข้าไปในลำดับที่กำหนด โปรดทราบว่าการตรวจจับพื้นที่ไม่สมบูรณ์: ไม่พิจารณาการหมุนดังนั้นในอินพุตบางตัวอาจให้ผลลัพธ์ที่ผิด แต่มันใช้งานได้กับสคริปต์ทดสอบ

import Data.List
s(ξ:υ:_,λ:σ:η:_)(x:y:_,l:w:_)=(ξ+λ<=x||ξ>=x+l||υ+σ<=y||υ>=y+w)&&ξ+λ<7&&υ+σ<13&&η<6
y p l=[(v,r):l|v<-[[x,y,0]|x<-[0..5],y<-[0..11]],r<-permutations p,all(s(v,r))l]
π=product
main=do
 n<-readLn
 p<-mapM(fmap(map read.words).const getLine)[1..n]
 putStr$if sum(map(π.init)p)>72||null(foldr((=<<).y)[[([9,0],[0..])]].sortBy((.π).compare.π)$p)then"NO"else"YES"

ไม่ฉันไม่ได้กังวลเกี่ยวกับประสิทธิภาพ แต่โปรแกรมจะต้องผ่านการทดสอบทั้งหมดเพื่อรับ upvote ของฉัน ขณะนี้กำลังทำงานกับการทดสอบที่ 9 ฉันจะปล่อยให้มันสักครู่เพื่อดูว่ามันเสร็จสิ้น
Gareth

@ กาเร็ ธ ฉันจะต้องปรับมันให้เหมาะสมสักหน่อย
หยุดหมุนทวนเข็มนาฬิกา

ตกลง. มันยังคงทำงานกับการทดสอบ 9 ที่นี่
Gareth

2

Python 461 ตัวอักษร

import sys
def L(P,z):
 if not P:return 1
 for w,h in[P[0],P[0][::-1]]:
  m=sum((2**w-1)<<i*6for i in range(h))
  for x in range(7-w):
   for y in range(13-h):
    n=m<<y*6+x
    if z&n==0and L(P[1:],z|n):return 1
 return 0
for G in sys.stdin.read().split('\n\n'):
 S=[(x,y)if z<6 else(x,z)if y<6 else(y,z)if x<6 else(9,9)for x,y,z in[sorted(eval(g.replace(' ',',')))for g in G.split('\n')[1:]if g]]
 print'YES\n'if sum(x*y for x,y in S)<73and L(S,0)else'NO\n'

Lตรวจสอบซ้ำว่าสี่เหลี่ยมในPสามารถเลื่อนในเลื่อนซึ่งzเป็นบิตของเซลล์ที่ครอบครองอยู่แล้ว การSกำหนดกำหนดวิธีการที่จะขึ้นอยู่กับแต่ละแพคเกจ (ขนาดใหญ่ที่สุด <= 5 ไปในแนวตั้ง)

รหัสนี้อาจอธิบายได้ แต่มันรวดเร็วในอินพุตการทดสอบทั้งหมด


1

GolfScript, 130 ตัวอักษร

"NO":g;~](;3/127{128*64+}12*\{.,0>.!{"YES":g;}*{([{[~@]..[~\]\}3*;]{)6<{~[2\?(]*128base 83,{2\?1$*.4$&0={3$|2$f}*}%;}*}%;}*;;}:f~g

มันใช้เวลาค่อนข้างนานในการทำให้มันทำงานใน GolfScript ความพยายามใด ๆ ในการตีกอล์ฟจะทำให้บางกรณีทดสอบแย่

โปรดรับการเตือนว่ารุ่นนี้อาจช้าอย่างไม่น่าเชื่อถ้าคุณรันด้วยของขวัญมากมายเกินไป


ฉันมักจะมีปัญหากับคน Golfscript ฉันพยายาม./test ruby golfscript.rb howard.gsแต่มันทำให้ฉันมีข้อผิดพลาด ฉันจะเรียกมันได้อย่างไร
Gareth

@Gareth คุณอาจเพิ่มเซมิโคลอนตามด้วยอินพุต (เช่น;"1\n6 12 5") ไปยังสคริปต์ที่กำหนด
Howard

ว้าวคุณไม่ได้ล้อเล่นเรื่องมันช้าในบางกรณี ฉันอาจต้องทิ้งไว้ทั้งคืนในกรณีทดสอบทั้งสองครั้ง (72 และ 73 รายการตามลำดับ ;-)
Gareth

ขออภัยจะไม่ผ่านการทดสอบ 5 ในสคริปต์ทดสอบ ฉันไม่สามารถลงคะแนนได้จนกว่าจะผ่านการทดสอบทั้งหมด
Gareth

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