Упаковка шматочків деревини


14

Є два шматки дерева. Обидва складаються з прямого тіла і деяких зайвих блоків нижче корпусу. Приклад шматка з додатковими блоками в (0-індексованих) позиціях 0,4,7,9,10:

XXXXXXXXXXX
X   X  X XX

Елемент може бути представлений у вигляді 01двійкової послідовності із iсимволом th, що показує, чи є блок у цьому iположенні. Верхній приклад може бути представлений як 10001001011.

Ми можемо скласти два шматки, вертикально перевернувши другий (а може і перевернути його по горизонталі). Після перегортання ми можемо знайти вирівнювання, де обидва шматки можна скласти разом, щоб мати висоту 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

Приклад призвів до загальної ширини 12 блоків.

Ви повинні написати програму або функцію, яка отримує два рядки як вхід, що представляє дві частини, і виводить ціле число мінімально досяжної ширини з висотою 3.

Вхідні дані

  • Дві рядки, що складаються з символів 0та 1.
  • Обидва рядки містять щонайменше один символ.
  • Ви можете вибрати два рядки як один, з'єднаний єдиним пробілом.

Вихідні дані

  • Єдине додатне ціле число, досяжна мінімальна загальна ширина.

Приклади

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

Це кодовий гольф, тому найкоротший запис виграє.


Чи належить деталь у першому прикладі бути частиною 1 у другій частині прикладу? Якщо так, то один з них помиляється.
mdc32

@ mdc32 Вони не були однаковими, але змінили перший, щоб уникнути плутанини.
randomra

Відповіді:


7

Pyth, 37 35 34 32 31 байт

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

Знімає введення нового рядка роздільним.

Демонстрація , тест-джгут .

Пояснення:

На високому рівні для кожної комбінації нормальних і перетворених рядків пересуваємо другий рядок вліво на задану кількість позицій і перевіряємо, чи не перекривається перший рядок. Це повторюється до тих пір, поки не буде знайдена сума зсуву без перекриттів. Ця сума зсуву додається до першої довжини рядка, а результат порівнюється з довжиною другої рядки. Більше значення друкується.

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.

4

Піп , 72 70 48 байт

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

Приймає два рядки як аргументи командного рядка. Відформатовано, з коментарями:

                     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)

Ми обчислюємо лише перекриття там, де нижній шматок стирчить зліва, тому нам потрібно спробувати це з виворітними як верхніми, так і нижніми частинами. Щоразу через внутрішню петлю, якщо в сумі немає 2-х, це підходить; ми приставляємо ще один нуль до кінця нижньої частини і намагаємося знову.

   0010
    111
   0121

   0010
   111_
   1120

   0010
  111__
  11110

   0010
 111___
 111010

   0010
111____
1110010

Щоб знайти загальну ширину, ми розділили елементи pна списки символів і підсумовуємо. Елементи операцій у списках нерівної довжини зберігають довжину більш тривалої, тому довжина цієї суми саме те, що нам потрібно. (Розщеплення потрібно, тому що просто підсумовування чисел усуне провідні нулі:, $+[0101 10] = 111але $+^[0101 10] = [0 1 1 1].)

C:\> pip.py woodPacking.pip 0010 111
5

3

Рубін 127 130

Це виявилося так довго ... :(

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

Тести: http://ideone.com/te8XWk

Читаний Ruby:

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

Чи можете ви протестувати нові додані приклади? [[m,n],[m,n.reverse],[n,m],[n,m.reverse]]Частина може бути неправильною. (Я не впевнений, але я допустив подібну помилку.)
randomra

@randomra Звичайно! Перегляньте посилання для тестування; Я там додав нові тести.
Крістіан Лупаску

Дякую, вибачте за зайві клопоти. Моя інтуїція полягала в тому, що вам знадобиться [n.reverse,m]замість цього, [n,m.reverse]але я не знаю Рубі.
випадкова

@randomra на самому ділі це не вдається тест '0010110111100', '001011010101001001100'вислів Очікуване: 28, Actual: 30 . Усі інші тести проходять. Отже, ви добре зробили тестування кутових корпусів. :)
Крістіан Лупаску

1

JavaScript ( ES6 ) 160

Неможливо скоротити ...

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>

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.