El problema del embalaje del trineo

11

Los elfos de Papá Noel necesitan ayuda para determinar si su lote actual de regalos encajará en el trineo de Papá Noel. Escriba el programa más corto posible en el idioma que elija para ayudarlos.

Restricciones

  • El trineo de Santa mide 6 pies de ancho por 12 pies de largo y mide 4 pies de profundidad.
  • Los regalos pueden ser frágiles, por lo que no pueden apilarse uno encima del otro.
  • Puedes rotar y voltear los regalos como quieras, pero Santa es un tipo bastante obsesivo-compulsivo, así que mantén las rotaciones en múltiplos de 90 grados.
  • Las regulaciones de salud y seguridad del Polo Norte estipulan que los presentes no pueden sobresalir más de 1 pie por encima de la parte superior de un trineo (por lo tanto, no pueden tener más de 5 pies de altura).

Entrada

La entrada estará activada STDINy será un número entero que representa el número de regalos en el lote seguido de una lista de las dimensiones de los regalos: 1 regalo por línea, 3 dimensiones (en pies) separadas por espacios.

Ejemplos:

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

Salida

La salida debería ser la palabra 'SÍ' si los regalos se pueden empacar en el trineo o 'NO' si no se pueden.

Salida para los ejemplos anteriores:

YES

YES

NO

NO

Scripts de prueba

Como antes, me he apropiado de algunos scripts de prueba escritos por Joey y Ventero para crear algunas pruebas para esta tarea:

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

Recompensas

Cada entrada que pueda verificar que cumpla con las especificaciones, pase las pruebas y obviamente haya tenido algún intento de jugar al golf recibirá un voto positivo de mí (así que proporcione instrucciones de uso con su respuesta). La solución más corta para finales de 2011 será aceptada como la ganadora.

Gareth
fuente
¿Se nos permite rotar los regalos? ¿Voltearlos de lado? ¿Rotarlos en un ángulo que no sea múltiplo de 90 °?
Ilmari Karonen
@IlmariKaronen Sí, puedes rotar los regalos a cualquier orientación que desees siempre que quepan. Creo que las matemáticas involucradas en encajar las cajas en un ángulo que no sea un múltiplo de 90 serían demasiado complicadas, ¿no? He asumido solo rotaciones de 90 grados para las pruebas.
Gareth
@IlmariKaronen Pensándolo bien, creo que necesito eliminar las rotaciones de otros múltiplos de 90 grados para evitar complicar demasiado la pregunta y asegurar que las pruebas den las respuestas correctas. Agregaré una restricción adicional.
Gareth
¿Por qué el ejemplo 3 es un no cuando el ejemplo 1 es un sí? 6x12x5 es más grande que 6x12x4, así que ¿están presentes en la parte superior? En cuyo caso, ¿por qué 3 es un no ya que también puede sobresalir en la parte superior?
Skizz
1
@Skizz: Está redactado de manera confusa, pero vea la cuarta restricción: los regalos pueden sobresalir 1 pie de la parte superior. Entonces, la profundidad efectiva del trineo es de 5 pies, no de 4 pies.
Ilmari Karonen

Respuestas:

3

Haskell, 312 318 caracteres

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"

Por alguna razón que no entiendo completamente en este momento, no termina sus pruebas # 9 y # 16 en un tiempo razonable. Pero no dijiste nada sobre el rendimiento, ¿verdad?


373 383 caracteres

Esta versión funciona mucho más rápido para los ejemplos: primero comprueba si no es imposible simplemente porque el área es demasiado pequeña, y luego comienza con las parcelas más grandes en lugar de insertarlas en el orden dado. Tenga en cuenta que la detección de área no es perfecta: no considera las rotaciones, por lo que en algunas entradas puede dar resultados incorrectos. Pero funciona con el script de prueba.

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"
dejó de girar en sentido antihorario
fuente
No, no me preocupaba el rendimiento, pero el programa tiene que pasar todas las pruebas para obtener mi voto positivo. Actualmente está trabajando en la prueba 9. Lo dejaré un rato para ver si termina.
Gareth
@Gareth Tendré que optimizarlo aún un poco.
dejó de girar en contra del reloj
Okay. Todavía está trabajando en la prueba 9 aquí.
Gareth
2

Python, 461 caracteres

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'

Lverifica recursivamente si los rectángulos Ppueden colocarse en el trineo, donde zhay una máscara de bits de celdas que ya están ocupadas. La Sasignación determina qué camino está arriba para cada uno de los paquetes (la dimensión más grande <= 5 va verticalmente).

El código es potencialmente exponencial, pero es rápido en todas las entradas de prueba.

Keith Randall
fuente
1

GolfScript, 130 caracteres

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

Me llevó bastante tiempo ejecutarlo en GolfScript. Cualquier intento de jugar golf más rompió algunos de los casos de prueba.

Tenga en cuenta que esta versión puede volverse increíblemente lenta si la ejecuta con demasiados regalos.

Howard
fuente
Siempre tengo problemas con los de golfscript. Estoy intentando ./test ruby golfscript.rb howard.gspero me está dando errores. ¿Cómo debería invocarlo?
Gareth
@Gareth Puede anteponer un punto y coma seguido de la entrada (p ;"1\n6 12 5". Ej. ) A la secuencia de comandos dada.
Howard
Wow, no estabas bromeando sobre que sea lento en algunos casos. Puede que tenga que dejarlo toda la noche en los dos últimos casos de prueba (72 y 73 regalos respectivamente ;-)
Gareth
Lo sentimos, no pasará la prueba 5 en el script de prueba. No puedo votar hasta que pase todas las pruebas.
Gareth
@Gareth Bueno, entonces este no recibirá un voto positivo de tu parte ;-) Implementa el enfoque exponencial completo para ser breve. Estoy trabajando en un algoritmo más rápido pero aún no está listo para su envío. Ya necesita mucho más espacio y todavía me quedan algunos casos para implementar.
Howard