Simula un sistema di tag ciclico


14

Un sistema di tag ciclico è un piccolo modello computazionale completo di Turing costituito da un alfabeto a due simboli (userò {0,1}), un elenco ciclico finito e non vuoto di produzioni che consistono di quei due simboli e una parola illimitata che comprende anche quei due simboli.

Ad ogni passo:

  • il primo elemento nella parola viene rimosso
  • se fosse 0la produzione corrente viene saltata
  • se fosse 1la produzione attuale viene aggiunta alla fine della parola .
  • la produzione successiva diventa attiva. Se questa è stata l'ultima produzione, torna alla prima.

Il sistema si arresta quando la parola diventa vuota.

Un esempio (da Wikipedia):

Productions: (010, 000, 1111)
Initial word: 11001

Generation  Production   Word (before)            Word (after)
   0           010           11001             →     1001010       
   1           000            1001010          →      001010000
   2           1111            001010000       →       01010000
   3           010              01010000       →        1010000
   4           000               1010000       →         010000000
   5           1111               010000000    →          10000000
   6           010                 10000000    →           0000000010
   7           000                  0000000010 →            000000010
   8           1111                  000000010 →             00000010
   9           010                    00000010 →              0000010

Il tuo compito, se scegli di accettarlo, è scrivere un programma o una funzione che accetta:

  • un elenco di produzioni,
  • la parola iniziale e
  • una generazione,

e stampa o restituisce la parola a quella generazione.

Per esempio,

cyclic_tag(
      prod=[[0,1,0],[0,0,0],[1,1,1,1]], 
      word=[1,1,0,0,1], 
      gen=4) => [1,0,1,0,0,0,0]

Dettagli di implementazione:

  • L'alfabeto non ha importanza. Puoi usare 0e 1, Truee False, Te NIL, Ae B, o anche 1e 0, o qualsiasi altra cosa tu possa inventare, purché tu sia coerente. Tutti gli input e output devono usare lo stesso alfabeto e devi indicare per cosa stai usando 0e per cosa 1.

  • La lunghezza della parola deve essere teoricamente illimitata. In altre parole, potresti non codificare una lunghezza massima di parola. Se eseguo il tuo programma su un computer ideale con una quantità infinita di memoria, il tuo programma deve teoricamente essere in grado di utilizzarlo. (Puoi ignorare i limiti del tuo interprete / compilatore.)

  • Se il sistema specificato si arresta prima che venga raggiunta la generazione specificata, è necessario restituire o stampare la parola vuota.

  • La produzione vuota esiste e devi essere in grado di gestirla. Se si scrive un programma completo, anche l'I / O deve essere in grado di gestirlo.

Modifica : inizialmente avevo pensato che la generazione 0fosse la parola di input stessa e che la generazione 1fosse il risultato del primo passo. Cioè, avevo previsto che tu restituissi la colonna precedente . Tuttavia , poiché non sono stato abbastanza chiaro nel dichiararlo, accetterò entrambe le opzioni ; per ogni generazione è possibile restituire il valore in entrambi colonna prima o dopo . Devi dichiarare che stai seguendo la colonna after , se lo stai facendo. Devi anche essere coerente in quale colonna scegli.

Assegnerò il codice più piccolo tra una settimana (27/10/2014).


Uhm, sei sicuro che il tuo risultato nell'esempio sia corretto? Sulla base dell'altro esempio che hai dato, penso che sia gen 5 ...
FryAmTheEggman

Possiamo prendere l'input in un ordine diverso?
Martin Ender,

1
@FryAmTheEggman: è corretto, intendevo la colonna "prima". Se più persone hanno commesso questo errore, cambierò la mia domanda per accettarla. Ammetto di non essere stato molto chiaro.
marinus,

@ MartinBüttner: fintanto che specifichi l'ordine, non importa.
marinus,

Risposte:


4

GolfScript (da 17 a 19 byte in base al formato di input e al formato di output accettato)

18 byte:

