Holzstücke verpacken


14

Es gibt zwei Holzstücke. Beide bestehen aus einem geraden Körper und einigen zusätzlichen Blöcken unterhalb des Körpers. Ein Beispielstück mit zusätzlichen Blöcken an (0-indizierten) Positionen 0,4,7,9,10:

XXXXXXXXXXX
X   X  X XX

Das Stück kann als 01binäre Sequenz dargestellt werden, wobei das idritte Zeichen angibt, ob sich an der idritten Position ein Block befindet . Das obere Beispiel kann als dargestellt werden10001001011 .

Wir können zwei Teile zusammenfügen, indem wir das zweite vertikal spiegeln (und vielleicht auch horizontal spiegeln). Nach dem Flip (s) finden wir eine Ausrichtung, in der die beiden Teile zu einer Höhe von 3 zusammengefügt werden können.

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

Das Beispiel ergab eine Gesamtbreite von 12 Blöcken.

Sie sollten ein Programm oder eine Funktion schreiben, die zwei Zeichenfolgen als Eingabe für die beiden Teile empfängt und eine Ganzzahl mit der minimal erreichbaren Breite ausgibt und einer Höhe von 3 .

Eingang

  • Zwei Zeichenfolgen bestehend aus den Zeichen 0und1 .
  • Beide Zeichenfolgen enthalten mindestens ein Zeichen.
  • Sie können die beiden Zeichenfolgen als eine Zeichenfolge empfangen, die durch ein einzelnes Leerzeichen verbunden ist.

Ausgabe

  • Eine einzelne positive ganze Zahl, die minimal erreichbare Gesamtbreite.

Beispiele

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

Dies ist Code Golf, also gewinnt der kürzeste Einstieg.


Soll das Stück im ersten Beispiel das Stück 1 im zweiten Teil des Beispiels sein? Wenn ja, dann ist einer von ihnen falsch.
mdc32

@ mdc32 Sie waren nicht die gleichen Teile, haben aber das erste geändert, um Verwirrung zu vermeiden.
Randomra

Antworten:


7

Pyth, 37 35 34 32 31 Bytes

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

Nimmt Eingabe-Newline getrennt.

Demonstration , Testgeschirr .

Erläuterung:

Auf der hohen Ebene verschieben wir für jede Kombination aus normaler und umgekehrter Zeichenfolge die zweite Zeichenfolge um eine bestimmte Anzahl von Positionen nach links und überprüfen, ob sie sich mit der ersten Zeichenfolge überschneidet. Dies wird wiederholt, bis ein Verschiebungsbetrag ohne Überlappungen gefunden wird. Dieser Verschiebungsbetrag wird zur Länge der ersten Zeichenfolge addiert und das Ergebnis mit der Länge der zweiten Zeichenfolge verglichen. Der höhere Wert wird gedruckt.

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

Pip , 72 70 48 Bytes

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

Nimmt die beiden Zeichenfolgen als Befehlszeilenargumente. Formatiert mit Kommentaren:

                     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)

Wir berechnen nur die Überlappungen, bei denen das untere Teil nach links absteht, also müssen wir es mit vertauschten oberen und unteren Teilen versuchen. Jedes Mal, wenn sich in der inneren Schleife keine 2en befinden, ist dies ein Fit. Wir heften dann eine weitere Null an das Ende des unteren Teils und versuchen es erneut.

   0010
    111
   0121

   0010
   111_
   1120

   0010
  111__
  11110

   0010
 111___
 111010

   0010
111____
1110010

Um die Gesamtbreite zu ermitteln, teilen wir die Elemente von pin Listen von Zeichen und Summe auf. Elementweise Operationen auf Listen mit ungerader Länge behalten die Länge der längeren bei, daher ist die Länge dieser Summe genau das, was wir brauchen. (Eine Aufteilung ist erforderlich, da durch einfaches Summieren als Zahlen führende Nullen entfernt werden:, $+[0101 10] = 111aber $+^[0101 10] = [0 1 1 1].)

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

3

Ruby 127 130

Dies stellte sich als so lang heraus ... :(

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

Tests: http://ideone.com/te8XWk

Lesbarer Rubin:

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

Könnten Sie die neu hinzugefügten Beispiele testen? Das [[m,n],[m,n.reverse],[n,m],[n,m.reverse]]Teil ist möglicherweise falsch. (Ich bin nicht sicher, aber ich habe einen ähnlichen Fehler gemacht.)
Randomra

@ Randomra Sicher! Bitte beachten Sie den Testlink; Ich habe dort die neuen Tests hinzugefügt.
Cristian Lupascu

Danke, Entschuldigung für den zusätzlichen Aufwand. Meine Intuition war, dass du [n.reverse,m]stattdessen brauchen würdest, [n,m.reverse]aber ich kenne Ruby nicht.
Randomra

@randomra tatsächlich, dass der Test mit dem '0010110111100', '001011010101001001100'Spruch Erwartet: 28, Tatsächlich: 30 fehlschlägt . Alle anderen Tests bestehen. Sie haben also gute Arbeit beim Testen von Eckfällen geleistet. :)
Cristian Lupascu

1

JavaScript ( ES6 ) 160

Könnte nicht kürzer machen ...

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>

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.