Programmare il robot impilatore di tazze


36

Sono sicuro che tutti hanno visto prima che le tazze possono essere impilate in piramidi (e altre forme):

           A    
        A A A   
 A     A A A A  
A A A A A A A A

Sì, Aè sicuramente un personaggio adeguato per rappresentare una tazza.

È possibile aggiungere nuove tazze a terra, a destra della struttura o in cima a due tazze adiacenti. Ecco di nuovo la struttura sopra, ma tutti i punti disponibili per le nuove tazze sono contrassegnati con _:

         _ A         
        A A A        
 A _ _ A A A A       
A A A A A A A A _ _ _

Diciamo che vogliamo costruire un robot in grado di assemblare queste pile di tazze. Il robot comprenderà due semplici istruzioni per manipolare tale struttura:

  • a: Aggiungi una nuova tazza nel primo punto disponibile nell'ordine di lettura da sinistra a destra (ovvero, scansiona le righe dall'alto verso il basso, da sinistra a destra fino a trovare un punto disponibile, quindi posiziona lì la tazza). L'esempio sopra sarebbe diventato:

             A A   
            A A A  
     A     A A A A 
    A A A A A A A A
    
  • r: Rimuovere la prima tazza nell'ordine di lettura da sinistra a destra. L'esempio sopra sarebbe diventato:

            A A A  
     A     A A A A 
    A A A A A A A A
    

Si scopre che qualsiasi struttura può essere costruita da zero usando solo queste due operazioni. Per esempio

      A
 A   A A
A A A A A

Può essere costruito con la sequenza di istruzioni

aaaaaaaaaaaarrrrraa

L'esempio più grande sopra può essere creato usando

aaaaaaaaaaaaaaaaaaaaaaaaaaaaaarrrrrrrrrrrrrrrrrraaaaaaarr

Eccone uno ancora più grande:

    A
   A A                   A
  A A A     A   A       A A
 A A A A   A A A A     A A A A
A A A A A A A A A A   A A A A A

che può essere costruito con

aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaarrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrraaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaarrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrraaaaaaaaaaaaaaaaaaarrrrrrrrrrrrrrraaaaaaaaaaaaaarrrrrrrrrrraaaaaaaa

Nota: se i punti sul terreno vengono liberati dalle istruzioni di rimozione, verranno riutilizzati prima di posizionare le tazze a destra di tutte le tazze esistenti. Per esempio

aaaarrra

cederà

A   A

non

    A A

Puoi pensare al terreno come se fosse in cima a una fila semi-infinita di tazze.

La sfida

Data una struttura di tazze impilate, restituisce una sequenza che rappresenta le istruzioni per costruire questa struttura. Il tuo punteggio principale è la somma dei numeri di istruzioni per i casi di test forniti in fondo. In caso di pareggio (che è probabile, perché sono convinto che sia possibile una soluzione ottimale efficiente), vince la soluzione più breve.

