Intérprete de conversação

10

"Talk" é uma linguagem baseada em acumulador baroquificada criada em resposta à citação de Dennis no talk.tryitonline.net.

Waiting for someone to create an esolang called talk. 

. O idioma "Talk" possui 4 comandos:

  • 00 Se o acumulador for 0, defina o acumulador como 0.
  • 01 Se o acumulador for 0, defina o acumulador como 1.
  • 10 Se o acumulador for 1, defina o acumulador como 0.
  • 11 Se o acumulador for 1, defina o acumulador como 1.

Entrada:

  • A entrada pode ser obtida por qualquer método de entrada aceitável, de acordo com nossas regras de E / S padrão.

  • Existem duas entradas, o valor inicial do acumulador e o programa. Você pode mesclar essas duas entradas em uma entrada ou dividir sua entrada em comandos válidos (por exemplo, tomando-os como uma lista; por exemplo [00, 01, 00]), se desejar.

Resultado:

  • No final de uma execução de comando, o acumulador é gerado implicitamente.

Regras:

  • A entrada pode ser uma única cadeia ou lista de caracteres.
  • Como esse é o , a resposta mais curta, em bytes, vence.
  • Tomamos dígitos ou strings / caracteres.

    Casos de teste:

0 0001111101 -> 1
0 000100 -> 1
0 11001000 -> 0

Classificação

Aqui está um snippet de pilha para gerar uma classificação regular e uma visão geral dos vencedores por idioma.

Para garantir que sua resposta seja exibida, inicie-a com um título, usando o seguinte modelo de remarcação:

# Language Name, N bytes

onde Nestá o tamanho do seu envio. Se você melhorar sua pontuação, poderá manter as pontuações antigas no título, identificando-as. Por exemplo:

# Ruby, <s>104</s> <s>101</s> 96 bytes

Se você quiser incluir vários números no cabeçalho (por exemplo, porque sua pontuação é a soma de dois arquivos ou você deseja listar as penalidades do sinalizador de intérpretes separadamente), verifique se a pontuação real é o último número no cabeçalho:

# Perl, 43 + 2 (-p flag) = 45 bytes

Você também pode transformar o nome do idioma em um link que será exibido no snippet do placar de líderes:

# [><>](http://esolangs.org/wiki/Fish), 121 bytes


fonte
3
Então existem duas entradas, a sequência de comandos e o valor inicial do acumulador?
Xnor
4
Alguns casos de teste que não alteram o acumulador, começam com 1 no acumulador ou não têm instruções seria bom
Jo rei
8
O Talk pode realmente ser considerado uma linguagem de programação ?
Luis Mendo
8
@A_ Esse comentário provavelmente foi feito como uma piada. No passado , um idioma chamado Lang teria um URL lang.tryitonline.net(agora é tio.run/#lang). Portanto, um idioma chamado Talk causaria confusão com o URL da sala de bate-papo criada recentemente, que étalk.tryitonline.net
Luis Mendo
7
No futuro, evite alterar a E / S depois que várias respostas forem publicadas. Voltei hoje e ter mapeado as entradas permitidas faz deste um desafio totalmente diferente do que respondi .
GammaFunction

Respostas:

21

Gelatina , 3 bytes

y@/

A entrada é uma lista única: o acumulador, seguido pelos pares.

Experimente online!

Como funciona

O yátomo realiza transliteração; [a, b] yc substitui a por b , então retorna b se a = c e c se a ≠ c .

y@/dobra / reduz a entrada ycom argumentos trocados, executando uma transliteração por par.

Dennis
fonte
13
Esta é a única resposta Jelly que eu vi até agora que usa apenas caracteres ASCII.
2
Houve alguns. Olha ma, não Unicode!
Dennis
21

Python 3 , 43 bytes

lambda s:re.sub("00|11","",s)[-1]
import re

Experimente online!

A função usa uma única string como entrada, onde o primeiro caractere é o estado inicial e o restante da string representa os comandos. Essa solução pode ser facilmente transportada para outros idiomas que oferecem melhor suporte para expressões regulares.

A parte difícil é provar que a solução produz o resultado correto. Para ver isso, precisamos de uma análise profunda dos comandos. Primeiramente, podemos ver que os comandos têm as seguintes propriedades:

  • Propriedade (1) : comanda 00e 11mantém o estado do acumulador.
  • Propriedade (2) : comanda 01e 10torna o estado do acumulador igual ao segundo bit, independentemente do seu estado original.

Portanto, o estado final do acumulador é:

  • Caso 1 : Se nenhum comando 01ou 10existir, o estado final é o mesmo que o estado inicial.
  • Caso 2 : Caso contrário, o último bit do último 10ou 01comando.

A seguir, mostraremos que a solução produz o resultado correto nos dois casos. Provaremos a afirmação para o estado final 0e o estado final de 1pode ser provado analogamente. Se o estado final for 0a entrada, está em uma das seguintes formas:

  • ^0{2k+1}11(11|00)*

    Para o Caso 1 , a sequência de entrada sdeve começar com 2k+10s, seguida por 11e 00comandos. Eliminar 00s e 11s produz um único 0, que é o estado final.

  • .+10{2k+1}11(11|00)*

    Para Caso 2 , as extremidades de corda de entrada com um 10comando, seguido de zero ou mais 00e 11s. Esse padrão é equivalente a um 1seguido por 2k+10s e, em seguida, zero ou mais 11s e 00s. A eliminação de 00s e 11s deixa para trás o último dos 2k+10s no final da sequência, que representa o estado final.

Com base em tudo o que precede, após a eliminação 00s e 11s simultaneamente em uma única passagem ( 01001é um contra-exemplo se 00é eliminada em uma passagem e, em seguida, 11em uma outra passagem) a partir da entrada s, o último carácter é o estado final. Portanto, a correção da solução é comprovada.

Joel
fonte
Bem-vindo ao PPCG! Excelente resposta e uma boa prova formal para acompanhar!
GammaFunction 25/08/19
3
Obrigado. Sinto que as pessoas podem duvidar que uma solução tão simples produza o resultado correto à primeira vista. Portanto, é necessário fornecer uma prova disso.
Joel
9

Perl 6 , 17 bytes

{m/.)>[(.)$0]*$/}

