Peças de madeira para embalagem

14

Existem dois pedaços de madeira. Ambos consistem em um corpo reto e alguns blocos extras abaixo do corpo. Uma peça de exemplo com blocos extras nas posições (indexadas em 0) 0,4,7,9,10:

XXXXXXXXXXX
X   X  X XX

A peça pode ser representada como uma 01sequência binária com o icaractere th mostrando se existe um bloco na iposição th. O exemplo superior pode ser representado como 10001001011.

Podemos montar duas peças girando verticalmente a segunda (e talvez também horizontalmente). Após o flip (s), podemos encontrar um alinhamento no qual as duas peças podem ser montadas para ter uma 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

O exemplo resultou em uma largura total de 12 blocos.

Você deve escrever um programa ou função que receba duas seqüências como entrada, representando as duas partes e produza um número inteiro com a largura mínima possível com uma altura de 3.

Entrada

  • Duas strings consistindo nos caracteres 0e 1.
  • Ambas as cadeias contêm pelo menos um caractere.
  • Você pode optar por receber as duas seqüências como uma unida por um único espaço.

Resultado

  • Um único número inteiro positivo, a largura total mínima alcançável.

Exemplos

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 é o código de golfe, portanto a entrada mais curta vence.

randomra
fonte
A peça no primeiro exemplo deveria ser a peça 1 na segunda parte do exemplo? Nesse caso, um deles está errado.
Mdc32 26/05
@ mdc32 Não eram as mesmas peças, mas mudaram a primeira para evitar confusão.
Randomra

Respostas:

7

Pitão, 37 35 34 32 31 bytes

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

Separa a nova linha de entrada.

Demonstração , Arnês de Teste .

Explicação:

No nível alto, para cada combinação de cadeias normais e reversas, deslocamos a segunda corda para a esquerda por um determinado número de posições e verificamos sobreposições com a primeira. Isso é repetido até que um valor de turno sem sobreposições seja encontrado. Essa quantidade de turno é adicionada ao comprimento da primeira string e o resultado é comparado com o comprimento da segunda string. O valor mais alto é impresso.

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
fonte
4

Pip , 72 70 48 bytes

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

Toma as duas seqüências como argumentos de linha de comando. Formatado, com comentários:

                     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)

Estamos apenas calculando as sobreposições em que a peça de baixo fica à esquerda, portanto, precisamos tentar com as peças de cima e de baixo invertidas. Cada vez que passa pelo loop interno, se não houver 2 na soma, é um ajuste; Em seguida, colocamos outro zero no final da peça de baixo e tentamos novamente.

   0010
    111
   0121

   0010
   111_
   1120

   0010
  111__
  11110

   0010
 111___
 111010

   0010
111____
1110010

Para encontrar a largura total, dividimos os elementos de pem listas de caracteres e soma. As operações por item em listas de comprimento desigual preservam o comprimento da mais longa, portanto, o comprimento dessa soma é exatamente o que precisamos. (A divisão é necessária porque somar como números eliminará zeros à esquerda:, $+[0101 10] = 111mas $+^[0101 10] = [0 1 1 1].)

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

Ruby 127 130

Isso acabou sendo tão longo ... :(

->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}

Testes: http://ideone.com/te8XWk

Ruby legível:

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
fonte
Você poderia testar os novos exemplos adicionados? A [[m,n],[m,n.reverse],[n,m],[n,m.reverse]]peça pode estar incorreta. (Eu não tenho certeza, mas eu cometi um erro similar.)
randomra
@randomra Claro! Por favor, veja o link do teste; Eu adicionei os novos testes lá.
Cristian Lupascu
Obrigado, desculpe pelo aborrecimento extra. Minha intuição era que você precisaria, em [n.reverse,m]vez de, [n,m.reverse]mas eu não conheço Ruby.
randomra 27/05
@randomra, na verdade, que falha no teste, '0010110111100', '001011010101001001100'dizendo Esperado: 28, Real: 30 . Todos os outros testes são aprovados. Então você fez um bom trabalho testando casos de canto. :)
Cristian Lupascu
1

JavaScript ( ES6 ) 160

Não foi possível diminuir ...

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
fonte