Ecco alcuni dettagli sulle regole:

  • Si può presumere che non ci siano spazi iniziali nella riga inferiore dell'input, quindi si deve sempre usare il punto più a sinistra per una tazza.
  • Puoi assumere qualsiasi ragionevole quantità di spazi finali (nessuno spazio, uno spazio, riempito con un rettangolo, riempito con un rettangolo con un singolo spazio finale).
  • Opzionalmente, è possibile aspettarsi che l'input termini in una sola nuova riga finale.
  • Puoi scegliere due caratteri ASCII stampabili distinti (da 0x20 a 0x7E, inclusi) invece di Ae spazi (le regole relative agli spazi vengono quindi trasferite al personaggio scelto).
  • L'output deve contenere solo due caratteri distinti che rappresentano le operazioni (è possibile scegliere altri caratteri oltre a ae r). Se lo si desidera, è possibile stampare una nuova riga finale.
  • Il tuo codice deve essere in grado di risolvere uno dei casi di test di seguito in meno di un minuto su un PC desktop ragionevole (se impiegherò due minuti al mio, ti darò il beneficio del dubbio, ma se impiegherò dieci ho vinto 't - credo che sia possibile un algoritmo ottimale che risolva qualcuno di loro in meno di un secondo).
  • Non è necessario ottimizzare il codice per i singoli casi di test (ad es. Codificandoli a piacere). Se sospetto che qualcuno lo faccia, mi riservo il diritto di modificare i casi di test.

Puoi usare questo script CJam per l'operazione inversa: ci vorranno una serie di istruzioni per la costruzione e stamperanno la pila di tazze risultante. (Grazie a Dennis per aver riscritto lo snippet e averlo notevolmente accelerato.)

Sp3000 ha anche gentilmente fornito questo script Python alternativo per lo stesso scopo.

Casi test

Dopo ogni caso di test, c'è un numero che indica il numero ottimale di istruzioni secondo la risposta di Ell.

                                       A
                                      A A
                                     A A A
                                    A A A A
                                   A A A A A
                                  A A A A A A
                                 A A A A A A A
                                A A A A A A A A
                               A A A A A A A A A
                              A A A A A A A A A A
                             A A A A A A A A A A A
                            A A A A A A A A A A A A
                           A A A A A A A A A A A A A
                          A A A A A A A A A A A A A A
                         A A A A A A A A A A A A A A A
                        A A A A A A A A A A A A A A A A
                       A A A A A A A A A A A A A A A A A
                      A A A A A A A A A A A A A A A A A A
                     A A A A A A A A A A A A A A A A A A A
                    A A A A A A A A A A A A A A A A A A A A
                   A A A A A A A A A A A A A A A A A A A A A
                  A A A A A A A A A A A A A A A A A A A A A A
                 A A A A A A A A A A A A A A A A A A A A A A A
                A A A A A A A A A A A A A A A A A A A A A A A A
               A A A A A A A A A A A A A A A A A A A A A A A A A
              A A A A A A A A A A A A A A A A A A A A A A A A A A
             A A A A A A A A A A A A A A A A A A A A A A A A A A A
            A A A A A A A A A A A A A A A A A A A A A A A A A A A A
           A A A A A A A A A A A A A A A A A A A A A A A A A A A A A
          A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A
         A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A
        A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A
       A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A
      A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A
     A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A
    A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A
   A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A
  A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A
 A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A
A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A

820
                                             A
                                            A A
                                           A A A
                                          A A A A
                                         A A A A A
                                        A A A A A A
                                       A A A A A A A
                                      A A A A A A A A
                     A               A A A A A A A A A
                    A A             A A A A A A A A A A
                   A A A           A A A A A A A A A A A
                  A A A A         A A A A A A A A A A A A
         A       A A A A A       A A A A A A A A A A A A A
        A A     A A A A A A     A A A A A A A A A A A A A A
   A   A A A   A A A A A A A   A A A A A A A A A A A A A A A
A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A

1946

               A
              A A
             A A A
            A A A A
           A A A A A
          A A A A A A
         A A A A A A A
        A A A A A A A A
       A A A A A A A A A               A
      A A A A A A A A A A             A A
     A A A A A A A A A A A           A A A
    A A A A A A A A A A A A         A A A A
   A A A A A A A A A A A A A       A A A A A       A
  A A A A A A A A A A A A A A     A A A A A A     A A
 A A A A A A A A A A A A A A A   A A A A A A A   A A A   A
A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A

2252

                                                         A A
                                                      A A A A
                                                   A A A A A A
                                                A A A A A A A A
                                             A A A A A A A A A A
                                          A A A A A A A A A A A A
                                       A A A A A A A A A A A A A A
                                    A A A A A A A A A A A A A A A A
                                 A A A A A A A A A A A A A A A A A A
                              A A A A A A A A A A A A A A A A A A A A
                           A A A A A A A A A A A A A A A A A A A A A A
                        A A A A A A A A A A A A A A A A A A A A A A A A
                     A A A A A A A A A A A A A A A A A A A A A A A A A A
                  A A A A A A A A A A A A A A A A A A A A A A A A A A A A
               A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A
            A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A
         A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A
      A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A
   A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A
A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A

9958

                   A A
                  A A A A
                 A A A A A A
                A A A A A A A A
               A A A A A A A A A A
              A A A A A A A A A A A A
             A A A A A A A A A A A A A A
            A A A A A A A A A A A A A A A A
           A A A A A A A A A A A A A A A A A A
          A A A A A A A A A A A A A A A A A A A A
         A A A A A A A A A A A A A A A A A A A A A A
        A A A A A A A A A A A A A A A A A A A A A A A A
       A A A A A A A A A A A A A A A A A A A A A A A A A A
      A A A A A A A A A A A A A A A A A A A A A A A A A A A A
     A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A
    A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A
   A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A
  A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A
 A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A
A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A

5540

A   A   A   A   A   A   A   A   A   A   A   A   A   A   A   A   A   A   A   A

10280

 A   A   A   A   A   A   A   A   A   A   A   A   A   A   A   A   A   A   A   A
A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A

10320

   A       A       A       A       A       A       A       A       A       A
  A A     A A     A A     A A     A A     A A     A A     A A     A A     A A
 A A A   A A A   A A A   A A A   A A A   A A A   A A A   A A A   A A A   A A A
A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A

5794

              A
             A A
            A A A
           A A A A                                               A
          A A A A A                                             A A
         A A A A A A A                                         A A A
        A A A A A A A A               A                       A A A A
       A A A A A A A A A             A A             A       A A A A A   A
      A A A A A A A A A A           A A A           A A     A A A A A A A A
     A A A A A A A A A A A         A A A A         A A A   A A A A A A A A A
    A A A A A A A A A A A A       A A A A A       A A A A A A A A A A A A A A
 A A A A A A A A A A A A A A     A A A A A A     A A A A A A A A A A A A A A A
A A A A A A A A A A A A A A A   A A A A A A A   A A A A A A A A A A A A A A A A

3297

                                                   A A
                                                  A A A
                                                 A A A A
                                                A A A A A
                                               A A A A A A
                                              A A A A A A A
                                             A A A A A A A A
                                            A A A A A A A A A
                                           A A A A A A A A A A     A
                                          A A A A A A A A A A A   A A
                                       A A A A A A A A A A A A A A A A
                                      A A A A A A A A A A A A A A A A A
                                     A A A A A A A A A A A A A A A A A A
      A                             A A A A A A A A A A A A A A A A A A A
     A A                           A A A A A A A A A A A A A A A A A A A A
    A A A             A A         A A A A A A A A A A A A A A A A A A A A A
   A A A A           A A A       A A A A A A A A A A A A A A A A A A A A A A
  A A A A A         A A A A     A A A A A A A A A A A A A A A A A A A A A A A
 A A A A A A     A A A A A A   A A A A A A A A A A A A A A A A A A A A A A A A
A A A A A A A   A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A

4081

                      A
                     A A       A                     A
                    A A A     A A                   A A A                 A
             A     A A A A   A A A A               A A A A     A         A A
  A         A A   A A A A A A A A A A         A   A A A A A   A A       A A A
 A A       A A A A A A A A A A A A A A       A A A A A A A A A A A     A A A A
A A A   A A A A A A A A A A A A A A A A     A A A A A A A A A A A A   A A A A A

4475

                                                             A              
      A           A                       A                 A A A   A       A
     A A         A A   A         A A     A A A   A         A A A A A A     A A
A   A A A A A   A A A A A   A   A A A   A A A A A A   A   A A A A A A A   A A A

5752

Ciò significa che il miglior punteggio possibile è 64.515 istruzioni.

Risposte:


32

Python 2, 64.515

import sys

input = map(str.rstrip, sys.stdin.readlines())
width = (len(input[-1]) + 1) / 2
for i in range(len(input)):
    indent = len(input) - i - 1
    input[i] = [c != " " for c in input[i][indent::2]]
    input[i] += [False] * (width - indent - len(input[i]))
input = [[False] * n for n in range(width - len(input) + 1)] + input
working_area = [[False] * n for n in range(width + 1)]

def add():
    sys.stdout.write("a")
    for row in range(width + 1):
        for i in range(row):
            if not working_area[row][i] and (
                row == width or
                (working_area[row + 1][i] and working_area[row + 1][i + 1])
            ):
                working_area[row][i] = True
                return
def remove():
    sys.stdout.write("r")
    for row in range(width + 1):
        if True in working_area[row]:
            working_area[row][working_area[row].index(True)] = False
            return

for row in range(width, -1, -1):
    r = input[row]; R = working_area[row]
    for i in range(len(r) - 1, -1, -1):
        if r[i]:
            while not R[i]: add()
        else:
            while R[i]: remove()

risultati

Test 1 # 1 - 820 # 2 - 1.946 # 3 - 2.252 # 4 - 9.958 # 5 - 5.540 # 6 - 10.280 # 7 - 10.320 # 8 - 5.794 # 9 - 3.297 # 10 - 4.081 # 11 - 4.475 # 12 - 5.752Test 2 Test 3
Test 4 Test 5 Test 6
Test 7 Test 8 Test 9
Test 10 Test 11 Test 12

Totale 64.515

Spiegazione

Iniziamo con una "area di lavoro" vuota. Scansioniamo l'ingresso in ordine di lettura inversa , cioè da destra a sinistra e dal basso verso l'alto. Se c'è una discrepanza tra l'ingresso e l'area di lavoro nella posizione corrente (ovvero, è presente una tazza nell'input ma non nell'area di lavoro, o viceversa), aggiungeremo o rimuoviamo le tazze nell'area di lavoro, secondo alle regole, fino a quando la discrepanza non viene risolta, a quel punto continuiamo alla posizione successiva.

Correttezza

Per dimostrare che questo metodo è corretto, cioè che la sequenza risultante genera la struttura di input, è sufficiente mostrare che non modifichiamo mai (cioè, aggiungiamo o rimuoviamo tazze in) posizioni che abbiamo già visitato (poiché, in ogni posizione che visitiamo , ci assicuriamo che l'area di lavoro corrisponda all'input.) Questa è una facile conseguenza del fatto che lavoriamo nell'ordine inverso in cui le tazze vengono aggiunte e rimosse:

  • Una tazza in posizione l sarà sempre essere rimosso prima una tazza in una posizione che riesce l in ordine di lettura, e quindi, che precede l in ordine di scansione, quindi non c'è pericolo di rimozione di una tazza che abbiamo già visitato.
  • Allo stesso modo, una tazza nella posizione l verrà sempre aggiunta prima di una tazza che la precede nell'ordine di scansione, dato che ci sono già due tazze al di sotto di essa (o che è nella parte inferiore); tuttavia, poiché avremo già visitato queste posizioni e quindi aggiunto le tazze necessarie e poiché, come notato sopra, non vi è alcun pericolo di averle rimosse in seguito, questa condizione è soddisfatta e quindi non c'è pericolo di aggiungere una tazza a un luogo che abbiamo già visitato.

ottimalità

Si noti che l'effetto di aggiungere o rimuovere una tazza da una struttura non dipende dalla sequenza di operazioni utilizzate per generare la struttura, ma solo dalla sua configurazione corrente. Di conseguenza, data una sequenza ottimale S n = { s 1 , ..., s n } di operazioni che generano una determinata struttura, ogni segmento iniziale di S n , cioè qualsiasi sequenza S m = { s 1 , .. ., s m }, dove mn , è anche una sequenza ottimale, per la struttura corrispondente che genera, altrimenti ci sarebbe una sequenza più breve di S n, generando la stessa struttura.

Possiamo dimostrare che il nostro metodo è ottimale per induzione sulla lunghezza della sequenza generativa ottimale: Il nostro metodo genera chiaramente una sequenza ottimale per qualsiasi struttura la cui sequenza generativa ottimale è vuota (esiste solo una di queste strutture: la struttura vuota). Supponiamo che il nostro Il metodo genera una sequenza ottimale per tutte le strutture la cui sequenza (o sequenze) ottimale è di lunghezza n e considera una struttura generata da una sequenza ottimale S n +1 . Vogliamo dimostrare che, data la struttura generata da S n +1 come input, il nostro metodo produce la stessa sequenza (o, almeno, una sequenza della stessa lunghezza).

Come notato sopra, S n è anche una sequenza ottimale, e quindi, per ipotesi, il nostro metodo produce una sequenza ottimale data la struttura generata da S n come input. Supponiamo, senza perdita di generalità, che S n sia la sequenza prodotta dal nostro metodo (in caso contrario, possiamo sempre sostituire i primi n elementi di S n +1 con detta sequenza e ottenere una sequenza di lunghezza n + 1 che genera la stessa struttura.) sia l essere la posizione modificata dall'ultima operazione S n + 1 (cioè, s n + 1 ), e lasciareS m è il segmento iniziale di S n , che il nostro programma avrà prodotto una volta raggiunto l (ma prima di elaborare l ). Si noti che, poiché le strutture generate da S n e S n +1 concordano in tutte le posizioni che seguono l , in ordine di lettura, S m è la stessa data in entrambe le strutture come input.

Se s n +1 è a(cioè aggiunta della tazza), allora non ci deve essere alcuna posizione precedente a l , nell'ordine di lettura, in cui una tazza può essere aggiunta alla struttura generata da S n . Di conseguenza, la sottosequenza di S n che segue S m deve essere tutto a(poiché rciò implicherebbe che c'è uno spazio vuoto prima di l , o che S n non è ottimale.) Quando arriviamo al processo l , avremo bisogno di aggiungi esattamente n - m tazze prima di poter aggiungere una tazza a l , quindi la sequenza risultante sarà Sm , seguito da n - m + 1aelementi, che equivale a S n +1 (non ci sarà alcuna discrepanza dopo questo punto, quindi questa è la sequenza completa prodotta.)