Experimente online!

Aproveita "Você pode mesclar essas duas entradas em uma entrada, se quiser", recebendo a entrada como o valor do acumulador concatenado com os comandos, por exemplo, 1,[00,11]é 10011. Se isso não estiver correto, serão necessários apenas 5 bytes extras f(accumulator, commands). Retorna um objeto de correspondência que pode ser coagido a uma sequência.

Explicação:

{                }  # Anonymous code block
 m/             /   # Find the first match from the input
   .)>              # Capture a number
      [     ]*      # Followed by any number of
       (.)$0        # Pairs of identical characters
              $     # Ending the string

Basicamente, isso funciona porque os comandos 00e 11não fazem nada literalmente, enquanto os comandos 01e 10apenas definem o acumulador para o segundo dígito do comando. Se não houver comandos, será necessário o valor inicial do acumulador.

Brincadeira
fonte
6

Zsh , 33 bytes

A lista de caracteres é passada como argumentos, o valor inicial do acumulador é passado como stdin.

read a
for x y;a=$[x^a?a:y]
<<<$a

Experimente online!


39 bytes : se os comandos devem ser uma única sequência

A entrada é accumulator commandscomo argumentos.

for x y (${(s::)2})1=$[x^$1?$1:y]
<<<$1

Experimente online!


Por diversão, aqui está um TIO (one-liner recursivo) de 50 bytes :

<<<${${2+`f $[$1^${2[1]}?$1:${2[2]}] ${2:2}`}:-$1}
GammaFunction
fonte
6

Python 3 , 52 bytes

f=lambda a,s:s and f([s[1],a][s[0]==s[1]],s[2:])or a

Experimente online!

Tipo de retorno inconsistente fixo graças a Chas Brown

Recebe entrada como duas strings; o acumulador e o código.

sete negativos
fonte
Oh não, isso foi rápido.
HighlyRadioactive
11
Bom, mas tem esse problema em potencial - f(1,'11')==f(1,'01')é False; às vezes retorna um inte às vezes um str. Então, talvez especificar que leva entrada acc como uma string?
Chas Brown
@ChasBrown Boa ligação, isso é muito mais simples do que eu estava pensando.
negativo sete
Bom, mas como sua função é recursiva, não pode ser anônima. Deve ter 52 bytes .
Jitse 26/08/19
5

Braquilog , 11 9 bytes

tġ₂≠ˢtt|h

Experimente online!

Como já se passou o tempo suficiente para esquecer a noção de imprimir o acumulador após cada comando , formulei uma solução significativamente menos ingênua com alguma inspiração da resposta Perl de Jo King.

       |     The output is
     tt      the last element of the last element of
