Interprete parlante


10

"Talk" è un linguaggio basato sull'accumulatore barocco che viene creato in risposta alla citazione di Dennis su talk.tryitonline.net.

Waiting for someone to create an esolang called talk. 

. La lingua "Talk" ha 4 comandi:

  • 00 Se l'accumulatore è 0, impostare l'accumulatore su 0.
  • 01 Se l'accumulatore è 0, impostare l'accumulatore su 1.
  • 10 Se l'accumulatore è 1, impostare l'accumulatore su 0.
  • 11 Se l'accumulatore è 1, impostare l'accumulatore su 1.

Ingresso:

  • L'input può essere preso tramite qualsiasi metodo di input accettabile dalle nostre regole I / O standard.

  • Ci sono due ingressi, il valore iniziale dell'accumulatore e il programma. È possibile unire questi due input in un input o dividere l'input in comandi validi (ad es. Prenderli come elenco; ad es. [00, 01, 00]) Se lo si desidera.

Produzione:

  • Al termine dell'esecuzione di un comando, l'accumulatore viene emesso implicitamente.

Regole:

  • L'ingresso può essere una singola stringa o un elenco di caratteri.
  • Poiché si tratta di , la risposta più breve, in byte, vince.
  • Prendiamo cifre o stringhe / caratteri.

    Casi test:

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

Classifiche

Ecco uno snippet di stack per generare sia una classifica regolare che una panoramica dei vincitori per lingua.

Per assicurarti che la tua risposta venga visualizzata, ti preghiamo di iniziare la risposta con un titolo, usando il seguente modello Markdown:

# Language Name, N bytes

dov'è Nla dimensione del tuo invio. Se si migliora il punteggio, è possibile mantenere i vecchi punteggi nel titolo, colpendoli. Per esempio:

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

Se si desidera includere più numeri nell'intestazione (ad es. Perché il punteggio è la somma di due file o si desidera elencare separatamente le penalità del flag dell'interprete), assicurarsi che il punteggio effettivo sia l' ultimo numero nell'intestazione:

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

Puoi anche rendere il nome della lingua un collegamento che verrà quindi visualizzato nello snippet della classifica:

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


3
Quindi ci sono due ingressi, la sequenza di comandi e il valore iniziale dell'accumulatore?
xnor

4
Alcuni casi di test che non cambiano l'accumulatore, iniziano con 1 nell'accumulatore o non hanno istruzioni sarebbero buone
Jo King,

8
Talk può davvero essere considerato un linguaggio di programmazione ?
Luis Mendo,

