Compila registri (per sostituzione)


21

Il tuo compito è compilare regex ... specificando una sostituzione per ogni personaggio in una regex.

regex

Le regex supportano queste

REGEX       = (LITERAL REGEX / GROUP REGEX / STAR REGEX / ALTERNATIVE)
LITERAL     = 1 / 0
GROUP       = '(' REGEX ')'
STAR        = (LITERAL / GROUP) '*'
ALTERNATIVE = '('REGEX ('|' REGEX)*')'

Perché solo 1 o 0? È per semplificazione. Il regex ha quindi solo i seguenti caratteri:

*()|10

Viene interpretato come segue:

  1. * è la stella di Kleene (ripetere il gruppo a sinistra o letterale 0 o più volte).
  2. | è alternanza (corrisponde se la regex a sinistra o la regex a destra corrispondono).
  3. () sta raggruppando.
  4. 1 corrisponde al personaggio 1.
  5. 0 corrisponde al carattere 0.

Come compilare?

Devi specificare sei frammenti di codice: uno per sostituire ogni carattere regex. Ad esempio, se la tua risposta è:

*: FSAGFSDVADFS
|: GSDGSAG
(: GSDG
): GDSIH
1: RGIHAIGH
0:GIHEBN

Quindi sostituisci ogni regex con il rispettivo frammento di codice, quindi:

(0|11)*

si trasforma in:

GSDGGIHEBNGSDGSAGRGIHAIGHRGIHAIGHGDSIHFSAGFSDVADFS

Cosa dovrebbe fare il programma risultante?

Il tuo programma dovrà:

  1. Prendi l'input.
  2. Emette un valore veritiero se il regex corrisponde all'intero input.
  3. Altrimenti emette un valore falso.

L'input esterno 01è un comportamento indefinito. L'input può essere vuoto.

Regole aggiuntive

  1. Per un dato carattere regex, lo snippet risultante deve essere sempre lo stesso.
  2. Non è stato aggiunto alcun prefisso o suffisso in seguito.
  3. Il regex è garantito essere non vuoto.

punteggio

Lo snippet meno combinato è il vincitore. Quindi il punteggio per il caso esemplificativo sarebbe calcolato come segue:

FSAGFSDVADFS+ GSDGSAG+ GSDG+ GDSIH+ RGIHAIGH+GIHEBN

12 + 7 + 4 + 5 + 8 + 6 = 42


Ciascun frammento deve contenere almeno 1 carattere?
trichoplax,

Lo snippet può avere lunghezza zero. La modifica è OK.
Akangka,

La lingua RegEx è valida per questa sfida? : P
Loovjo,

Ritengo che RegEx abbia il build-in RegEx. Sono costretto a farlo. Voglio escludere Retina e regex, tuttavia, secondo Mego, non è permesso. Tuttavia, non so di lumache e amici.
Akangka,

@ChristianIrwan È interessante notare che non sono ancora sicuro che questo sia persino risolvibile in Retina e, anche se lo è, sarà tutt'altro che competitivo.
Martin Ender,

Risposte:


7

Lumache , 48 byte

0 -> )0(\0!(l.)(~

1 -> )0(\1!(l.)(~

( -> )0({{(

) -> )0}}(~

| -> )0}|{(

* -> )0),(~

Se dovessimo cercare corrispondenze parziali anziché corrispondere solo all'input completo, sarebbe molto semplice. 0diventerebbe \0, 1diventerebbe \1, *diventerebbe ,, e gli altri si mapperebbero su se stessi. Invece ci sono molti shenanigani per impedire che le partite inizino da qualche parte oltre l'inizio o finiscano da qualche parte oltre la fine. !(l.)è un'asserzione che fallirà se l'inizio della partita non è all'inizio dell'input. ~corrisponde a una cella esterna all'input, quindi viene aggiunta a tutti i caratteri che possono trovarsi alla fine della regex. Se segue un altro carattere regex, questo viene cancellato da un quantificatore numerico0che richiede che venga abbinato 0 volte, essenzialmente commentandolo. Per consentire a *( ,) di funzionare correttamente nonostante il test fittizio fuori limite sia in mezzo, le regole di corrispondenza della parentesi del linguaggio sono ampiamente utilizzate. Dalla documentazione:

Le coppie di parentesi ()o parentesi graffe corrispondenti {}si comporteranno come previsto (come le parentesi in regex), ma è anche possibile tralasciare metà di una coppia e farla dedurre, secondo le seguenti regole. )o }raggruppa tutto a sinistra fino all'istruzione di apertura del gruppo non chiusa più vicina dello stesso tipo ( (o {rispettivamente) o all'inizio dello schema se non esiste. Chiude qualsiasi istruzione di apertura non chiusa del tipo opposto nel mezzo di questo intervallo. Un altrimenti ineguagliato (o {è chiuso dalla fine del modello.

Chiaro come il fango, giusto?


Sospiro, dimentico che al di fuori di regex esiste persino un linguaggio corrispondente. Bel lavoro, ma scusa, nessun
voto positivo

@ChristianIrwan in questo sito c'è davvero una sfida per lo sviluppo di linguaggi di corrispondenza 2D, la maggior parte dei quali ha usi degenerati 1d. codegolf.stackexchange.com/questions/47311/…
Sparr

7

CJam, 151 byte

{]Na/Saf+{:m*:sSf-~}%}:J{+:MU{]W=~Jea&,}|}:TM0sa`T
{]Na/Saf+{:m*:sSf-~}%}:J{+:MU{]W=~Jea&,}|}:TM1sa`T
M{{+:M];eas!}:T}|U):UM'[T
MN`T
U(:UM'JT
M\"S+ea`,m*\"T

