Aiuta mio figlio a trovare le sue lettere


17

sfondo

Basato su un gioco che il mio bambino di quattro anni ha ricevuto dal suo rabbino.

L '"obiettivo" è "trovare" le lettere in un determinato ordine, ad es aecdb. Ti viene data una pila di carte lettera, ad es daceb. Puoi cercare nello stack solo nell'ordine indicato, anche se ciclicamente. Quando incontri una lettera che ti serve, la togli dalla pila.

Obbiettivo

Dato un ordine e una pila (permutazioni duplicate senza reciprocità), trova la sequenza di lettere in cima alla pila (è tutta ASCII stampabile) che vedi mentre giochi.

Esempio passo-passo

Dobbiamo trovare l'ordine aecdb, dato lo stack daceb:

Cima alla pila d: Non quello che stiamo cercando ( a), in modo da aggiungiamo alla sequenza: de ruotare per ottenere lo stack: acebd.

Top of stack a: Sì! in modo da aggiungiamo alla sequenza: dae rimuoverlo dalla pila: cebd.

Cima alla pila c: Non quello che stiamo cercando ( e), in modo da aggiungiamo alla sequenza: dace ruotare per ottenere lo stack: ebdc.

Top of stack e: Sì! in modo da aggiungiamo alla sequenza: dacee rimuoverlo dalla pila: bdc.

Cima alla pila b: Non quello che stiamo cercando ( c), in modo da aggiungiamo alla sequenza: dacebe ruotare per ottenere lo stack: dcb.

Cima alla pila d: Non quello che stiamo cercando ( c), in modo da aggiungiamo alla sequenza: dacebde ruotare per ottenere lo stack: cbd.

Top of stack c: Sì! in modo da aggiungiamo alla sequenza: dacebdce rimuoverlo dalla pila: bd.

Cima alla pila b: Non quello che stiamo cercando ( d), in modo da aggiungiamo alla sequenza: dacebdcbe ruotare per ottenere lo stack: db.

Top of stack d: Sì! in modo da aggiungiamo alla sequenza: dacebdcbde rimuoverlo dalla pila: b.

Top of stack b: Sì! in modo da aggiungiamo alla sequenza: dacebdcbdbe rimuoverlo dalla pila: .

E abbiamo finito. Il risultato è dacebdcbdb.

Implementazione di riferimento

def letters(target, stack):
    string = ''
    while stack:
        string += stack[0]
        if stack[0] == target[0]:
            stack.pop(0)
            target = target[1:]
        else:
            stack.append(stack.pop(0))
    return string

print letters('aecdb', list('daceb'))

Provalo online!

Casi test

try, yrtyrtyry

1234, 43214321432434

ABCDEFGHIJKLMNOPQRSTUVWXYZ, RUAHYKCLQZXEMPBWGDIOTVJNSFRUAHYKCLQZXEMPBWGDIOTVJNSFRUHYKCLQZXEMPWGDIOTVJNSFRUHYKLQZXEMPWGIOTVJNSFRUHYKLQZXMPWGIOTVJNSRUHYKLQZXMPWIOTVJNSRUYKLQZXMPWOTVNSRUYQZXPWOTVSRUYQZXPWTVSRUYQZXWTVSRUYZXWTVSUYZXWTVUYZXWVYZXWYZXYZ

?, ??

a, a a a

abcd, abcdabcd

Risposte:


5

Tre metodi abbastanza diversi stanno dando conteggi di byte uguali.

Python 2 , 59 byte

s,t=input()
for c in s*99:
 if c in t:print c;t=t.lstrip(c)

Provalo online!

Stampa ogni personaggio nella sua riga.


Python 2 , 59 byte

lambda s,t:[c==t[0]and t.pop(0)or c for c in s*99if c in t]

Provalo online!

Accetta gli elenchi come input e genera un elenco.


Python 3 , 59 byte

def f(s,t):
 for c in t:p,q=s.split(c);s=q+p;print(end=p+c)

Provalo online!


1
Hm, sono sospettoso delle prime due versioni ... perché nello 99specifico?
Erik the Outgolfer,

@EriktheOutgolger È almeno il numero di caratteri ASCII stampabili, e quindi lo è almeno la lunghezza di ciascun input.
xnor

5

APL (Dyalog Classic) , 21 byte

∊⊢,⊢∘⊂~¨(,\⊣⊂⍨1,2>/⍋)

Provalo online!

Questo è un treno equivalente a {∊⍵,(⊂⍵)~¨(,\⍺⊂⍨1,2>/⍺⍋⍵)}