Allo stesso modo, se s n +1 è r, allora non ci deve essere alcuna coppa in una posizione che precede l , in ordine di lettura, nella struttura generata da S n . Di conseguenza, la sottosequenza di S n che segue S m deve essere tutta r. Quando arriviamo al processo l , dovremo rimuovere esattamente n - m tazze prima di poter rimuovere la tazza in l , quindi la sequenza risultante sarà S m , seguita da n - m + 1 relementi, che equivale di nuovo a S n +1 .

In altre parole, il nostro metodo produce una sequenza ottimale per detta struttura di input, e quindi, per induzione, per qualsiasi struttura di input.

Si noti che ciò non significa che questa implementazione sia la più efficiente. È sicuramente possibile, ad esempio, calcolare il numero di tazze che devono essere aggiunte o rimosse, in ogni punto direttamente, invece di eseguire effettivamente queste operazioni.

Unicità

Possiamo usare l'ottimalità del nostro metodo per mostrare che le sequenze ottimali sono, in effetti, uniche (cioè che non esistono due distinte sequenze ottimali che generano la stessa struttura). Usiamo, di nuovo, l'induzione sulla dimensione della sequenza generatrice ottimale: La sequenza vuota è ovviamente l'unica sequenza generatrice ottimale della struttura vuota. Supponiamo che tutte le sequenze di generazione ottimali di lunghezza n siano uniche e consideri una struttura, Σ, generata dalle due sequenze ottimali S n +1 e T n +1 .

