Embalaje de piezas de madera

14

Hay dos piezas de madera. Ambos consisten en un cuerpo recto y algunos bloques adicionales debajo del cuerpo. Una pieza de ejemplo con bloques adicionales en las posiciones (indexadas a 0) 0,4,7,9,10:

XXXXXXXXXXX
X   X  X XX

La pieza se puede representar como una 01secuencia binaria con el icarácter th mostrando si hay un bloque en la iposición th. El ejemplo superior se puede representar como 10001001011.

Podemos juntar dos piezas volteando verticalmente la segunda (y quizás volteándola horizontalmente también). Después de la vuelta (s) podemos encontrar una alineación donde las dos piezas se pueden juntar para tener una altura de 3.

Two example pieces:

XXXXXXXXXXX   XXXXXXXX
X   X  X XX     XXX

Second piece flipped vertically and horizontally:

 XXXXXXXXXXX   
 X   X  X XX
  XXX
XXXXXXXX

Pieces put together:

 XXXXXXXXXXX   
 XXXXX  X XX
XXXXXXXX

El ejemplo resultó en un ancho total de 12 bloques.

Debe escribir un programa o función que reciba dos cadenas como entrada que represente las dos piezas y genere un número entero del ancho mínimo alcanzable con una altura de 3.

Entrada

  • Dos cadenas que consisten en los caracteres 0y 1.
  • Ambas cadenas contienen al menos un carácter.
  • Puede elegir recibir las dos cadenas como una unida por un solo espacio.

Salida

  • Un solo entero positivo, el ancho total mínimo alcanzable.

Ejemplos

0 0  =>  1

1 0  =>  1

1 1  =>  2

11 111  =>  5

010 0110  =>  5

0010 111  =>  5

00010 11011  =>  6

01010 10101  =>  5

1001 100001  =>  6

1110001100001 1100100101  =>  14

001101010000101 100010110000  =>  16

0010110111100 001011010101001000000  =>  21

0010110111100 001011010101001001100  =>  28

100010100100111101 11100101100010100100000001  =>  27

0010 10111  =>  5

0100 10111  =>  5

0010 11101  =>  5

0100 11101  =>  5

10111 0010  =>  5

10111 0100  =>  5

11101 0010  =>  5

11101 0100  =>  5

Este es el código de golf, por lo que gana la entrada más corta.

randomra
fuente
¿Se supone que la pieza en el primer ejemplo es la pieza 1 en la segunda parte del ejemplo? Si es así, entonces uno de ellos está equivocado.
mdc32
@ mdc32 No eran las mismas piezas, pero cambiaron la primera para evitar confusiones.
randomra

Respuestas:

7

Pyth, 37 35 34 32 31 bytes

eSX0lM.zff-\1@VhY>eYT*Fm,d_d.z0

Toma entrada nueva línea separada.

Demostración , prueba de arnés .

Explicación:

En el nivel superior, para cada combinación de cadenas normales e inversas, desplazamos la segunda cadena a la izquierda por un número determinado de posiciones, y verificamos las superposiciones con la primera cadena. Esto se repite hasta que se encuentre una cantidad de turno sin superposiciones. Esa cantidad de turno se agrega a la longitud de la primera cadena y el resultado se compara con la segunda longitud de la cadena. Se imprime el valor más alto.

eSX0lM.zff-\1@VhY>eYT*Fm,d_d.z0

                            .z     The list of the two input strings.
                       m           Map to 
                        ,d_d       The pair of each string and its reverse.
                     *F            Take the cartesisan product of those lists.
         f                         Filter those pairs of a first string and a 
                                   second string, possibly reversed,
          -\1                      On the absence of the string "1" in
             @V                    The vectorized intersection (intersection
                                   of 0th position, 1st position, etc.) of
               hY                  the first string and
                 >eYT              the second string without the first T elements.
        f                    0     Starting at 0 and counting upwards, find the
                                   lowest T where the result is truthy. 
                                   (where anything passes the inner filter)
    lM.z                           Map the input strings to their lengths.
  X0                               Add the above result to the first entry.
eS                                 Take the maximum of the two values and print.
isaacg
fuente
4

Pip , 72 70 48 bytes

Fp[aRVa]CP[bRVb]L#a+1{I2NI$+plAE:#$+^pp@1.:0}MNl

Toma las dos cadenas como argumentos de línea de comandos. Formateado, con comentarios:

                     a, b initialized from cmdline args; l is [] (implicit)
F p [aRVa]CP[bRVb]   For each possible pair p of a/reverse(a) with b/reverse(b):
 L #a+1 {            Loop for each potential offset of bottom piece:
  I 2 NI $+p         If no 2's in the sum of p:
   l AE: # $+ ^p     Append the max width of elements of p to l (see below for explanation)
  p@1 .: 0           Append a 0 to bottom piece
 }