fornisce la permutazione dell'argomento destro nell'argomento sinistro

1,2>/confrontare coppie consecutive con >e anteporre un 1

⍺⊂⍨usa la maschera booleana sopra per dividere in gruppi; 1s nella maschera segna l'inizio di un nuovo gruppo

,\ concatenazioni cumulative dei gruppi

(⊂⍵)~¨ complemento di ciascuno rispetto a

⍵, anteporre

appiattire come una singola stringa


4

Lotto, 155 byte

@set/pt=
@set/ps=
@set r=
:l
@set c=%s:~,1%
@set r=%r%%c%
@if %c%==%t:~,1% set t=%t:~1%&set c=
@set s=%s:~1%%c%
@if not "%t%"=="" goto l
@echo %r%

Prende il bersaglio e lo stack come input su STDIN.


4

JavaScript (ES6), 54 byte

Prende il bersaglio come stringa e lo stack come matrice di caratteri. Restituisce una stringa.

f=(t,[c,...s])=>t&&c+f(t.slice(c==t[0]||!s.push(c)),s)

Casi test

Come?

Ad ogni iterazione, estraiamo il personaggio cin cima alla pila e lo aggiungiamo al risultato finale. Quindi eseguiamo una chiamata ricorsiva i cui parametri dipendono dal risultato di c == t[0], dove t[0]è il prossimo personaggio previsto.

Se ccorrisponde t[0]:

  • rimuoviamo cdalla stringa di destinazione passandot.slice(1)
  • rimuoviamo cdallo stack passando sinvariato

Se cnon corrisponde t[0]:

  • lasciamo invariata la stringa target passando t.slice(0)
  • torniamo cindietro alla fine della pila



3

Haskell , 49 46 byte

q@(a:b)#(c:d)|a==c=a:b#d|e<-d++[c]=c:q#e
a#_=a

Provalo online!

Abbastanza semplice. L'argomento di sinistra è "l'obiettivo" e quello di destra è lo stack. Se il capo dell'obiettivo corrisponde alla parte superiore dello stack, lo anteponiamo e ricominciamo con il resto dell'obiettivo e lo stack (senza aggiungere nuovamente l'elemento in cima). Altrimenti anteponiamo l'articolo in cima e ci ripetiamo con lo stesso obiettivo, leggendo l'oggetto in cima alla fine della pila. Quando l'obiettivo è vuoto, la corrispondenza del modello sceglie la seconda riga e viene restituita la lista vuota.

EDIT: -3 byte grazie a @GolfWolf e @Laikoni!





1
@GolfWolf la tua seconda soluzione (e quella di Laikoni) non funziona. Produce "ytrty" invece di "yrtyry" a causa della precedenza dell'operatore con (:) e (#)
user1472751

1

Pulito , 85 byte

import StdEnv
g l[u:v][a:b]|a==u=g[a:l]v b=g[a:l][u:v](b++[a])
g l[]_=reverse l
f=g[]

Provalo online!

Definisce la funzione parziale che fprende [Char]e [Char], dove il primo argomento è il bersaglio e il secondo è lo stack.


1

Java 8, 88 byte

a->b->{for(int c:a)for(char t=0;c!=t;System.out.print(t)){t=b.poll();if(c!=t)b.add(t);}}

Input come char[]e java.util.LinkedList<Character>( java.util.Queueimplementazione)

Spiegazione:

Provalo online.

a->b->{                        // Method with two parameters and no return-type
  for(int c:a)                 //  Loop over the characters of the char-array
    for(char t=0;c!=t;         //   Inner loop until we've found the character in the queue
        System.out.print(t)){  //     After every iteration: print the char `t`
      t=b.poll();              //    Remove the top of the queue, and save it in `t`
      if(c!=t)                 //    If this is not the character we're looking for:
        b.add(t);}}            //     Add it at the end of the queue again

1

> <> , 38 32 byte

Modifica: il pellicano verde acqua ha un ><>approccio molto migliore qui che scambia i metodi di input

