Le problème de l'emballage du traîneau

11

Les elfes du père Noël ont besoin d'aide pour déterminer si leur lot actuel de cadeaux rentrera dans le traîneau du père Noël. Écrivez le programme le plus court possible dans la langue de votre choix pour les aider.

Contraintes

  • Le traîneau du Père Noël mesure 6 pieds de large par 12 pieds de long et est de 4 pieds de profondeur.
  • Les cadeaux peuvent être fragiles, donc ils ne peuvent pas être empilés les uns sur les autres.
  • Vous pouvez faire pivoter et retourner les cadeaux comme vous le souhaitez, mais le Père Noël est un gars plutôt obsessionnel-compulsif, alors gardez les rotations à des multiples de 90 degrés.
  • Les règles de santé et de sécurité du pôle Nord stipulent que les cadeaux ne doivent pas dépasser de plus de 1 pied au-dessus du haut d'un traîneau (ils ne doivent donc pas dépasser 5 pieds de haut).

Contribution

L'entrée sera activée STDINet sera un entier représentant le nombre de cadeaux dans le lot suivi d'une liste des dimensions des cadeaux - 1 présent par ligne, 3 dimensions (en pieds) séparées par des espaces.

Exemples:

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

Production

La sortie devrait simplement être le mot «OUI» si les cadeaux peuvent être emballés dans le traîneau ou «NON» s'ils ne le peuvent pas.

Sortie pour les exemples ci-dessus:

YES

YES

NO

NO

Scripts de test

Comme précédemment, je me suis approprié des scripts de test écrits par Joey et Ventero pour créer des tests pour cette tâche: -

Usage: ./test [your program and its arguments]

Récompenses

Chaque entrée dont je peux vérifier qu'elle répond aux spécifications, réussit les tests et a évidemment eu une tentative de golf recevra un vote positif de ma part (veuillez donc fournir des instructions d'utilisation avec votre réponse). La solution la plus courte d'ici la fin de 2011 sera acceptée comme gagnante.

Gareth
la source
Sommes-nous autorisés à faire tourner les cadeaux? Retournez-les sur le côté? Faites-les pivoter d'un angle qui n'est pas un multiple de 90 °?
Ilmari Karonen
@IlmariKaronen Oui, vous pouvez faire pivoter les cadeaux dans n'importe quelle orientation, à condition qu'ils correspondent. Je pense que les calculs nécessaires pour ajuster les boîtes à un angle qui n'est pas un multiple de 90 seraient trop compliqués, n'est-ce pas? Je n'ai supposé que des rotations de 90 degrés pour les tests.
Gareth
@IlmariKaronen Après réflexion, je pense que je dois éliminer les rotations des autres multiples de 90 degrés pour éviter de compliquer la question de manière excessive et pour m'assurer que les tests donnent des réponses correctes. J'ajouterai une contrainte supplémentaire.
Gareth
Pourquoi l'exemple 3 est-il non alors que l'exemple 1 est oui? 6x12x5 est plus grand que 6x12x4. Dans ce cas, pourquoi le 3 est-il non, car cela peut aussi dépasser le sommet?
Skizz
1
@ Skizz: C'est formulé de manière confuse, mais voyez la quatrième contrainte: les cadeaux peuvent coller à 1 pied du haut. La profondeur effective du traîneau est donc de 5 pieds, pas de 4 pieds.
Ilmari Karonen

Réponses:

3

Haskell, 312 318 caractères

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"

Pour une raison que je ne comprends pas complètement pour le moment, cela ne termine pas vos tests # 9 et # 16 dans un délai raisonnable. Mais vous n'avez rien dit sur la performance, n'est-ce pas?


373 383 caractères

Cette version fonctionne beaucoup plus rapidement pour les exemples: elle vérifie d'abord si ce n'est pas impossible simplement parce que la zone est trop petite, puis elle commence par les plus grandes parcelles plutôt que de les insérer dans l'ordre donné. Notez que la détection de zone n'est pas parfaite: elle ne prend pas en compte les rotations, elle peut donc sur certaines entrées donner de mauvais résultats. Mais cela fonctionne avec le script de test.

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"
a cessé de tourner dans le sens antihoraire
la source
Non, je n'étais pas concerné par les performances, mais le programme doit passer tous les tests pour obtenir mon vote positif. Il travaille actuellement sur le test 9. Je vais laisser un peu de temps pour voir s'il se termine.
Gareth
@Gareth, je devrai encore un peu l'optimiser.
cessé de tourner dans le sens inverse des aiguilles d'une montre
D'accord. Il fonctionne toujours sur le test 9 ici.
Gareth
2

Python, 461 caractères

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'

Lvérifie récursivement si les rectangles Ppeuvent être placés dans le traîneau, où se ztrouve un masque de cellules déjà occupé. L' Saffectation détermine le sens de montée pour chacun des packages (la plus grande dimension <= 5 va verticalement).

Le code est potentiellement exponentiel, mais il est rapide sur toutes les entrées de test.

Keith Randall
la source
1

GolfScript, 130 caractères

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

Il a fallu un certain temps pour le faire fonctionner dans GolfScript. Toute tentative de jouer au golf a encore brisé certains des cas de test.

Soyez averti que cette version peut devenir incroyablement lente si vous l'exécutez avec trop de cadeaux.

Howard
la source
J'ai toujours du mal avec les golfscript. J'essaye ./test ruby golfscript.rb howard.gsmais ça me donne des erreurs. Comment dois-je l'invoquer?
Gareth
@Gareth Vous pouvez simplement ajouter un point-virgule suivi de l'entrée (par exemple ;"1\n6 12 5") du script donné.
Howard
Wow, vous ne plaisantiez pas que cela soit lent dans certains cas. Je devrai peut-être la laisser toute la nuit sur les deux derniers cas de test (72 et 73 cadeaux respectivement ;-)
Gareth
Désolé, il ne dépassera pas le test 5 du script de test. Je ne peux pas voter jusqu'à ce qu'il passe tous les tests.
Gareth
@Gareth Eh bien, celui-ci n'obtiendra pas de vote positif de votre part ;-) Il implémente l'approche exponentielle complète afin d'être court. Je travaille sur un algorithme plus rapide mais il n'est pas encore prêt à être soumis. Il a déjà besoin de beaucoup plus d'espace et j'ai encore quelques cas à mettre en œuvre.
Howard