t            the last element of the input
 ġ₂          split into length-2 slices
   ≠ˢ        with equal pairs removed.
       |     If there is no such element, the input
        h    's first element is the output.

Solução antiga:

Braquilog , 18 16 bytes

ġ₂ᵗc{th~h?tt|h}ˡ

Experimente online!

-2 bytes para alterar o formato de entrada.

String não relacionada
fonte
5

JavaScript (ES6), 27 bytes

Aceita entrada como (a)(code), onde o código é uma lista de números inteiros de 2 bits.

a=>c=>c.map(x=>a^=x==a+1)|a

Experimente online!


JavaScript (ES6),  47  40 bytes

Aceita entrada como (a)(code), onde código é uma sequência.

a=>c=>c.replace(/../g,x=>a^=x%4==a+1)&&a

Experimente online!

Como?

(uma=0 0,x=012)(uma=1 1,x=102)

  a | x (bin) | int(x) % 4 | a + 1 | equal?
----+---------+------------+-------+--------
  0 |   "00"  |  0 % 4 = 0 |   1   |   N
  1 |   "00"  |  0 % 4 = 0 |   2   |   N
  0 |   "01"  |  1 % 4 = 1 |   1   |   Y
  1 |   "01"  |  1 % 4 = 1 |   2   |   N
  0 |   "10"  | 10 % 4 = 2 |   1   |   N
  1 |   "10"  | 10 % 4 = 2 |   2   |   Y
  0 |   "11"  | 11 % 4 = 3 |   1   |   N
  1 |   "11"  | 11 % 4 = 3 |   2   |   N
Arnauld
fonte
4

sed -E, 26 19 bytes

Um gritante -7 bytes do @Cowsquack ao perceber a remoção de todos os pares também funciona.

s/(.)\1//g
s/.*\B//

Aceita entrada concatenada em stdin. Inspirado pela resposta Perl de Jo King . Retirar pares finais Remova todos os pares e, em seguida, obtenha o último dígito.

Experimente online! Experimente online!

GammaFunction
fonte
11
A última linha pode ser simples s/.*\B//, mas de qualquer maneira, alterar a abordagem levemente gera 19 bytes ainda mais curtos. Experimente on-line!
user41805
11
Não achei que s/(.)\1//gfuncionaria, pois poderia remover o final de um par e o início do próximo, mas ainda funciona. Excelente!
GammaFunction
@GammaFunction s/(.)\1//gé equivalente ao s/00|11//gmostrado na minha solução.
Joel
4

Retina 0.8.2 , 18 11 bytes

(.)\1

!`.$

Experimente online! O link inclui casos de teste. Aceita entrada concatenada. Economizou 6 bytes graças ao @CowsQuack por apontar que remover todos os caracteres duplicados e depois pegar o último caractere restante funciona, embora na verdade a porta da resposta original do @ JoKing pudesse ter sido alterada em 3 bytes, mesmo sem esse truque.

Neil
fonte
12 bytes Experimente online!
user41805
@ Cowsquack D'oh, depois de pensar em separar os estágios, já é uma economia de 2 bytes, depois outro byte salvo porque você pode usar !`.$e depois outros 4 bytes porque você não precisa limitar os pares à direita ...
Neil
4

Python 3 , 38 bytes

lambda l:[y for*x,y in l if[y]!=x][-1]

Experimente online!

Baseado na solução de Joel . Recebe a entrada como uma lista do valor inicial do acumulador (comprimento-uma cadeia) seguido pelos comandos (comprimento-duas cadeias). Localiza o último comando com dois valores desiguais e gera seu segundo caractere.

Para fazer com que isso caia no valor inicial do acumulador quando não houver tais comandos, fazemos com que a cadeia de valor inicial de caractere único passe no teste. Fazemos isso verificando se uma lista de singleton com o último caractere é desigual para uma lista de todos os caracteres anteriores, que é passada por qualquer comprimento - uma string ou comprimento - two string com dois caracteres diferentes.

xnor
fonte
3

Perl 5 -p , 37 33 bytes

