雪橇包装问题


11

圣诞老人的精灵需要帮助来确定他们当前的礼物是否适合圣诞老人的雪橇。用您选择的语言编写最短的程序,以帮助他们。

约束条件

  • 圣诞老人的雪橇宽6英尺,长12英尺,深4英尺。
  • 礼物可能很脆弱,因此它们可能不会堆叠在一起。
  • 您可以根据需要旋转和翻转礼物,但是圣诞老人的强迫性非常强,因此将旋转保持90度的倍数即可。
  • 北极的健康和安全法规规定,礼物的伸出高度不得超过雪橇顶部的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”(是),否则不能输出“ NO”(否)。

以上示例的输出:

YES

YES

NO

NO

测试脚本

和以前一样,我已经使用了JoeyVentero编写的一些测试脚本来为此任务创建一些测试:

用法: ./test [your program and its arguments]

奖赏

我可以验证符合规格,通过测试并且显然已经尝试过打高尔夫球的每个条目都会收到我的赞誉(因此请提供使用说明和答案)。最短的解决方案将在2011年底获胜。


我们可以旋转礼物吗?将它们翻转到一边?旋转角度不是90°的倍数?
Ilmari Karonen 2011年

@IlmariKaronen是的,您可以根据自己的喜好将礼物旋转到任意方向。我认为,以不大于90的倍数的角度装配盒子时涉及的数学会过于复杂吗?我只假设测试旋转90度。
Gareth

@IlmariKaronen经过进一步思考,我认为我需要消除90度其他倍数的旋转,以避免使问题过于复杂,并确保测试给出正确答案。我将添加一个额外的约束。
Gareth

当示例1为“是”时,为什么示例3为“否”?6x12x5大于6x12x4,因此是否允许将顶部戳出?在那种情况下为什么3不为好,因为那也可以突出?
Skizz

1
@Skizz:它的措辞令人困惑,但请参见第四个约束:礼物可能会伸出顶部1英尺。因此,雪橇的有效深度是5英尺,而不是4英尺。
Ilmari Karonen 2011年

Answers:


3

Haskell,312318个字符

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"

不,我不关心性能,但是该程序确实必须通过所有测试才能获得支持。目前正在测试9上进行。我会稍等一下,看看它是否完成了。
Gareth

@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"给定脚本的输入(例如)。
霍华德

哇,您并不是在开玩笑,因为它在某些情况下运行缓慢。我可能分别离开整个晚上的最后两个测试案例(72和73节礼物;-)
加雷

抱歉,它不会超过测试脚本中的测试5。在所有测试通过之前,我无法投票。
Gareth

@Gareth好吧,那么这将不会对您不利;-)它实现了完整的指数方法,以求简短。我正在研究一种更快的算法,但尚未准备好提交。它已经需要更多的空间,我还有一些案例需要执行。
霍华德
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.