Ajude meu filho a encontrar suas cartas


17

fundo

Baseado em um jogo que meu filho de quatro anos ganhou do rabino.

O "objetivo" é "encontrar" as letras em uma determinada ordem, por exemplo aecdb. Você recebe uma pilha de cartas, por exemplo daceb. Você só pode pesquisar na pilha na ordem especificada, embora de forma cíclica. Quando você encontra uma carta de que precisa, tira-a da pilha.

Objetivo

Dada uma ordem e uma pilha (permutações livres de duplicatas), encontre a sequência das letras da pilha superior (é tudo ASCII imprimível) que você vê durante o jogo.

Exemplo passo a passo

Precisamos encontrar a ordem aecdb, dada a pilha daceb:

Topo da pilha d: Não é o que nós estamos procurando ( a), de modo que adicioná-lo à sequência: de girar para obter a pilha: acebd.

Topo da pilha a: Sim! assim nós adicioná-lo à sequência: dae removê-lo da pilha: cebd.

Topo da pilha c: Não é o que nós estamos procurando ( e), de modo que adicioná-lo à sequência: dace girar para obter a pilha: ebdc.

Topo da pilha e: Sim! assim nós adicioná-lo à sequência: dacee removê-lo da pilha: bdc.

Topo da pilha b: Não é o que nós estamos procurando ( c), de modo que adicioná-lo à sequência: dacebe girar para obter a pilha: dcb.

Topo da pilha d: Não é o que nós estamos procurando ( c), de modo que adicioná-lo à sequência: dacebde girar para obter a pilha: cbd.

Topo da pilha c: Sim! assim nós adicioná-lo à sequência: dacebdce removê-lo da pilha: bd.

Topo da pilha b: Não é o que nós estamos procurando ( d), de modo que adicioná-lo à sequência: dacebdcbe girar para obter a pilha: db.

Topo da pilha d: Sim! assim nós adicioná-lo à sequência: dacebdcbde removê-lo da pilha: b.

Topo da pilha b: Sim! assim nós adicioná-lo à sequência: dacebdcbdbe removê-lo da pilha: .

E nós terminamos. O resultado é dacebdcbdb.

Implementação de referência

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'))

Experimente online!

Casos de teste

try, yrtyrtyry

1234, 43214321432434

ABCDEFGHIJKLMNOPQRSTUVWXYZ, RUAHYKCLQZXEMPBWGDIOTVJNSFRUAHYKCLQZXEMPBWGDIOTVJNSFRUHYKCLQZXEMPWGDIOTVJNSFRUHYKLQZXEMPWGIOTVJNSFRUHYKLQZXMPWGIOTVJNSRUHYKLQZXMPWIOTVJNSRUYKLQZXMPWOTVNSRUYQZXPWOTVSRUYQZXPWTVSRUYQZXWTVSRUYZXWTVSUYZXWTVUYZXWVYZXWYZXYZ

?, ??

a, a a a

abcd, abcdabcd

Respostas:


5

Três métodos bastante diferentes estão fornecendo contagens iguais de bytes.

Python 2 , 59 bytes

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

Experimente online!

Imprime cada caractere em sua própria linha.


Python 2 , 59 bytes

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

Experimente online!

Pega listas como entrada e gera uma lista.


Python 3 , 59 bytes

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

Experimente online!


1
Hum, desconfio das duas primeiras versões ... por que 99especificamente?
Erik the Outgolfer

@EriktheOutgolger É pelo menos o número de caracteres ASCII imprimíveis e, pelo menos, o comprimento de cada entrada.
Xnor

5

APL (Dyalog Classic) , 21 bytes

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

Experimente online!

Este é um trem equivalente a {∊⍵,(⊂⍵)~¨(,\⍺⊂⍨1,2>/⍺⍋⍵)}

dá a permutação do argumento da direita no argumento da esquerda

1,2>/compare pares consecutivos com >e adicione um 1

⍺⊂⍨use a máscara booleana acima para dividir em grupos; 1s na máscara marcam o início de um novo grupo

,\ concatenações cumulativas dos grupos

(⊂⍵)~¨ complemento de cada um com relação a

⍵, preceder

achatar como uma única corda


4

Lote, 155 bytes

@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%

Leva o alvo e empilha como entradas no STDIN.


4

JavaScript (ES6), 54 bytes