0[i:0(1$.
\~~l]1+{$[&
/?=&:&:o:{

Provalo online!

Prende l'ordine delle lettere attraverso la -sbandiera e la pila attraverso l'input.

Come funziona:

0[.... Creates a new empty stack
...... This puts the order of the letters safely away
......

..i:0(1$. Takes input until EOF (-1). This means input is in reverse
..~...    And then teleports to the ~ on this line
......

......      Gets the first character from the beginning of the order
\.~l]1+{$[& And stores it in the register before going to the next line
/.....

......     Output the bottom of the stack
......     Checks if the bottom of the stack is equal to the current character
/?=&:&:o:{ If so, go to the second line, else cycle the stack and repeat

0.....      Pop the extra 0 we collected
\~~l]1+{$[& Pop the value that was equal and get the next character from the order
/.....      And go down to the last line. This will end with an error (which could be avoid with a mere 4 extra bytes


1

> <> , 21 16 byte

i$\~~
=?\$:{::o@

Provalo online!

Il flusso è stato modificato per utilizzare gli spazi vuoti e rimuovere il reindirizzamento del codice aggiuntivo. (-5 byte) - Grazie a @JoKing

> <> , 21 byte

i:{:@=?v:o$!
o~i00. >

Provalo online!

L'altra> <> risposta può essere trovata qui.

Spiegazione

Lo stack inizia con un set iniziale di caratteri usando il flag -s. L'input è l'ordine dei caratteri fornito dall'utente. Questa spiegazione seguirà il flusso del codice.

i$\        : Take input, swap the top 2 stack items then move to line 2;
             [1,2,3] -> [1,2,4,3]
  \$:      : Swap the top 2 stack items then duplicate the top item;
             [1,2,4,3] -> [1,2,3,4,4]
     {::o  : Move the stack items 1 left then duplicate the stack top twice and print one;
             [1,2,3,4,4] -> [2,3,4,4,1,1]
=?\      @ : Swap the top three stack items left 1 then do an equal comparison, if equality move to line 1 else continue;
             [2,3,4,4,1,1] -> [2,3,4,1,1,4] -> [2,3,4,1]
  \~~      : Remove the top 2 stack items;
             [2,3,4,1] -> [2,3]

Oh sì, inserirla in questo modo ha più senso lol
Jo King,

Che ne dici di 17 byte ?
Jo King,

1
@JoKing - Molto bello il cambiamento per far sparire quel routing ridondante, ma non ho potuto resistere togliendo un byte extra: P
Pellicano

0

Perl, 62 byte

sub{$_=$_[1];for$x(@{$_[0]}){/\Q$x\E/;$z.="$`$&";$_="$'$`"}$z}

Prende il suo primo argomento, l'ordine, come un elenco di caratteri e il suo secondo, lo stack, come una stringa.

Ungolfed:

sub {
    $_ = $_[1];
    for $x (@{$_[0]}) {
        /\Q$_\E/;
        $z.="$`$&";
        $_ = "$'$`"
    }
    $z
}

Ti sei mai chiesto a cosa servissero tutte quelle oscure variabili regex? Chiaramente, sono stati progettati per questa sfida esatta. Corrispondiamo al personaggio attuale $x(che purtroppo deve essere evaso nel caso si tratti di un personaggio speciale regex). Ciò divide convenientemente la stringa in "prima della corrispondenza" $`, "la corrispondenza" $&e "dopo la corrispondenza" $'. Nella ricerca ciclica, abbiamo visto chiaramente tutti i personaggi prima della partita e li abbiamo rimessi in pila. Abbiamo anche visto il personaggio attuale, ma non lo abbiamo rimesso. Quindi aggiungiamo "prima della partita" all'elenco "visto" $ze costruiamo lo stack di "dopo la partita" seguito da "prima della partita".


0

SNOBOL4 (CSNOBOL4) , 98 byte

	S =INPUT
	L =INPUT
R	S LEN(1) . X REM . S	:F(END)
	OUTPUT =X
	L POS(0) X =	:S(R)
	S =S X	:(R)
END

Provalo online!

Stampa ogni lettera su una riga. Usa questa versione per stampare tutto sulla stessa riga. Accetta input come stack, quindi target, separati da una nuova riga.

	S =INPUT			;*read stack
	L =INPUT			;*read letters
R	S LEN(1) . X REM . S	:F(END)	;*set X to the first letter of S and S to the remainder. If S is empty, goto END.
	OUTPUT =X			;*output X
	L POS(0) X =	:S(R)		;*if the first character of L matches X, remove it and goto R
	S =S X	:(R)			;*else put X at the end of S and goto R
END

0

Perl, 44 byte

Include +4per-lF

Fornisci input come su STDIN come target quindi impila (questo è l'ordine inverso rispetto agli esempi):

(echo daceb; echo aecdb) | perl -lF -E '$a=<>;say,$a=~s/^\Q$_//||push@F,$_ for@F'

Se non ti dispiace una nuova riga finale 40funziona:

(echo daceb; echo aecdb) | perl -plE '$_=<>=~s%.%s/(.*)\Q$&//s;$_.=$1;$&%reg'
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.