8
@A_ Quel commento era probabilmente inteso come uno scherzo. In passato , una lingua chiamata Lang avrebbe un URL lang.tryitonline.net(ora lo è tio.run/#lang). Quindi un linguaggio chiamato Talk causerebbe confusione con l'URL per la chatroom creata di recente, che ètalk.tryitonline.net
Luis Mendo,

7
In futuro, si prega di astenersi dal modificare l'I / O dopo che sono state pubblicate diverse risposte. Sono tornato oggi e aver permesso di mappare gli input rende questa sfida completamente diversa da quella a cui ho risposto .
Funzione gamma

Risposte:


21

Gelatina , 3 byte

y@/

L'input è un unico elenco: l'accumulatore, seguito dalle coppie.

Provalo online!

Come funziona

L' yatomo esegue la traslitterazione; [a, b] yc sostituisce una con b , quindi restituisce b se a = c e c se a ≠ c .

y@/piega / riduce l'input ycon argomenti scambiati, eseguendo una traslitterazione per coppia.


14
Questa è l'unica risposta di Jelly che ho visto finora che utilizza solo caratteri ASCII.

2
Ce n'erano alcuni. Guarda, no Unicode!
Dennis,

21

Python 3 , 43 byte

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

Provalo online!

La funzione accetta una singola stringa come input, in cui il primo carattere è lo stato iniziale e il resto della stringa rappresenta i comandi. Questa soluzione può essere facilmente trasferita in altre lingue che supportano meglio le espressioni regolari.

La parte difficile è dimostrare che la soluzione produce il risultato corretto. Per vedere questo, abbiamo bisogno di un'analisi approfondita dei comandi. Innanzitutto, possiamo vedere che i comandi hanno le seguenti proprietà:

  • Proprietà (1) : comanda 00e 11mantiene lo stato dell'accumulatore.
  • Proprietà (2) : comanda 01e 10rende lo stato dell'accumulatore uguale al secondo bit indipendentemente dal suo stato originale.

Pertanto, lo stato dell'accumulatore finale è:

  • Caso 1 : se non esiste alcun comando 01o 10, lo stato finale è lo stesso dello stato iniziale.
  • Caso 2 : Altrimenti, l'ultimo bit dell'ultimo 10o del 01comando.

Successivamente mostreremo che la soluzione produce il risultato corretto in entrambi i casi. Dimostreremo l'affermazione per lo stato finale 0e lo stato finale di 1può essere dimostrato in modo analogo. Se lo stato finale è 0l'input è in una delle seguenti forme:

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

    Per il caso 1 , la stringa di input sdeve iniziare con 2k+10s, seguita da 11e 00comandi. L'eliminazione di 00s e 11s produce un singolo 0, che è lo stato finale.

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

    Per il caso 2 , la stringa di input termina con un 10comando, seguito da zero o più 00e 11s. Questo modello equivale a 1seguito da 2k+10s, quindi zero o più 11s e 00s. L'eliminazione di 00s e 11s lascia l'ultimo degli 2k+10 alla fine della stringa, che rappresenta lo stato finale.

Riferiscono tutto quanto sopra, dopo aver eliminato 00s e 11s contemporaneamente in un unico passaggio ( 01001è un contro-esempio se 00viene eliminato in un solo passaggio e poi 11in un altro passaggio) dall'ingresso s, l'ultimo carattere è lo stato finale. Quindi la correttezza della soluzione è dimostrata.


Benvenuti in PPCG! Ottima risposta e una bella prova formale da seguire!
Funzione gamma

3
Grazie. Sento che le persone potrebbero dubitare che una soluzione così semplice produca il risultato corretto a prima vista. Quindi è necessario fornire una prova per questo.
Gioele,

9

Perl 6 , 17 byte

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

Provalo online!

Approfitta di "Puoi unire questi due input in un input se vuoi" prendendo input come valore dell'accumulatore concatenato con i comandi, ad esempio 1,[00,11]è10011 . Se questo non va bene, allora è solo 5 byte extra per prenderlo come f(accumulator, commands). Restituisce un oggetto match che può essere forzato in una stringa.

Spiegazione:

{                }  # 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

Fondamentalmente funziona perché i comandi 00e 11non fanno letteralmente nulla, mentre i comandi 01e 10impostano semplicemente l'accumulatore sulla seconda cifra del comando. Se non ci sono comandi, prende invece il valore iniziale dell'accumulatore.


6

Zsh , 33 byte

L'elenco dei caratteri viene passato come argomenti, il valore iniziale dell'accumulatore viene passato come stdin.

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

Provalo online!


39 byte : se i comandi devono essere una singola stringa

L'input è accumulator commandscome argomento.

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

Provalo online!


Per divertimento, ecco un one-liner ( TIO ) ricorsivo da 50 byte :

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

6

Python 3 , 52 byte

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

Provalo online!

Risolto un tipo di ritorno incoerente grazie a Chas Brown

Accetta input come due stringhe; l'accumulatore e il codice.


Oh no, è stato veloce.
Altamente radioattivo il

1
Bello ma ha questo potenziale problema - f(1,'11')==f(1,'01')è False; a volte restituisce un inte talvolta un str. Quindi forse specificare che accetta acc input come stringa?
Chas Brown,

@ChasBrown Buona chiamata, è molto più semplice di quello a cui stavo pensando.
negativo sette

Bene, ma poiché la tua funzione è ricorsiva, non può essere anonima. Dovrebbe essere 52 byte .
Jitse,

5

Brachylog , 11 9 byte

tġ₂≠ˢtt|h

Provalo online!

Dal momento che è stato abbastanza a lungo che sono stato in grado di dimenticare l'idea di stampare l'accumulatore dopo ogni comando , ho formulato una soluzione significativamente meno ingenua con qualche ispirazione dalla risposta Perl di 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.

Vecchia soluzione:

Brachylog , 18 16 byte

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

Provalo online!

-2 byte dalla modifica del formato di input.


5

JavaScript (ES6), 27 byte

Accetta input come (a)(code), dove code è un è un elenco di numeri interi a 2 bit.

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

Provalo online!


JavaScript (ES6),  47  40 byte

Accetta input come (a)(code), dove code è una stringa.

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

Provalo online!

Come?

(a=0,x=012)(a=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

4

sed-E , 26 19 byte

Funziona anche un enorme -7 byte da @Cowsquack realizzando la rimozione di tutte le coppie.

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

Accetta input concatenati insieme su stdin. Ispirato dalla risposta Perl di Jo King . Elimina le coppie finali Rimuovi tutte le coppie, quindi ottieni l'ultima cifra.

Provalo online! Provalo online!


1
L'ultima riga può essere semplice s/.*\B//, ma cambiando leggermente l'approccio si ottiene anche 19 byte ancora più brevi Provalo online!
user41805

1
Eh, non pensavo che s/(.)\1//gavrebbe funzionato, dal momento che poteva rimuovere la fine di una coppia e l'inizio della successiva, ma funziona ancora. Eccellente!
Funzione gamma

@GammaFunction s/(.)\1//gè equivalente a s/00|11//gquello mostrato nella mia soluzione.
Gioele,

4

Retina 0.8.2 , 18 11 byte

(.)\1

!`.$

Provalo online! Il link include casi di test. Accetta input concatenati. Hai salvato 6 byte grazie a @CowsQuack per aver sottolineato che rimuovere tutti i personaggi raddoppiati e quindi prendere l'ultimo personaggio rimanente funziona, anche se in effetti il ​​porto della risposta originale di @ JoKing avrebbe potuto essere golfato di 3 byte anche senza quel trucco.



@Cowsquack D'oh, una volta che pensi di separare gli stage, è già un risparmio di 2 byte, quindi un altro byte salvato perché puoi usarlo !`.$e quindi altri 4 byte perché non devi limitarti alle coppie finali ...
Neil,

4

Python 3 , 38 byte

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

Provalo online!

Basato su soluzione di Joel . Accetta l'input come un elenco del valore iniziale dell'accumulatore (lunghezza-una stringa) seguito dai comandi (lunghezza-due stringhe). Trova l'ultimo comando con due valori diversi e genera il suo secondo carattere.

Per far sì che questo cada al valore dell'accumulatore iniziale quando non ci sono tali comandi, lo facciamo in modo che la stringa del valore iniziale a carattere singolo passi il test. Lo facciamo controllando se un elenco singleton con l'ultimo carattere non è uguale a un elenco di tutti i caratteri precedenti, che viene passato da qualsiasi lunghezza-una stringa o lunghezza-due stringa con due caratteri diversi.


3

Perl 5 -p , 37 33 byte

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

Provalo online!

L'input è di due righe: la prima riga è la sequenza di comando, la seconda è l'accumulatore.



3

Gelatina , 8 6 byte

EÐḟṪṪo

Provalo online!

-2 byte grazie a Nick Kennedy che mi informa di un cambio di regole. (La sua proposta di golf,EÐḟFȯṪ sembra un po 'più intelligente ma ha la stessa lunghezza della mia soluzione precedente meno s2.) Il formato di input ora prende i comandi come un elenco di stringhe di due caratteri, ma il piè di pagina del test si traduce dal vecchio formato per comodità.

Tradotto dalla mia nuova soluzione Brachylog.

Vecchia versione:

Gelatina , 13 byte

ḢẎ⁼⁹a⁸o
s2ç@ƒ

Provalo online!

Non sono sicuro al 100% che questo sia corretto, ma ha successo su tutti e tre i casi di test. Prende i comandi come argomento sinistro e l'accumulatore iniziale come argomento destro.


1
È possibile dividere EÐḟFȯṪl'input in un elenco, quindi si potrebbe avere con l'input come ad es [[0,0],[0,1],[1,1],[1,1],[0,1]].
Nick Kennedy,

Wow, le modifiche alle specifiche erano davvero piuttosto grandi ...
Unrelated String

3

Haskell , 29 byte

Definisce una funzione senza nome sulla prima riga con type (Foldable t, Eq b) => b -> t [b] -> b. Ai fini di questo codice golf, possiamo creare un'istanza come Char -> [String] -> Chardove il primo argomento è l'accumulatore e il secondo è un elenco di stringhe in cui ogni stringa è un singolo comando.

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

Provalo online!


1
Stesso conto se lo definisci usando la notazione con prefisso . Non riesco a credere di aver scritto quasi la stessa identica risposta allo stesso tempo, anche includendo la spiegazione della firma del tipo ...
Cole

2

Python, 111 byte

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 Qualcuno mi ha battuto!


2

Haskell , 36 byte

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

Provalo online!

Prende l'input come f(string)(char)dove il carattere è l'accumulatore e la stringa è l'elenco di comandi.




2

Barilotto , -ir, 16 byte

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

Provalo online!

Ha spiegato:

  1. Prende l'input implicito e sposta a destra il valore degli accumulatori verso il basso

  2. Ripeti le seguenti (lunghezza dello stack - 1 diviso per 2) volte

2.1. Riporta l'accumulatore verso l'alto

2.2. Confronta per l'uguaglianza con la prima parte del comando

2.2.1. Se vero, sostituire l'accumulatore, altrimenti far apparire la sostituzione

L'input viene preso come valore iniziale acc concatenato con la sorgente. Per esempio

010011000
  • Il primo carattere è il valore acc
  • Il resto è programma

1

Bash , 58 40 byte

Aggiungi un byte per un programma completo: cambia fin $0.

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

58 byte Provalo online!

Il ternario tornerà falso quando $1è impostato su 0, ma ,1alla fine assicura che tutto ((expression))ritorni vero, tranne un errore di sintassi.

Quando tutti gli argomenti vengono consumati, si verifica un errore di sintassi e la ricorsione termina.



1

Carbone , 16 byte

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

Provalo online! Il collegamento è alla versione dettagliata del codice. Accetta argomenti separati. Spiegazione:

F⪪η²

Dividi le istruzioni in coppie di cifre e passaci sopra.

F⁼θ§ι⁰

Se l'accumulatore è uguale alla prima cifra ...

≔§ι¹θ

... quindi assegnare ad essa la seconda cifra.

θ

Stampa l'accumulatore alla fine del ciclo.



1

Gelatina , 7 byte

fؽḂ⁹;Ṫ

Un collegamento diadico che accetta il programma come un elenco di numeri interi a sinistra e l'accumulatore iniziale a destra che produce un numero intero.

Provalo online! O vedi una suite di test


Sto rimuovendo l'input-mapping perché @GammaFunction mi ha consigliato di farlo.

@A_ ah OK non posso cancellare sul cellulare quindi dovrò risolverlo in seguito
Jonathan Allan

@A_ risolto per funzionare con 0,1,2,3 la versione non mappata delle istruzioni come cifre va bene?
Jonathan Allan,

1
Sì, va bene.


1

Incantesimi runici , 28 byte

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

Provalo online!

Accetta input come una serie di byte separati da spazi (Runic non comprende gli elenchi). Il primo byte è lo stato iniziale e ogni altro byte è il programma. Non viene eseguita alcuna convalida (ovvero presuppone che vengano immessi solo programmi validi come input e non importa quale valore viene utilizzato per rappresentare 0e 1).


1

x86 Assembly, 33 byte

Accetta lo stato dell'accumulatore iniziale in CL(intero 0o 1) e l'indirizzo dei comandi come stringa ASCII con terminazione zero ESI. Lascia lo stato dell'accumulatore finale inCL .

Puntare l'istruzione di chiamata sull'offset 0x1B(etichetta interpretnella Spiegazione).

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

Spiegazione (utilizzando la sintassi 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



0

Cristallo , 46 byte

Con i comandi in un Array(Tuple(Int32,Int32)), come ad esempio [{0,0}, {0,1}, {0,0}].

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

Provalo online!

È abbastanza semplice da capire in una forma più leggibile:

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

La funzione scorre attraverso ogni comando, scompattando automaticamente i valori di tupla in ce v. Quindi imposta il statedalla formula

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

a cui sono arrivato principalmente per tentativi ed errori. Una volta elaborati tutti i comandi, restituisce il valore dello stato.


0

C (clang) , 68 62 byte

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

Provalo online!

Porta un puntatore all'inizio della stringa di origine, un puntatore alla fine della stringa di origine (start + strlen (start)) e il valore iniziale dell'accumulatore.

Vecchia versione (stampa ASCII 48/49 per 0/1):

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

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.