Intérprete de manipulação de string

11

Sumário

Uma nova linguagem de manipulação de strings foi criada, usando apenas os caracteres $+#-!*|@>! Sua tarefa é implementar um intérprete para ele no menor número possível de bytes.

Entrada

Uma string, que é uma única linha desse idioma. Isso pode ser tomado de qualquer maneira razoável (stdin, parâmetro de função, argumento de linha de comando etc.) ou como uma variável predefinida. Se o programa solicitar entrada do usuário, aceite todas as entradas solicitadas pelo stdin e nada mais, veja abaixo. Você pode assumir que é um programa válido.

Resultado

Qualquer que seja o idioma, especificações abaixo. Você deve gerar uma string, de qualquer maneira razoável (stdout, saída da função etc.) ou um valor variável. Quando o idioma sai explicitamente, isso deve ir para stdout. As brechas padrão são proibidas.

Especificações de idioma

Processamento e sintaxe

A linguagem possui uma forma muito simples de processamento, pois apenas manipula as strings: começa com uma string vazia ( "") e muda a cada termo. Um termo é composto de uma ou duas partes: uma função (abaixo) seguida de possivelmente um parâmetro (abaixo), que edita seu comportamento. Os termos são separados por pipes ( |). Você pode supor que não será um programa vazio e nenhum termo estará vazio. Você deve gerar o valor no final do programa.

Funções

O idioma possui apenas 6 funções, como mostrado abaixo. Cada função aceita um ou zero parâmetros.

  • + concatenar strings (pega um parâmetro de string, concatena com o valor atual)
  • ! reverter a ordem de caracteres do valor atual (sem parâmetro)
  • * repita a string (pega um parâmetro inteiro, repete o valor atual várias vezes)
  • - remove todas as ocorrências de um valor (pega um parâmetro de string, remove todas as ocorrências dele do valor atual)
  • $ [pseudo-] embaralha aleatoriamente o valor atual (sem parâmetro)
  • <gera o valor atual para stdout(sem parâmetros)

Valores

Estes são os valores que podem ser passados ​​para funções, representados por regex que os corresponderia:

  • @[^|]*uma string literal, incluindo qualquer caractere que não seja pipes. Pode estar vazio.
  • #[0-9]+ um literal inteiro
  • >a próxima linha de stdin. Se usado com *, converta para número inteiro.

Casos de teste

╔════════════════════════╤═════════════╤══════════════╗
║code                    │input        │output        ║
╟────────────────────────┼─────────────┼──────────────╢
║+>|!|+@hello|*>         │13           │31hello31hello║
║                        │2            │              ║
╟────────────────────────┼─────────────┼──────────────╢
║+>|+@abcdefg|$          │hello        │hcloeebafdlg  ║
╟────────────────────────┼─────────────┼──────────────╢
║+@how areyou|-@o|->     │w            │h areyu       ║
╟────────────────────────┼─────────────┼──────────────╢
║+@out|<|*#3             │             │out           ║
║                        │             │outoutout     ║
╟────────────────────────┼─────────────┼──────────────╢
║+>                      │what ever 345│what ever 345 ║
╟────────────────────────┼─────────────┼──────────────╢
║+@$pe<i@l|<|-@$pe<i@l|+>│A|$o $pe<!@| │$pe<i@l       ║
║                        │             │A|$o $pe<!@|  ║
╟────────────────────────┼─────────────┼──────────────╢
║<|+>|!|<                │input text   |              ║
║                        │             │txet tupni    ║ 
║                        │             │txet tupni    ║
╟────────────────────────┼─────────────┼──────────────╢
║+@>#                    │             |>#            ║
╚════════════════════════╧═════════════╧══════════════╝

Observe que o caso de teste 2 é aleatório, portanto, qualquer permutação dos caracteres nele é válida. Além disso, as saídas na tabela são separadas por novas linhas, mas seu programa não precisa fazer o mesmo. O último valor em cada caso, a saída final.

Exemplo (intérprete de python)

Experimente online! IMO melhor se você executá-lo através do IDLE ou o que você usar. (Joguei até 424 bytes depois, mas tenho certeza de que você pode fazer melhor).

Artemis ainda não confia em SE
fonte
2
Permitir que a entrada já esteja em uma variável não é padrão, assim como permitir que a saída esteja em uma.
Jonathan Allan
Seus exemplos parecem imprimir uma nova linha sempre que <são encontrados. Isso é obrigatório?
Modalidade de ignorância
O programa terá novas linhas? Porque se ele pode, ele invalida a resposta de Chas Brown
Personificação da Ignorância
2
Para suas dúvidas futuras, considere evitar formatos de E / S complicados . Limitar a entrada ao stdin custa bytes extras em alguns idiomas e não traz muito para o desafio.
Arnauld
1
@digEmAll Como é que eu acabei de adicionar +@>#? Eu costumava #também.
Artemis ainda não confia em

Respostas:

3

Ruby -palF\| , 146 142 bytes

r='';$F.map{|i|x=i[1]!=?>?i[2..-1]:gets.chomp;eval %w[r.reverse! r*=x.to_i 0 $><<r r=r.chars.shuffle*'' r.gsub!x,'' r+=x][i[0].ord*5%11]};$_=r

Experimente online!

Resposta Python do porto de Chas Brown . Não imprime novas linhas após a saída.

Como sempre, a versão Ruby 2.6 será 2 bytes mais curta com indexação de intervalo sem fim ( i[2..]).