Le linee corrispondono ai caratteri 01(|)*(in quell'ordine). Provalo online!

Questo non usa espressioni regolari incorporate o altri tipi di pattern matching. In effetti, CJam non ha nessuna di queste caratteristiche. Invece, parte dall'espressione regolare che rappresenta e crea tutte le possibili stringhe che potrebbe corrispondere, per verificare infine se l'input dell'utente è uno di questi.

Esecuzioni di test

Quanto segue utilizza un programma che legge un'espressione regolare da STDIN, sostituisce ciascuno dei suoi caratteri con lo snippet corretto e infine valuta il codice generato per vedere se corrisponde all'input specificato nell'argomento della riga di comando.

$ cat regex.cjam
l"01(|)*""

{]Na/Saf+{:m*:sSf-~}%}:J{+:MU{]W=~Jea&,}|}:TM0sa`T
{]Na/Saf+{:m*:sSf-~}%}:J{+:MU{]W=~Jea&,}|}:TM1sa`T
M{{+:M];eas!}:T}|U):UM'[T
MN`T
U(:UM'JT
M\"S+ea`,m*\"T

"N%ers~
$ cjam regex.cjam '' <<< '(|)'
1
$ cjam regex.cjam '0' <<< '(|)'
0
$ cjam regex.cjam '' <<< '0(|)'
0
$ cjam regex.cjam '0' <<< '0(|)'
1
$ cjam regex.cjam '' <<< '(0|11)*'
1
$ cjam regex.cjam '0' <<< '(0|11)*'
1
$ cjam regex.cjam '11' <<< '(0|11)*'
1
$ cjam regex.cjam '011011000' <<< '(0|11)*'
1
$ cjam regex.cjam '1010' <<< '(0|11)*'
0

Sfortunatamente, questo non è particolarmente veloce. Si soffocerà piuttosto rapidamente se ci sono più di 9 caratteri nell'input o più di una singola stella di Kleene nella regex.

Al costo di 5 byte extra - per un totale di 156 byte - siamo in grado di generare stringhe più brevi per abbinare il potenziale input e deduplicarle. Questo non cambia il funzionamento del codice; lo rende più efficiente.

$ cat regex-fast.cjam 
l"01(|)*""

{]Na/Saf+{:m*:sSf-~}%}:J{+:MU{]W=~Jea&,}|}:TM0sa`T
{]Na/Saf+{:m*:sSf-~}%}:J{+:MU{]W=~Jea&,}|}:TM1sa`T
M{{+:M];eas!}:T}|U):UM'[T
MN`T
U(:UM'JT
M\"S+eas,)m*:sSf-L|\"T

"N%ers~
$ cjam regex-fast.cjam '0101001010' <<< '(01|10)*'
0
$ cjam regex-fast.cjam '011001101001' <<< '(01|10)*'
1
$ cjam regex-fast.cjam '0' <<< '(0*1)*'
0
$ time cjam regex-fast.cjam '101001' <<< '(0*1)*'
1

Ho ancora idea di come potrei renderlo più breve e / o più veloce. Aggiungerò una spiegazione quando sarò soddisfatto dei risultati.
Dennis,

Sembra esserci un superfluo `-escaping of the "` nel modello per *. Indipendentemente da ciò, non sono riuscito a ottenere questo programma per accettare alcun input, anche per il caso più semplice in cui il regex è costituito solo da un 0(vedi test nell'interprete online ). Sto sbagliando?
matz,

1
@matz Il mio codice utilizza argomenti della riga di comando, che non sono implementati in quell'interprete. Prova questo invece.
Dennis,
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.