Leva o alvo como uma sequência e a pilha como uma matriz de caracteres. Retorna uma string.

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

Casos de teste

Quão?

A cada iteração, extraímos o caractere cno topo da pilha e o anexamos ao resultado final. Em seguida, executamos uma chamada recursiva cujos parâmetros dependem do resultado de c == t[0], onde t[0]é o próximo caractere esperado.

Se ccorresponder t[0]:

  • removemos cda string de destino passandot.slice(1)
  • removemos cda pilha passando sinalterados

Se cnão corresponder t[0]:

  • deixamos a string de destino inalterada passando t.slice(0)
  • nós empurramos de cvolta no final da pilha



3

Haskell , 49 46 bytes

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

Experimente online!

Relativamente simples. O argumento da esquerda é o "objetivo" e o da direita é a pilha. Se a cabeça da meta corresponder ao topo da pilha, nós a precederemos e recorremos novamente ao restante da meta e à pilha (sem adicionar novamente o item na parte superior). Caso contrário, anexamos o item superior e recorremos com o mesmo objetivo, lendo o item superior até o final da pilha. Quando a meta está vazia, a correspondência de padrões escolhe a segunda linha e a lista vazia é retornada.

EDIT: -3 bytes graças a @GolfWolf e @Laikoni!





1
@GolfWolf, sua segunda solução (e a de Laikoni) não funciona. Ela produz "ytrty" em vez de "yrtyry" por causa da precedência do operador com (:) e (#)
user1472751

1

Limpo , 85 bytes

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[]

Experimente online!

Define a função parcial fassumida [Char]e [Char], onde o primeiro argumento é o destino e o segundo é a pilha.


1

Java 8, 88 bytes

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

Entradas como char[]e java.util.LinkedList<Character>( java.util.Queueimplementação)

Explicação:

Experimente 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 bytes

Edit: Teal pelican tem uma ><>abordagem muito melhor aqui que troca os métodos de entrada

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

Experimente online!

Leva a ordem das letras pela -sbandeira e a pilha pela entrada.

Como funciona:

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 bytes

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

Experimente online!

O fluxo foi alterado para utilizar os espaços vazios e remover o redirecionamento de código extra. (-5 bytes) - Graças a @JoKing

> <> , 21 bytes

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

Experimente online!

A outra resposta> <> pode ser encontrada aqui.

Explicação

A pilha começa com um conjunto inicial de caracteres usando o sinalizador -s. Entrada é a ordem de caracteres fornecida pelo usuário. Esta explicação seguirá o fluxo do código.

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 yeah, introduzindo-lo dessa forma faz mais sentido lol
Jo rei

Que tal 17 bytes ?
Jo rei

1
@JoKing - Muito boa mudança para fazer aqueles roteamento redundante ir embora, eu não pude resistir em tomar um byte extra fora embora: P
Teal pelicano

0

Perl, 62 bytes

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

Leva seu primeiro argumento, a ordem, como uma lista de caracteres, e o segundo, a pilha, como uma sequência.

Ungolfed:

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

Você já se perguntou para que servem todas essas variáveis ​​obscuras de expressão regular? Claramente, eles foram projetados para esse desafio exato. Combinamos com o personagem atual $x(que infelizmente precisa ser escapado caso seja um personagem especial de regex). Isso convenientemente divide a string em "antes da partida" $`, "a partida" $&e "após a partida" $'. Na busca cíclica, vimos claramente todos os personagens antes da partida e os colocamos de volta na pilha. Também vimos o personagem atual, mas não o colocamos de volta. Portanto, anexamos "antes da partida" à lista de "vistos" $ze construímos a pilha de "após a partida", seguida de "antes da partida".


0

SNOBOL4 (CSNOBOL4) , 98 bytes

	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

Experimente online!

Imprime cada letra em uma nova linha. Use esta versão para obter tudo para imprimir na mesma linha. Recebe a entrada como pilha e, em seguida, destino, separados por uma nova linha.

	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 bytes

Inclui +4para-lF

Dê entrada como em STDIN como destino e empilhe (esta é a ordem inversa dos exemplos):

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

Se você não se importa com uma nova linha final, isso 40funciona:

(echo daceb; echo aecdb) | perl -plE '$_=<>=~s%.%s/(.*)\Q$&//s;$_.=$1;$&%reg'
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.