$\=<>;s/(.)(.)/$\=$2if$\==$1/ge}{

Experimente online!

A entrada tem duas linhas: a primeira linha é a sequência de comandos, a segunda é o acumulador.

Xcali
fonte
3

Python 2 , 56 bytes

f=lambda a,c:f([a,1,0,a][int(c[:2],2)],c[2:])if c else a

Experimente online!

Chas Brown
fonte
3

Geléia , 8 6 bytes

EÐḟṪṪo

Experimente online!

-2 bytes graças a Nick Kennedy, informando-me sobre uma alteração nas regras. (Seu golfe proposto EÐḟFȯṪ, parece um pouco mais inteligente, mas tem o mesmo tamanho que minha solução anterior menos s2.) O formato de entrada agora assume os comandos como uma lista de cadeias de caracteres de dois caracteres, mas o rodapé do teste se traduz no formato antigo por conveniência.

Traduzido da minha solução Brachylog mais recente.

Versão antiga:

Gelatina , 13 bytes

ḢẎ⁼⁹a⁸o
s2ç@ƒ

Experimente online!

Não tenho 100% de certeza de que isso esteja correto, mas é bem-sucedido nos três casos de teste. Toma os comandos como argumento esquerdo e o acumulador inicial como argumento correto.

String não relacionada
fonte
11
A entrada pode ser dividida em uma lista, para que você possa ter EÐḟFȯṪa entrada como por exemplo [[0,0],[0,1],[1,1],[1,1],[0,1]].
Nick Kennedy
Uau, as alterações nas especificações foram realmente muito grandes ...
String não relacionada
3

Haskell , 29 bytes

Define uma função sem nome na primeira linha com o tipo (Foldable t, Eq b) => b -> t [b] -> b. Para os propósitos deste código golf, podemos instancia-lo como Char -> [String] -> Charonde o primeiro argumento é o acumulador e o segundo é uma lista de cadeias de caracteres com cada cadeia sendo um único comando.

foldl(#)
a#[x,y]|a==x=y|1>0=a

Experimente online!

ankh-morpork
fonte
11
O mesmo número de bytes, se você o definir usando a notação de prefixo . Eu não posso acreditar que eu escrevi quase a mesma resposta exata, ao mesmo tempo, mesmo incluindo a explicação tipo de assinatura ...
cole
2

Python, 111 bytes

def f(a,b):
    c=a
    for i in range(0,len(b)-1,2):
        c=(not b[i])*(c or b[i] or b[i+1]) or c*b[i]*b[i+1]
    return c

Ungolfed. EDIT: AHHH Alguém me venceu!

Altamente radioativo
fonte
2

Haskell , 36 bytes

f(x:y:s)=f s.last.(:[y|x/=y])
f _=id

Experimente online!

Toma como local f(string)(char)onde o caractere é o acumulador e a string é a lista de comandos.

Brincadeira
fonte
2

Stax , 3 bytes

F|t

Execute e depure

Para cada instrução, execute a tradução de caracteres.

recursivo
fonte
1

Bash , 58 40 bytes

Adicione um byte para um programa completo: altere fpara $0.

(($1=$2-a?a:$3,1))&&f $1 ${@:4}||echo $1

58 bytes Experimente online!

O ternário retornará falso quando $1definido como 0, mas ,1no final garante que o todo ((expression))retorne verdadeiro, exceto um erro de sintaxe.

Quando todos os argumentos são consumidos, ocorre um erro de sintaxe e a recursão termina.


GammaFunction
fonte
1

Carvão , 16 bytes

F⪪η²F⁼θ§ι⁰≔§ι¹θθ

Experimente online! Link é a versão detalhada do código. Leva argumentos separados. Explicação:

F⪪η²

Divida as instruções em pares de dígitos e faça um loop sobre eles.

F⁼θ§ι⁰

Se o acumulador for igual ao primeiro dígito ...

≔§ι¹θ

... depois atribua o segundo dígito a ele.

θ

Imprima o acumulador no final do loop.

Neil
fonte
1

Geléia , 7 bytes

fؽḂ⁹;Ṫ

Um link diádico que aceita o programa como uma lista de números inteiros à esquerda e o acumulador inicial à direita que produz um número inteiro.

Experimente online! Ou veja uma suíte de testes

Jonathan Allan
fonte
Estou removendo o mapeamento de entrada porque @GammaFunction me recomendou fazer isso.
@A_ ah OK não pode excluir no celular assim que terá de resolver isso mais tarde
Jonathan Allan
@A_ corrigiu para trabalhar com 0,1,2,3 a versão não mapeada das instruções como dígitos, tudo bem?
Jonathan Allan
11
Sim, está bem.
1

Encantos Rúnicos , 28 bytes

/~@/i~/i<
/=?/~iR:l}i{l1-=?!

Experimente online!

Recebe entrada como uma série de bytes separados por espaço (o Runic não entende listas). O primeiro byte é o estado inicial e todos os outros bytes são o programa. Nenhuma validação é executada (ou seja, assume que apenas programas válidos são dados como entrada e não se importa com o valor usado para representar 0e 1).

Draco18s não confia mais no SE
fonte
1

Montagem x86, 33 bytes

Coloca o estado inicial do acumulador em CL(inteiro 0ou 1) e o endereço dos comandos como uma String ASCII terminada em zero ESI. Deixa o estado final do acumulador emCL .

Aponte a instrução de chamada no deslocamento 0x1B(etiqueta interpretna Explicação).

3C 30 74 03 B0 01 C3 30 C0 C3 E8 F1 FF FF FF 38
C8 AC 75 07 E8 E7 FF FF FF 88 C1 AC 84 C0 75 EA
C3

Explicação (Usando a sintaxe da Intel):

; function to convert ASCII '1'/'0' into 0 or 1 int values (from AL to AL)
ctob:
        CMP AL, 0x30 ; '0'
        JE .zero
        MOV AL, 1
        RET
        .zero:
        XOR AL, AL
        RET

; interpreting function
        interp_lp:
                CALL ctob     ; convert to number
                CMP AL, CL    ; compare to current accumulator
                LODSB         ; read the next character of the string
                              ; this doesn't affect any flags and we need to do
                              ; it in both cases anyway
                JNE interpret ; if AL != CL (from above, not the new value of AL), skip forward
                CALL ctob     ; convert AL to number
                MOV CL, AL    ; store AL in CL
interpret:      LODSB         ; read the next character of the string
                TEST AL, AL   ; check if it is a zero byte
                JNZ interp_lp ; if not, jump back into the loop
        RET

Fayti1703
fonte
1

C (gcc) , 45 41 bytes

f(a,i)char*i;{a=*i?f(a^*i?a:i[1],i+2):a;}

Experimente online!

4 bytes eliminados graças a @ErikF!

G. Sliepen
fonte
11
Você pode salvar 4 bytes usando o truque usual de armazenar o valor de retorno no primeiro parâmetro: Experimente online!
ErikF 26/08/19
1

Barril , -ir, 16 bytes

"(!;½|':"=['_"|_

Experimente online!

Explicado:

  1. Pega a entrada implícita e muda o valor dos acumuladores para a direita

  2. Repita o seguinte (comprimento da pilha - 1 dividido por 2) vezes

2.1 Mude o acumulador de volta ao topo

2.2 Compare para igualdade com a primeira parte do comando

2.2.1 Se verdadeiro, substitua o acumulador, caso contrário, pop a substituição

A entrada é tomada como o valor acc inicial concatenado com a fonte. Por exemplo

010011000
  • O primeiro caractere é valor acc
  • O resto é programa
Lyxal
fonte
0

Cristal , 46 bytes

Com comandos em um Array(Tuple(Int32,Int32)), como [{0,0}, {0,1}, {0,0}].

def f(s,i);i.map{|c,v|s+=~(s^c)&(s^v)%2};s;end

Experimente online!

É muito simples de entender de uma forma mais legível:

def f(state, instructions)
  instructions.map do |check, value|
    state += ~(state ^ check) & (state ^ value) % 2
  end
  state
end

A função percorre cada comando, descompactando automaticamente os valores da tupla em ce v. Em seguida, define o statepela fórmula

state = state + NOT(state XOR check) AND (state XOR value) mod 2

a que cheguei principalmente por tentativa e erro. Depois que todos os comandos foram processados, ele retorna o valor do estado.

Kinxer
fonte
0

C (clang) , 68 62 bytes

t(s,e,a)char*s,*e;{for(;s<e;++s)a=*s++-48^a?a:*s-48;puts(&a);}

Experimente online!

Leva um ponteiro para o início da string de origem, um ponteiro para o final da string de origem (start + strlen (start)) e o valor inicial do acumulador.

Versão antiga (imprime ASCII 48/49 para 0/1):

t(s,e,a)char*s,*e;{for(;s<e;++s)a=*s++-48^a?a:*s-48;putchar(a+48);}
osuka_
fonte
0

Java (JDK) , 38 bytes

a->p->p.reduce(a,(s,c)->c<1|c>2?s:c%2)

Experimente online!

As entradas são uma inte uma IntStreamde 0, 1, 2ou 3, o que corresponde a 00, 01, 10, 11a partir de binário.

Olivier Grégoire
fonte