Kirill L.
fonte
6

R , 287 286 273 269 bytes

function(C,x='',`[`=gsub,`!`=intToUtf8,`?`=utf8ToInt){for(k in el(strsplit(C,'\\|'))){B=eval(parse(t='^.'['','(?<=.)>$'['readLines(,1)','[@#](.+)'['"\\1"',k],,T]]));x=switch((?substr(k,1,1))%%13-2,strrep(x,B),paste0(x,B),,B['',x,f=T],!rev(?x),print(x),,!sample(?x))};x}

Experimente online!

  • -1 graças a @Kirill L.
  • -4 graças a @Giuseppe

Código desenrolado e explicação:

function(C){                                      # C is the string manipulation expression
  x = ''                                          # initialize x = ''
  tokens = el(strsplit(C,'\\|'))                  # split C by pipe '|'
  for(k in tokens){                               # for each token k
    arg2 = k
    arg2 = gsub('[@#](.+)','"\\1"',k)             # replace @X or #X with "X" (in quotes)
    arg2 = gsub('(?<=.)>$','"readLines(,1)"',
                 arg2,perl=T)                     # replace > with readLines(,1)
    arg2 = gsub('^.','',arg2)                     # remove the first character
    B = eval(parse(t=arg2))                       # evaluate the string : this will be our 
                                                  # second argument B
    A = substr(k,1,1)                             # take the first character : 
                                                  # i.e. the main command (+,-,! etc)
    x = switch(A,                                 # switch on the main command, execute the 
            '+'=paste0(x,B),                      # corresponding expression and 
            '!'=intToUtf8(rev(utf8ToInt(x))),     # store the result into x
            '*'=strrep(x,B),                      # Note: in the actual code we switch on
            '-'=B['',x,f=T],                      # the utf8 value MOD 13-2 of the command
            '$'=intToUtf8(sample(utf8ToInt(x))),
            '<'=print(x)
        )
    }
    x                                             # return x (and print it implicitly)
}
digEmAll
fonte
3

Python 2 , 215 219 209 208 bytes

from random import*
I=raw_input;o=''
for t in I().split('|'):p=t[1:]=='>'and I()or t[2:];exec"o=o[::-1] o*=int(p) 0 print(o) o=''.join(sample(o,len(o))) o=o.replace(p,'') o+=p".split()[ord(t[0])*5%11]
print o

Experimente online!

-4 porque raw_inputé necessário.

9 bytes graças à incorporação da ignorância ; 1 byte apenas do Ascii .

Chas Brown
fonte
A entrada diferente do programa deve ser de stdin, conforme especificado na pergunta.
Artemis ainda não confia em SE
Eu uso o Python 3, mas até onde eu sabia, esse uso de entrada requer raw_input. Corrija-me se eu estiver errado ..
Artemis ainda não confia SE
De acordo com os documentos do Py 2.7: input([prompt])Equivalente a eval (raw_input (prompt)). Esta função não captura erros do usuário. Se a entrada não for sintaticamente válida, um SyntaxError será gerado.
Artemis ainda não confia no SE
Portanto, o problema que você está levantando é algo como aqui , onde as seqüências de entrada precisariam ser citadas - em vez de não citadas como em uma situação stdin 'verdadeira'. Novamente, geralmente as regras de E / S são um pouco relaxadas; mas eu vou modificar.
Chas Brown
Obrigado por mudar. Você pode salvar alguns bytes mudando para Python 3 e usando seu código antigo + 3 bytes para colchetes, mas ... +1 de qualquer maneira
Artemis ainda não confia em SE
2

C # (compilador interativo do Visual C #) , 305 bytes

a=>{string s="",d,g;foreach(var c in a.Split('|')){g=$"{c,2}";d=g[1]==62?ReadLine():g.Substring(2);var z=c[0]%14;s=z<1?string.Concat(Enumerable.Repeat(s,int.Parse(d))):z<2?s+d:z<4?s.Replace(d,""):z<5?s:z<6?string.Concat(s.Reverse()):string.Concat(s.OrderBy(_=>Guid.NewGuid()));Write(z==4?s:"");}return s;}

Experimente online!

Modalidade de ignorância
fonte
1

Perl 5 -MList::Util=shuffle -pF/\|/ , 220 217 210 183 bytes

map{$,=s/..//r;$\=reverse$\if/^!/;$,ne""||chomp($,=<>),$\=~s/\Q$,//g if/^-/;say$\if/^</;$\=join"",shuffle$\=~/./g if/^\$/;$\.=$,eq""?<>=~s/\n//r:$,if/^\+/;$\x=$,eq""?<>:$,if/^\*/}@F}{

Experimente online!

Xcali
fonte
1

Javascript, 292 267 bytes

f=(p)=>{c='';p.split`|`.map(l=>{v=l.substr(2);v=l[1]=='#'?parseInt(v):l[1]=='>'?prompt():v;c={'+':_=>c+v,'-':_=>c.split(v).join``,'*':_=>c.repeat(v),'$':_=>[...c].sort(_=>.5-Math.random()).join``,'!':_=>[...c].reverse().join``,'<':_=>alert(c)||c}[l[0]]();});return c}

JSFiddle

Johan du Toit
fonte
O caso de teste 6 não funciona direito ...
Artemis ainda não confia em SE
1
@ArtemisFowl, Obrigado, o regex não estava funcionando corretamente e a mudança para split..join salvou alguns bytes.
Johan du Toit