Ricordiamo che S n e T n sono essi stessi ottimali, e quindi, per ipotesi, unici. Poiché il nostro metodo produce sequenze ottimali, S n e T n possono essere considerati generati dal nostro metodo. Lasciate l S e L T sia le sedi modificate dall'ultima operazione S n + 1 e T n + 1 , rispettivamente, e supponiamo, senza perdita di generalità, che l S segue, o uguale, l T in ordine di lettura. Dal momento che le strutture generate da S ne T n concordano in tutte le posizioni dopo l S , in ordine di lettura, la sequenza prodotta dal nostro metodo, data una struttura come input, una volta raggiunta l S (ma prima di elaborarla), è la stessa per entrambe; chiamare questa sequenza U .

Poiché l'ultima azione di S n +1 modifica l S , se Σ ha una tazza a l S allora non ci deve essere alcun posto vacante prima di l S , e se Σ non ha una tazza a l S, allora non deve esserci alcun tazza prima l S , in ordine di lettura. Pertanto, il resto della generatrice Σ sequenza, seguendo U , deve consistere di applicazione ripetuta la stessa istruzione, dettata dalla presenza o assenza di una tazza a l S (altrimenti non sarebbe ottimale). In altre parole, S n +1 e T n +1sono uguali (entrambi iniziano con U e terminano con la sequenza di istruzioni ripetute), ovvero la sequenza di generazione ottimale di Σ è unica, quindi, per induzione, tutte le sequenze di generazione ottimali sono uniche.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.