~.@*<{\1,or(@*+}/`

Accetta input nel modulo [1 1 0 0 1] [[0 1 0] [0 0 0] [1 1 1 1]] 4e fornisce output nel modulo [1 0 1 0 0 0 0]. (Potrebbero essere 17 byte senza l'ultimo` se l'output 1010000è accettabile).

Demo online

19 byte:

~.@*<{\0`or(1&@*+}/

Accetta input nel modulo "11001" ["010" "000" "1111"] 4 .

Demo online

Dissezione

~        # Evaluate input: stack: word productions gen
.@*<     # Produce a list of the right number of productions with suitable repetition
{        # For each of those productions:
  \      #   Bring the word to the top
  0`or   #   Ensure that we don't get an error if the word is empty
  (1&    #   Pop the first char from the word and evaluate it
  @*     #   Repeat the production that many times
  +      #   Concatenate 0 or 1 copies of the production to the rest of the word
}/       # Endforeach

Si ringrazia Martin Büttner 's soluzione CJam per l'idea di generare l'elenco delle produzioni di ripetizione e troncamento.


Sei legato alla soluzione CJam che citi, quindi ho scelto quella risposta. Se ti tagli un altro byte riconsidererò :)
Marin

@marinus, accetti la versione a 17 byte a cui mi riferisco nel testo della mia risposta?
Peter Taylor,

Non l'avevo visto, ma sembra valido. Forse dovresti contrassegnarlo un po 'più chiaramente.
Marin

5

Haskell, 55 53 51

(t:w)%p|t=w++p|0<1=w
x%_=x
e w=(!!).scanl(%)w.cycle

questo usa Truecome 1e Falsecome 0. esempio di esecuzione:

*Main> let t=True ; f=False
*Main> e [t,f,t] [[f,f,f],[t,t,t]] 4
[False,False,False,False,False]

3

CJam, 31 30 28 27 24 18 byte

{_@*<{\_0a?(@*+}/}

Questo definisce un blocco (la cosa più vicina a una funzione), che si aspetta che l'input risieda nello stack in questo modo

[1 1 0 0 1] [[0 1 0] [0 0 0] [1 1 1 1]] 9

Allo stesso modo lascerà una serie di se 0e1 s in pila.

Provalo qui. Incollare l'ingresso uno sulla prima riga, il codice sulla terza riga e aggiungere a ~per valutare effettivamente il blocco. Per esempio

[1 1 0 0 1] [[0 1 0] [0 0 0] [1 1 1 1]] 9
{_@*<{\_0a?(@*+}/}~

Se l'output non deve avere la stessa forma dell'input

Spiegazione:

_@*<{\_0a?(@*+}/
_@               "Duplicate the generation and pull the productions to the top.";
  *<             "Repeat the productions N times and take the first N elements.";
    {         }/ "For each element in that list, run this block.";
     \           "Swap production and current word W.";
      _0a?       "W = (W != []) ? W : [0]. This is to ensure we can unshift an element.";
          (      "Unshift the first 0 or 1 from the word.";
           @     "Rotate the stack, pulling the production to the top.";
            *    "Repeat it 0 or 1 times.";
             +   "Append to the word.";

Lo stato finale della parola viene lasciato in pila.

Grazie a Peter Taylor per avermi fatto rivisitare questo.


1
l~{_,g{('1=@(:Pa+@@P*+}*}*\;28 e ancora possibilità di miglioramento (in particolare la (:Pparte), ma tempo per il pranzo
Ottimizzatore

@Optimizer Ah, buona idea. Grazie. E sì, :Pmi infastidisce anche: D
Martin Ender,

l~{_,g{(si@(:Pa+@@P*+}*}*\;: 27 e dopo averlo esaminato, :Pè effettivamente efficiente: P
Ottimizzatore

_,gpuò anche essere sostituito con _!!ma stessi byte.
Ottimizzatore

@Optimizer che potrei anche usare _{...}{}?allora.
Martin Ender,

2

Mathematica, 84 80 77 caratteri

f[_,w_,_]=w;f[p_,{x_,y___},n_/;n>0]:=f[RotateLeft@p,Flatten@{y,p~Take~x},n-1]

Esempio:

f[{{0, 1, 0}, {0, 0, 0}, {1, 1, 1, 1}}, {1, 1, 0, 0, 1}, 4]

{1, 0, 1, 0, 0, 0, 0}


2

Pyth 22

Richiede tutti e 3 gli argomenti come input separati.

#Vvw=z+tz*@Q%NlQshz)zq

Accetta argomenti come:

11001
["010","000","1111"]
4

Spiegazione:

                        : Implicit: z = input(); Q=eval(input())
#                       : Loop until an exception is thrown
 Vvw               )    : for N in range(eval(input()))
    =z                  : assign to z
      +tz               : the sum of the tail of z and
         *@Q%NlQ        : Q[N%len(Q)] times
                shz     : the numeric value of the first character in z
                    zq  : print z then throw exception

Python 2-61 67 91 105 124

c=lambda p,w,g:g*w and c(p[1:]+p[:1],w[1:]+w[0]*p[0],g-1)or w

Bella risposta Joe-Basic. Suppone che la produzione vuota sia [[]].

Grazie a @xnor, per aver sottolineato che giocare a golf alle 2 del mattino è una decisione sbagliata.

Un ringraziamento in più a @xnor, a cui mi sembra dovuto il 50% del mio punteggio.

Campione:

>>> c([[0,1,0],[0,0,0],[1,1,1,1]],[1,1,0,0,1],4)
[1, 0, 1, 0, 0, 0, 0]

1
Sicuramente è più breve usare una lambda e scrivere g and wper x? Inoltre, penso che g*wdovrebbe funzionare per dare un valore veritiero quando entrambi gsono diversi da zero e wnon vuoti.
xnor

Inoltre, non capisco l'interno if x else w. Non sarà xsempre vero perché questo codice viene eseguito solo if xo mi manca qualcosa?
xnor

@xnor Sicuramente, hai perfettamente ragione :)
FryAmTheEggman,

1
Ancora un po 'di golf con and/ ortrick e ruotando pinvece di incrementare n:c=lambda p,w,g:g*w and c(p[1:]+p[:1],w[1:]+w[0]*p[0],g-1)or w
xnor

@xnor Grazie :) Inoltre, ora che l'hai resa una funzione di 3 variabili, penso di tradurla in Pyth ...
FryAmTheEggman

1

Javascript ES6 - 88 byte

f=(p,w,g,n)=>g?w.replace(/(.)(.*)/,(_,a,b)=>f(p,a*1?b+p[(n=n||0)%p.length]:b,g-1,n+1)):w

Sembra stranamente simile alla risposta di Fry che è appena apparsa nel mio browser. (Nessuna copia, lo giuro solennemente.)

Sembrerebbe che abbia seguito la route array mentre io ho seguito la route string / regex.

Allargato:

f = (p,w,g,n) =>
    g ?
        w.replace( /(.)(.*)/, (_,a,b) =>
            f( p, a*1 ? b + p[(n=n||0)%p.length] : b, g-1, n+1 )
        )
    :
        w

Uscita campione

f(['010','000','1111'],'11001',4)
"1010000"

Ora guarda le lingue del golf entrare e massacrare entrambi. : D


In realtà ho cancellato il mio post perché stavo ottenendo risposte diverse per i due esempi. Hai provato l'esempio in cui va di generazione in generazione? Sembra essere fuori da uno rispetto all'esempio di chiamata completo che ha dato ...
FryAmTheEggman

E non preoccuparti, credo che tu non mi abbia copiato: P
FryAmTheEggman,

@FryAmTheEggman: Mine genera costantemente la colonna "before" per la generazione numerata. Ciò è coerente con l'esempio nell'OP e sembra logico che "generazione 0" restituisca semplicemente l'input senza elaborarlo, il che è coerente con questa interpretazione. Per inciso, ho aggiunto la dichiarazione di non responsabilità "copia" perché le soluzioni erano sorprendentemente simili per alcuni aspetti. Abbiamo usato gli stessi nomi degli argomenti, la stessa struttura ricorsiva di base, e abbiamo anche aggiunto lo stesso fantasma quarto argomento, n. Grandi menti, eh? : D
COTO

Ok, immagino che se uno di noi ha torto, entrambi abbiamo torto! Uniti stiamo in piedi.
FryAmTheEggman,

@FryAmTheEggman: non avevi torto sul signor Peppe. ;)
COTO
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.