そりパッキング問題


11

サンタのエルフは、プレゼントの現在のバッチがサンタのそりに収まるかどうかを判断するのに助けが必要です。彼らを助けるために、あなたが選んだ言語で可能な限り短いプログラムを書いてください。

制約

  • サンタのそりは、幅6フィート、長さ12フィート、深さ4フィートです。
  • プレゼントは壊れやすい可能性があるため、互いに積み重ねることはできません。
  • プレゼントは好きなように回転させたり反転させたりすることができますが、サンタはかなり強迫観念に満ちているので、回転を90度の倍数に保ちます。
  • ノースポールの健康と安全の規制では、プレゼントがそりの上から1フィートを超えて突き出てはならない(したがって、高さが5フィートを超えてはならない)と規定されています。

入力

入力はオンにSTDINなり、バッチ内のプレゼントの数を表す1つの整数に、プレゼントの次元のリストが続きます-1行に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

テストスクリプト

前と同じように、JoeyとVenteroによって書かれたいくつかのテストスクリプトを使用して、このタスクのテストを作成しました。

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

報酬

仕様を満たしていることを確認でき、テストに合格し、明らかにゴルフの試みを行った各エントリは、私から賛成票を受け取ります(そのため、使用方法を回答してください)。2011年末までに最短のソリューションが勝者として受け入れられます。


プレゼントを回転させることはできますか?裏返して?90°の倍数ではない角度でそれらを回転させますか?
— イルマリカロネン

@IlmariKaronenはい、収まる限り、任意の向きにプレゼントを回転させることができます。私は、90の倍数ではない角度でボックスをはめ込むことに関係する数学は複雑すぎると思いますか?テストでは90度の回転のみを想定しています。
— ガレス

@IlmariKaronenさらに考えてみると、質問が過度に複雑にならないように、またテストで正しい答えが得られるように、90度の倍数の回転を排除する必要があると思います。余分な制約を追加します。
— ガレス

例1がyesの場合、例3がnoなのはなぜですか?6x12x5は6x12x4よりも大きいので、上から突き出すことができますか?なぜ3がノーであるのか、それでもトップを突き出すことができますか?
— スキッツ

1
@Skizz:紛らわしい言い回しですが、4番目の制約を見てください。したがって、そりの有効深度は4フィートではなく5フィートです。
— イルマリカロネン

回答:


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"

いいえ、パフォーマンスに関心はありませんでしたが、プログラムはすべてのテストに合格してから投票する必要があります。現在、テスト9に取り組んでいます。終了するかどうかを確認するために、しばらくお待ちください。
— ガレス

@Garethまだ少し最適化する必要があります。
— 反時計回りの回転を停止

OK。ここではまだテスト9に取り組んでいます。
— ガレス

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 ;"1\n6 12 5"与えられたスクリプトにセミコロンの後に入力(例:)を追加するだけです。
— ハワード

うわー、あなたはそれがいくつかのケースで遅いことをからかっていませんでした。私は;-)それぞれ72と73のプレゼント(2最後のテストケースにすべての夜にそれを残していること
— ギャレス

申し訳ありませんが、テストスクリプトではテスト5を過ぎません。すべてのテストに合格するまで、投票できません。
— ガレス

@Garethさて、これはあなたの側から賛成を得ることはありません;-)それは短くするために完全な指数関数的アプローチを実装しています。より高速なアルゴリズムに取り組んでいますが、まだ提出の準備ができていません。すでにかなり多くのスペースが必要であり、実装のためにいくつかのケースが残っています。
— ハワード
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.