MNl                  The answer is min(l); print it (implicit)

Solo estamos calculando las superposiciones donde la pieza inferior sobresale a la izquierda, por lo que debemos intentarlo con las piezas superior e inferior invertidas. Cada vez a través del ciclo interno, si no hay 2 en la suma, es un ajuste; Luego añadimos otro cero al final de la pieza inferior e intentamos nuevamente.

   0010
    111
   0121

   0010
   111_
   1120

   0010
  111__
  11110

   0010
 111___
 111010

   0010
111____
1110010

Para encontrar el ancho total, dividimos los elementos pen listas de caracteres y suma. Las operaciones por elementos en listas de longitud desigual conservan la longitud de la más larga, por lo que la longitud de esta suma es exactamente lo que necesitamos. (La división es necesaria porque simplemente sumar como números eliminará los ceros a la izquierda:, $+[0101 10] = 111pero $+^[0101 10] = [0 1 1 1]).

C:\> pip.py woodPacking.pip 0010 111
5
DLosc
fuente
3

Rubí 127 130

Esto resultó ser tan largo ... :(

->m,n{[[m,n],[m,n.reverse],[n,m],[n,m.reverse]].map{|u,d|[(0..l=u.size).find{|i|(d.to_i(2)<<i)&u.to_i(2)<1}+d.size,l].max}.min}

Pruebas: http://ideone.com/te8XWk

Rubí legible:

def pack_length piece1, piece2
  min_possible_packed_length = [
    min_packed_length(piece1, piece2),
    min_packed_length(piece1, piece2.reverse),
    min_packed_length(piece2, piece1),
    min_packed_length(piece2, piece1.reverse)
  ].min

  min_possible_packed_length
end

def min_packed_length up_piece, down_piece
  x = up_piece.to_i 2
  y = down_piece.to_i 2

  # find the smallest shift for the piece placed down 
  # so that they fit together
  min_packed_shift = (0..up_piece.size).find{|i| (y<<i)&x<1 }

  # min pack length cannot be smaller than any of the 
  # two pieces
  [min_packed_shift + down_piece.size, up_piece.size].max
end
Cristian Lupascu
fuente
¿Podría probar los nuevos ejemplos agregados? La [[m,n],[m,n.reverse],[n,m],[n,m.reverse]]parte puede ser incorrecta. (No estoy seguro, pero cometí un error similar.)
randomra
@randomra ¡Seguro! Por favor vea el enlace de prueba; Agregué las nuevas pruebas allí.
Cristian Lupascu
Gracias, perdón por la molestia extra. Mi intuición era que necesitarías en [n.reverse,m]lugar de, [n,m.reverse]pero no conozco a Ruby.
randomra
@randomra en realidad no pasa la prueba '0010110111100', '001011010101001001100'diciendo Esperado: 28, Actual: 30 . Todas las otras pruebas pasan. Así que has hecho un buen trabajo probando casos de esquina. :)
Cristian Lupascu
1

JavaScript ( ES6 ) 160

No se pudo acortar ...

F=(a,b,c=[...b].reverse(),
K=(a,b,t=a.length)=>{
for(e=i=-1;e&&i++<t;)for(e=j=0;u=b[j];j++)e|=u&a[j+i];
return t<i+j?i+j:t
})=>Math.min(K(a,b),K(a,c),K(b,a),K(c,a))

// test

out=x=>O.innerHTML += x+'\n'

test=[
 ['0', '0', 1],['1', '0', 1],['1', '1', 2],['11', '111', 5]
,['010', '0110', 5],['0010', '111', 5],['0010', '10111', 5]
,['00010', '11011', 6],['01010', '10101', 5],['1001', '100001', 6]
,['1110001100001', '1100100101', 14]
,['001101010000101', '100010110000', 16]
,['0010110111100', '001011010101001000000', 21]
,['0010110111100', '001011010101001001100', 28]
,['100010100100111101', '11100101100010100100000001', 27]
,['0010','10111', 5],['0100','10111', 5]
,['0010','11101', 5],['0100','11101', 5]
,['10111','0010', 5],['10111','0100', 5]
,['11101','0010', 5],['11101','0100', 5]
]

test.forEach(t=>{
  r = F(t[0],t[1]),
  out(
    (r==t[2]?'Ok':'Fail') 
    + ' A: '+t[0]+', B: '+t[1]
    + ', Result: '+r + ', Check:  '+t[2])
})
pre { font-size: 10px }
<pre id=O></pre>

edc65
fuente