Il conteggio di "a" se "b" deve essere uguale. L'hai preso al computer?


75

Nel popolare (ed essenziale) libro di informatica, Introduzione ai linguaggi formali e agli automi di Peter Linz, viene spesso affermato il seguente linguaggio formale:

definizione

principalmente perché questa lingua non può essere elaborata con automi a stati finiti. Questa espressione significa "La lingua L è costituita da tutte le stringhe di" a "seguite da" b ", in cui il numero di" a "e" b è uguale e diverso da zero ".

Sfida

Scrivi un programma / funzione funzionante che ottiene una stringa, contenente solo "a" se "b" , come input e restituisce / genera un valore di verità , dicendo se questa stringa è valida il linguaggio formale L.

  • Il programma non può utilizzare strumenti di calcolo esterni, inclusi rete, programmi esterni, ecc. Le shell sono un'eccezione a questa regola; Bash, ad esempio, può utilizzare le utilità della riga di comando.

  • Il programma deve restituire / emettere il risultato in modo "logico", ad esempio: restituendo 10 anziché 0, suono "beep", invio a stdout ecc. Ulteriori informazioni qui.

  • Si applicano le regole standard per il golf.

Questo è un . Vince il codice più breve in byte. In bocca al lupo!

Casi di prova veritieri

"ab"
"aabb"
"aaabbb"
"aaaabbbb"
"aaaaabbbbb"
"aaaaaabbbbbb"

Casi di prova falsi

""
"a"
"b"
"aa"
"ba"
"bb"
"aaa"
"aab"
"aba"
"abb"
"baa"
"bab"
"bba"
"bbb"
"aaaa"
"aaab"
"aaba"
"abaa"
"abab"
"abba"
"abbb"
"baaa"
"baab"
"baba"
"babb"
"bbaa"
"bbab"
"bbba"
"bbbb"

24
L' ingresso può essere vuoto? (Stai dicendo che non fa parte della lingua, ma non se si tratta di un input che dobbiamo considerare.)
Martin Ender

1
E se la nostra lingua non avesse verità o falsità? Sarebbe empty string == truthyed non-empty string == falsyessere accettabile?
DJMcMayhem

5
Bella sfida, ma penso che il titolo potrebbe essere un po 'meno ambiguo (cioè una menzione a^n b^no simile, piuttosto che solo il numero di as pari al numero di bs)
Sp3000

1
@ Sp3000 Ho scelto questo titolo perché sembrava divertente. Potrei cambiarlo più tardi in altro ...

1
Sono un po 'sorpreso che in oltre 50 risposte io sia l'unico a usare un generatore di paser. A dire il vero non è strettamente competitivo sulla lunghezza, ma il problema posto è quello di analizzare un linguaggio semplice ma non banale. Mi piacerebbe molto vedere le risposte in altre sintassi del compilatore-compilatore perché non ho molta familiarità con le scelte.
dmckee,

Risposte:


34

MATL , 5 4 byte

tSP-

Stampa un array non vuoto di 1 s se la stringa appartiene a L e un array vuoto o un array con 0 s (entrambi falsi) in caso contrario.

Grazie a @LuisMendo per giocare a golf a 1 byte!

Provalo online!

Come funziona

t      Push a copy of the implicitly read input.
 S     Sort the copy.
  P    Reverse the sorted copy.
   -   Take the difference of the code point of the corresponding characters
       of the sorted string and the original.

6
La mia seconda risposta (funzionante) alla MATL. :)
Dennis,

2
Strana definizione di verità e falsità: 'aabb' dà -1 -1 1 1 è verità. 'aaabb' dà -1 -1 0 1 1 ed è errato
Etoplay il

3
@Etoplay Un array non vuoto con tutti i suoi valori diversi da zero è veritiero. È la definizione usata in Matlab e Octave
Luis Mendo il

145

Python 3, 32 byte

eval(input().translate(")("*50))

Uscite tramite codice di uscita : errore per falso, nessun errore per vero.

La stringa viene valutata come codice Python, sostituendo le parentesi (per ae )per b. Solo le espressioni della forma a^n b^ndiventano espressioni ben formate di parentesi come ((())), valutando fino alla tupla ().

Eventuali parentesi non corrispondenti danno un errore, come piacerà a più gruppi (()()), poiché non esiste un separatore. Anche la stringa vuota ha esito negativo (sarebbe riuscita exec).

La conversione ( -> a, ) -> beseguita utilizzando str.translate, sostituisce i caratteri come indicato da una stringa che funge da tabella di conversione. Data la stringa di 100 lunghezze ") (" * 50, le tabelle mappano i primi 100 valori ASCII come

... Z[\]^_`abc
... )()()()()(

che prende ( -> a, ) -> b. In Python 2, devono essere fornite conversioni per tutti i 256 valori ASCII, che richiedono "ab"*128un byte in più; grazie a isaacg per averlo segnalato.


58
Ok, è intelligente.
TLW,

Che cosa *128fa?
Erik the Outgolfer,

5
128può essere sostituito da 50(o 99per quella materia) per salvare un byte.
isaacg,

@ Eʀɪᴋ ᴛʜᴇ Gᴏʟғᴇʀ: penso che sia un quantificatore. Ma non conosco davvero Python e non ho ancora trovato documentazione su questo.
Tito

4
@isaacg Grazie, non ero a conoscenza del fatto che sia cambiato per Python 3.
xnor

28

Retina , 12 byte

Ringraziamenti a FryAmTheEggman che ha trovato questa soluzione in modo indipendente.

+`a;?b
;
^;$

Stampa 1per input valido e in 0altro modo.

Provalo online! (La prima riga abilita una suite di test separata da avanzamento riga.)

Spiegazione

I gruppi di bilanciamento richiedono una sintassi costosa, quindi sto cercando di ridurre un input valido in un modulo semplice.

Fase 1

+`a;?b
;

Questo +dice a Retina di ripetere questo stadio in un ciclo fino a quando l'uscita smette di cambiare. Abbina o abo a;be lo sostituisce con ;. Consideriamo alcuni casi:

  • Se as e bs nella stringa non sono bilanciati nello stesso modo (e )normalmente devono esserlo, alcuni ao brimarranno nella stringa, poiché ba, o b;anon possono essere risolti e un singolo ao bda solo non può o. Per sbarazzarsi di tutti i as e la bs ci deve essere quello corrispondente balla destra di ciascuna a.
  • Se l' ae bnon sono tutti annidati (ad esempio, se abbiamo qualcosa di simile ababo aabaabbb), allora finiremo con più ;(e, potenzialmente, alcuni as ed bs), perché la prima iterazione troverà più abs per inserirli e ulteriori iterazioni conserverà il numero di ;nella stringa.

Quindi, se e solo se l'input è nel modulo , finiremo con un singolo nella stringa.anbn;

Fase 2:

^;$

Controlla se la stringa risultante non contiene altro che un solo punto e virgola. (Quando dico "check" intendo in realtà ", conta il numero di corrispondenze di regex dato, ma poiché tale regex può corrispondere al massimo una volta a causa delle ancore, questo dà uno 0o 1.)


25

Haskell, 31 byte

f s=s==[c|c<-"ab",'a'<-s]&&s>""

La comprensione dell'elenco [c|c<-"ab",'a'<-s]crea una stringa di uno 'a'per ciascuno 'a'in s, seguito da uno 'b'per ciascuno 'a'in s. Evita il conteggio abbinando una costante e producendo un output per ogni corrispondenza.

Questa stringa viene controllata per essere uguale alla stringa originale e la stringa originale viene verificata come non vuota.


È adorabile. Spesso dimentico quanto sia utile che Haskell ordini gli elementi di una lista di comprensione in modo coerente e molto specifico.
Vectornaut,

Molto più bello del mio miglior tentativo ( f=g.span id.map(=='a');g(a,b)=or a&&b==(not<$>a)). Molto bene.
Jules,

Wow, non sapevo che si potesse abbinare una costante nella comprensione di una lista!
rubik,

16

Grime , 12 byte

A=\aA?\b
e`A

Provalo online!

Spiegazione

La prima riga definisce un non-terminale A, che corrisponde a una lettera a, possibilmente al non-terminale A, e quindi a una lettera b. La seconda riga corrisponde all'intero input ( e) rispetto al non terminale A.

Versione a 8 byte non competitiva

e`\a_?\b

Dopo aver scritto la prima versione di questa risposta, ho aggiornato Grime per considerarlo _come il nome dell'espressione di livello superiore. Questa soluzione equivale a quanto sopra, ma evita di ripetere l'etichetta A.


Perché non l'hai fatto in J?
Leaky Nun,

@LeakyNun Volevo solo sfoggiare Grime. : P
Zgarb,

Hai costruito questa lingua?
Leaky Nun,

@LeakyNun Sì. Lo sviluppo è lento, ma in corso.
Zgarb,

11

Brachylog , 23 19 byte

@2L,?lye:"ab"rz:jaL

Provalo online!

Spiegazione

@2L,                  Split the input in two, the list containing the two halves is L
    ?lye              Take a number I between 0 and the length of the input              
        :"ab"rz       Zip the string "ab" with that number, resulting in [["a":I]:["b":I]]
               :jaL   Apply juxtapose with that zip as input and L as output
                        i.e. "a" concatenated I times to itself makes the first string of L
                        and "b" concatenated I times to itself makes the second string of L

8
Congratulazioni per essere entrato su tryitonline.net!
Leaky Nun,

10

05AB1E , 9 byte

Codice:

.M{J¹ÔQ0r

Spiegazione:

.M         # Get the most frequent element from the input. If the count is equal, this
           results into ['a', 'b'] or ['b', 'a'].
  {        # Sort this list, which should result into ['a', 'b'].
   J       # Join this list.
    Ô      # Connected uniquified. E.g. "aaabbb" -> "ab" and "aabbaa" -> "aba".
     Q     # Check if both strings are equal.
      0r   # (Print 0 if the input is empty).

Gli ultimi due byte possono essere scartati se si garantisce che l'ingresso non è vuoto.

Utilizza la codifica CP-1252 . Provalo online! .


Cosa succede con input vuoto?
AdmBorkBork,

2
Cerca diverso da zero nel post; è lì :)
Lynn,

@Lynn Tuttavia, le specifiche non dicono solo zero per una lingua valida? Non sull'input.
Emigna,

Vero. Lì ho pensato male. Ma puoi ancora fare .M{J¹ÔQ0rper il tuo.
Emigna,

@Emigna Grazie, ho modificato il post.
Adnan,

9

Gelatina , 6 byte

Ṣ=Ṛ¬Pȧ

Stampa la stringa stessa se appartiene a L o è vuota e 0 altrimenti.

Provalo online! o verifica tutti i casi di test .

Come funziona

Ṣ=Ṛ¬Pȧ  Main link. Argument: s (string)

Ṣ       Yield s, sorted.
  Ṛ     Yield s, reversed.
 =      Compare each character of sorted s with each character of reversed s.
   ¬    Take the logical NOT of each resulting Boolean.
    P   Take the product of the resulting Booleans.
        This will yield 1 if s ∊ L or s == "", and 0 otherwise.
     ȧ  Take the logical AND with s.
       This will replace 1 with s. Since an empty string is falsy in Jelly,
       the result is still correct if s == "".

Versione alternativa, 4 byte (non competitiva)

ṢnṚȦ

Stampa 1 o 0 . Provalo online! o verifica tutti i casi di test .

Come funziona

ṢnṚȦ  Main link. Argument: s (string)

Ṣ     Yield s, sorted.
  Ṛ   Yield s, reversed.
 n    Compare each character of the results, returning 1 iff they're not equal.
   Ȧ  All (Octave-style truthy); return 1 if the list is non-empty and all numbers
      are non-zero, 0 in all other cases.

9

J, 17 byte

#<.(-:'ab'#~-:@#)

Funziona correttamente per dare falsey per la stringa vuota. L'errore è falso.

Vecchie versioni:

-:'ab'#~-:@#
2&#-:'ab'#~#   NB. thanks to miles

Prova e spiegazione

Il verbo principale è un fork composto da questi tre verbi:

# <. (-:'ab'#~-:@#)

Questo significa "Il minore di ( <.) la lunghezza ( #) e il risultato del dente giusto ((-:'ab'#~-:@#) )".

Il dente giusto è un treno 4 , composto da:

(-:) ('ab') (#~) (-:@#)

Lasciate krappresentare il nostro contributo. Quindi, questo equivale a:

k -: ('ab' #~ -:@#) k

-:è l'operatore di gara, quindi i -:test principali per l'invarianza sotto la forcella monadica'ab' #~ -:@# .

Poiché il dente sinistro della forcella è un verbo, diventa una funzione costante. Quindi, la forcella equivale a:

'ab' #~ (-:@# k)

Il dente destro della forcella dimezza ( -:) la lunghezza ( #) di k. Osservare #:

   1 # 'ab'
'ab'
   2 # 'ab'
'aabb'
   3 # 'ab'
'aaabbb'
   'ab' #~ 3
'aaabbb'

Ora, questo è ksolo su input validi, quindi abbiamo finito qui. #errori per stringhe di lunghezza dispari, che non soddisfano mai la lingua, quindi ci siamo anche fatti.

In combinazione con il minore della lunghezza e questo, la stringa vuota, che non fa parte del nostro linguaggio, cede la sua lunghezza 0, e abbiamo finito con tutto.


L'ho modificato in modo 2&#-:'ab'#~#che ti consenta di evitare l'errore e 0invece di emetterlo mentre usi ancora 12 byte.
miglia

@miles Fascinating! Non ci ho mai pensato in quel modo.
Conor O'Brien,

Questo gestisce la stringa vuota?
Zgarb,

@Zgarb l'ha risolto!
Conor O'Brien,

9

Bison / YACC 60 (o 29) byte

(Bene, la compilazione per un programma YACC è un paio di passaggi, quindi potresti voler includerne alcuni. Vedi sotto per i dettagli.)

%%
l:c'\n';
c:'a''b'|'a'c'b';
%%
yylex(){return getchar();}

La funzione dovrebbe essere abbastanza ovvia se sai interpretarla in termini di grammatica formale. Il parser accetta uno abo uno aseguito da qualsiasi sequenza accettabile seguita da a b.

Questa implementazione si basa su un compilatore che accetta la semantica di K&R per perdere alcuni caratteri.

È più prolisso di quanto vorrei con la necessità di definire yylexe chiamare getchar.

Compila con

$ yacc equal.yacc
$ gcc -m64 --std=c89 y.tab.c -o equal -L/usr/local/opt/bison/lib/ -ly

(la maggior parte delle opzioni di gcc sono specifiche per il mio sistema e non dovrebbero essere conteggiate nel conteggio dei byte; potresti voler contare -std=c89che aggiunge 8 al valore elencato).

Corri con

$ echo "aabb" | ./equal

o equivalente.

Il valore di verità viene restituito al sistema operativo e gli errori vengono segnalati anche syntax erroralla riga di comando. Se riesco a contare solo la parte del codice che definisce la funzione di analisi (ovvero trascurare la seconda %%e tutto ciò che segue) ottengo un conteggio di 29 byte.


7

Perl 5.10, 35 17 byte (con -n flag)

say/^(a(?1)?b)$/

Assicura che la stringa inizi con as e quindi ricerchi su bs. Corrisponde solo se entrambe le lunghezze sono uguali.

Grazie a Martin Ender per aver dimezzato il conteggio dei byte e avermi insegnato un po 'sulla ricorsione nelle regex: D

Restituisce l'intera stringa se corrisponde e nulla in caso contrario.

Provalo qui!


Il più vicino che riesco a gestire, incluso il caso di test non vuoto, è di 18 byte: $_&&=y/a//==y/b//(richiede -p), senza il vuoto è possibile rilasciare il valore &&per 16! Così vicino ...
Dom Hastings,

1
Quindi posso fare altri 17 byte: echo -n 'aaabbb'|perl -pe '$_+=y/a//==y/b//'ma non posso spostare un altro byte ... Potrei rinunciare a questo!
Dom Hastings,

7

JavaScript, 54 55 44

s=>s&&s.match(`^a{${l=s.length/2}}b{${l}}$`)

Crea un regex semplice basato sulla lunghezza della stringa e lo testa. Per una lunghezza 4 string ( aabb) il regex assomiglia a:^a{2}b{2}$

Restituisce un valore di verità o falsità.

11 byte salvati grazie a Neil.

f=s=>s&&s.match(`^a{${l=s.length/2}}b{${l}}$`)
// true
console.log(f('ab'), !!f('ab'))
console.log(f('aabb'), !!f('aabb'))
console.log(f('aaaaabbbbb'), !!f('aaaaabbbbb'))
// false
console.log(f('a'), !!f('a'))
console.log(f('b'), !!f('b'))
console.log(f('ba'), !!f('ba'))
console.log(f('aaab'), !!f('aaab'))
console.log(f('ababab'), !!f('ababab'))
console.log(f('c'), !!f('c'))
console.log(f('abc'), !!f('abc'))
console.log(f(''), !!f(''))


Il f=può essere omesso.
Leaky Nun,

Un'espressione di funzione è una presentazione valida o deve essere effettivamente, ahem, funzionale?
Scimonster,

Una funzione è un invio valido.
Leaky Nun,

@TimmyD Restituiva vero, ma ora restituisce falso.
Scimonster,

1
s=>s.match(`^a{${s.length/2}}b+$`)?
l4m2

5

C, 57 53 byte

t;x(char*s){t+=*s%2*2;return--t?*s&&x(s+1):*s*!1[s];}

Vecchia soluzione lunga 57 byte:

t;x(char*s){*s&1&&(t+=2);return--t?*s&&x(s+1):*s&&!1[s];}

Compilato con gcc v. 4.8.2 @Ubuntu

Grazie ugoren per i suggerimenti!

Provalo su Ideone!


Dato che sono nuovo qui e non posso ancora commentare altre risposte, voglio solo sottolineare che la soluzione 62b di @Josh dà falsi positivi su stringhe come "aaabab".
Jasmes,

Passare (t+=2)a t++++per -1 byte.
owacoder,

@owacoder t++++non è un codice C valido.
Jasmes,

Risparmia con t+=*s%2*2e:*s*!1[s]
ugoren il

Risposta molto intelligente! Purtroppo fallisce nell'input "ba": ideone.com/yxixG2
Josh

4

Retina , 22 byte

Un'altra risposta più breve nella stessa lingua è appena arrivata ...

^(a)+(?<-1>b)+(?(1)c)$

Provalo online!

Questa è una vetrina dei gruppi di bilanciamento in regex, che è spiegato completamente da Martin Ender .

Dato che la mia spiegazione non si avvicinerebbe alla metà di essa, mi limiterò a collegarla e non tenterò di spiegare, in quanto ciò sarebbe dannoso per la gloria della sua spiegazione.


4

Befunge-93, 67 byte

0v@.<  0<@.!-$<  >0\v
+>~:0`!#^_:"a" -#^_$ 1
~+1_^#!-"b" _ ^#`0: <

Provalo qui! Potrebbe spiegare come funziona in seguito. Potrebbe anche provare a giocare a golf un po 'di più, solo per i calci.


3

MATL , 9 byte

vHI$e!d1=

Provalo online!

L'array di output è vero se non è vuoto e tutte le sue voci sono diverse da zero. Altrimenti è falso. Ecco alcuni esempi .

v     % concatenate the stack. Since it's empty, pushes the empty array, []
H     % push 2
I$    % specify three inputs for next function
e     % reshape(input, [], 2): this takes the input implicitly and reshapes it in 2
      % columns in column major order. If the input has odd length a zero is padded at
      % the end. For input 'aaabbb' this gives the 2D char array ['ab;'ab';'ab']
!     % transpose. This gives ['aaa;'bbb']
d     % difference along each column
1=    % test if all elements are 1. If so, that means the first tow contains 'a' and
      % the second 'b'. Implicitly display

2
Questa è una comoda definizione di verità. (Sapevo del requisito diverso da zero, ma non di quello non vuoto.)
Dennis

3

codice macchina x86, 29 27 byte

hexdump:

33 c0 40 41 80 79 ff 61 74 f8 48 41 80 79 fe 62
74 f8 0a 41 fe f7 d8 1b c0 40 c3

Codice dell'Assemblea:

    xor eax, eax;
loop1:
    inc eax;
    inc ecx;
    cmp byte ptr [ecx-1], 'a';
    je loop1;

loop2:
    dec eax;
    inc ecx;
    cmp byte ptr [ecx-2], 'b';
    je loop2;

    or al, [ecx-2];
    neg eax;
    sbb eax, eax;
    inc eax;
done:
    ret;

Passa all'inizio sui abyte, quindi sui seguenti byte "b". Il primo loop aumenta un contatore e il secondo loop lo diminuisce. Successivamente, esegue un OR bit a bit tra le seguenti condizioni:

  1. Se il contatore non è 0 alla fine, la stringa non corrisponde
  2. Se il byte che segue la sequenza di bs non è 0, anche la stringa non corrisponde

Quindi, deve "invertire" il valore di verità in eax- impostarlo su 0 se non fosse 0, e viceversa. Si scopre che il codice più corto per farlo è il seguente codice a 5 byte, che ho rubato dall'output del mio compilatore C ++ per result = (result == 0):

    neg eax;      // negate eax; set C flag to 1 if it was nonzero
    sbb eax, eax; // subtract eax and the C flag from eax
    inc eax;      // increase eax

1
Penso che tu possa migliorare la tua negazione. Prova: neg eaxper impostare la bandiera di trasporto come prima, cmcper invertire la bandiera di trasporto e salcimpostare AL su FFh o 0 a seconda che sia impostata o meno la bandiera di trasporto. Salva 2 byte, anche se finisce con un risultato a 8 bit anziché a 32 bit.
Jules,

La stessa cosa usando string ops, con ESI che punta alla stringa di input e restituendo il risultato in AL (usa SETcc, richiede 386+):xor eax,eax | xor ecx,ecx | l1: inc ecx | lodsb | cmp al, 'a' | jz l1 | dec esi | l2: lodsb | cmp al,'b' | loopz l2 | or eax,ecx | setz al | ret
ninjalj

@ninjalj Dovresti pubblicarlo in una risposta: è sufficientemente diverso dal mio e sospetto che sia significativamente più breve!
Anatolyg,

3

Rubino, 24 byte

eval(gets.tr'ab','[]')*1

(Questa è solo la brillante idea di xnor in forma Ruby. La mia altra risposta è una soluzione che mi è venuta in realtà.)

Il programma accetta l'input, trasforma ae bin [e] rispettivamente, e lo valuta.

L'input valido formerà un array nidificato e non accade nulla. Un'espressione sbilanciata farà arrestare il programma. In Ruby l'input vuoto viene valutato come nil, il che si arresterà in modo anomalo perché nilnon ha definito un *metodo.


3

Sed, 38 + 2 = 40 byte

s/.*/c&d/;:x;s/ca(.*)bd/c\1d/;tx;/cd/p

Un output di stringa non vuoto è veritiero

Gli automi a stati finiti non possono farlo, dici? Che dire degli automi a stati finiti con loop . : P

Corri con re nbandiere.

Spiegazione

s/.*/c&d/        #Wrap the input in 'c' and 'd' (used as markers)
:x               #Define a label named 'x'
s/ca(.*)bd/c\1d/ #Deletes 'a's preceded by 'c's and equivalently for 'b's and 'd's. This shifts the markers to the center
tx               #If the previous substitution was made, jump to label x
/cd/p            #If the markers are next to one another, print the string

Bel approccio. Grazie per la rottura.
joeytwiddle,

3

JavaScript, 44 42

Cancellato 44 è ancora regolare 44; (

f=s=>(z=s.match`^a(.+)b$`)?f(z[1]):s=="ab"

Opere ricorsivamente togliendo l'esterno aed be ricorsivamente utilizzando il valore interno selezionato ma .+. Quando non c'è corrispondenza a ^a.+b$sinistra, il risultato finale è se la stringa rimanente è il valore esatto ab.

Casi test:

console.log(["ab","aabb","aaabbb","aaaabbbb","aaaaabbbbb","aaaaaabbbbbb"].every(f) == true)
console.log(["","a","b","aa","ba","bb","aaa","aab","aba","abb","baa","bab","bba","bbb","aaaa","aaab","aaba","abaa","abab","abba","abbb","baaa","baab","baba","babb","bbaa","bbab","bbba","bbbb"].some(f) == false)

3

ANTLR, 31 byte

grammar A;r:'ab'|'a'r'b'|r'\n';

Utilizza lo stesso concetto della risposta YACC di @ dmckee , leggermente più golfato.

Per eseguire il test, seguire i passaggi della guida introduttiva di ANTLR . Quindi, inserisci il codice sopra in un file chiamato A.g4ed esegui questi comandi:

$ antlr A.g4
$ javac A*.java

Quindi prova dando input su STDIN in questo grun A rmodo:

$ echo "aaabbb" | grun A r

Se l'input è valido, non verrà emesso nulla; se non è valido,grun darà un errore (o token recognition error, extraneous input, mismatched inputo no viable alternative).

Esempio di utilizzo:

$ echo "aabb" | grun A r
$ echo "abbb" | grun A r
line 1:2 mismatched input 'b' expecting {<EOF>, '
'}

Trucco intelligente che aggiunge la nuova riga come alternativa in una singola regola. Penso che potrei salvarne alcuni anche in yacc. La grammerparola chiave è una puzzolente per giocare a golf con antlr. Mi piace usare Fortran .
dmckee,

3

C, 69 byte

69 byte:

#define f(s)strlen(s)==2*strcspn(s,"b")&strrchr(s,97)+1==strchr(s,98)

Per chi non ha familiarità:

  • strlen determina la lunghezza della stringa
  • strcspn restituisce il primo indice nella stringa in cui è stata trovata l'altra stringa
  • strchr restituisce un puntatore alla prima occorrenza di un personaggio
  • strrchr restituisce un puntatore all'ultima occorrenza di un personaggio

Un grande grazie a Titus!


1
salva un byte con >97invece di==98
Tito

2
La soluzione di 61 byte fornisce falsi positivi su stringhe come "aaabab". Vedi ideone.com/nmT8rm
Jasmes,

Ah, hai ragione Jasmes, grazie. Dovrò ripensarci un po '.
Josh,

Tornando alla soluzione a 69 byte, non sono sicuro di riuscire ad accorciarmi usando questo approccio.
Josh,

3

R, 64 61 55 byte, 73 67 byte (robusto) o 46 byte (se sono consentite stringhe vuote)

  1. Ancora una volta, la risposta di xnor è stata rielaborata. Se è implicito dalle regole che l'input sarà costituito da una stringa di as e bs, dovrebbe funzionare: restituisce NULL se l'espressione è valida, genera ed errore o nient'altro.

    if((y<-scan(,''))>'')eval(parse(t=chartr('ab','{}',y)))
    
  2. Se l'input non è affidabile e può contenere alcuni rifiuti, ad esempio aa3bb, è necessario prendere in considerazione la seguente versione (deve restituire TRUEper veri casi di test, non NULL):

    if(length(y<-scan(,'')))is.null(eval(parse(t=chartr("ab","{}",y))))
    
  3. Infine, se sono consentite stringhe vuote, possiamo ignorare la condizione per l'input non vuoto:

    eval(parse(text=chartr("ab","{}",scan(,''))))
    

    Ancora una volta, NULL in caso di successo, altrimenti.


Non conosco R, qual è il tuo risultato per input vuoto? (Dovrebbe essere falso)
Tito

Non esiste davvero un modo più breve per testare input vuoti?
Tito

Versione 1: proprio niente (ingresso corretto restituisce solo NULL), versione 2: proprio niente (ingresso corretto restituisce solo TRUE), versione 3 (supponendo stringhe vuote sono OK, come stato): NULL. R è un linguaggio statistico orientato agli oggetti che dattiloscrive tutto semplicemente OK, senza alcun preavviso.
Andreï Kostyrka,

Questa (risposta 1) può essere ulteriormente migliorata a 55 byte:if((y<-scan(,''))>'')eval(parse(t=chartr('ab','{}',y)))
Giuseppe

3

Japt , 11 byte

©¬n eȦUg~Y

Provalo online!

Dà o trueo false, tranne che """" che è falsa in JS.

Disimballato e come funziona

U&&Uq n eXYZ{X!=Ug~Y

U&&     The input string is not empty, and...
Uq n    Convert to array of chars and sort
eXYZ{   Does every element satisfy...?
X!=       The sorted char does not equal...
Ug~Y      the char at the same position on the original string reversed

Adottato dalla soluzione MATL di Dennis .


2

C (Ansi), 65 75 byte

golfed:

l(b,i,j,k)char*b;{for(i=j=0;(k=b[i++])>0&k<=b[i];)j+=2*(k>97)-1;return !j;}

Spiegazione:

Imposta un valore j e incrementa j su ogni b e diminuisce j su qualsiasi altra cosa. Controllato se la lettera precedente è inferiore o uguale alla lettera successiva in modo da impedire a abab di funzionare

Le modifiche

Aggiunti controlli per casi abab.


Questo non darà falsi positivi su stringhe come bao abab?
Zgarb,

Ah sì, ho letto male il post dal momento che non riuscivo a vedere l'immagine dal momento che è bloccato per me. Risolvendolo!
dj0wns

2

Lotto, 133 byte

@if ""=="%1" exit/b1        Fail if the input is empty
@set a=%1                   Grab the input into a variable for processing
@set b=%a:ab=%              Remove all `ab` substrings
@if "%a%"=="%b%" exit/b1    Fail if we didn't remove anything
@if not %a%==a%b%b exit/b1  Fail if we removed more than one `ab`
@if ""=="%b%" exit/b0       Success if there's nothing left to check
@%0 %b%                     Rinse and repeat

Restituisce uno ERRORLEVELdi 0 in caso di successo, 1 in caso di fallimento. A Batch non piace fare la sostituzione della sottostringa su stringhe vuote, quindi dobbiamo controllarlo in anticipo; se un parametro vuoto fosse legale, la riga 6 non sarebbe necessaria.


2

PowerShell v2 +, 61 52 byte

param($n)$x=$n.length/2;$n-and$n-match"^a{$x}b{$x}$"

Prende l'input $ncome stringa, crea $xcome half the length. Costruisce un -andconfronto booleano tra $ne un -matchoperatore regex rispetto alla regex di un numero uguale di a'se b'. Uscite booleane $TRUEo $FALSE. L' $n-andè lì per tenere conto di ""= $FALSE.

Alternativo, 35 byte

$args-match'^(a)+(?<-1>b)+(?(1)c)$'

Questo utilizza la regex dalla risposta di Leaky , basata su gruppi di bilanciamento .NET, incapsulati nell'operatore PowerShell -match. Restituisce la stringa per verità o stringa vuota per falso.


Nella versione alternativa si dovrebbe valutare -matchcontro $args[0], altrimenti -matchfunzionerà come un filtro
Mathias R. Jessen

@ MathiasR.Jessen Nel codice di produzione, sì, ma possiamo giocare a golf [0]qui perché ci viene fornito solo un input e abbiamo solo bisogno di un valore di verità / falsità come output. Poiché una stringa vuota è falsa e una stringa non vuota è vera, possiamo filtrare in base all'array e recuperare la stringa di input o restituirla, il che soddisfa i requisiti della sfida.
AdmBorkBork,

2

Pyth - 13 byte

&zqzS*/lz2"ab

Ha spiegato:

  qz          #is input equal to
          "ab #the string "ab"
     *        #multiplied by
      /lz2    #length of input / 2
    S         #and sorted?
&z            #(implicitly) print if the above is true and z is not empty

Puoi usare una stringa come input e poi &qS*/lQ2"ab
crearla

@LeakyNun grazie per il suggerimento! Puoi spiegare come / perché funziona? Questa è la prima volta che uso
Pyth

Ad esempio, +4si espanderà a +4Q(implicito riempimento di argomenti)
Leaky Nun,

2

Haskell, 39 byte

p x=elem x$scanl(\s _->'a':s++"b")"ab"x

Esempio di utilizzo: p "aabb"->True .

scanl(\s _->'a':s++"b")"ab"xcostruire un elenco di tutti ["ab", "aabb", "aaabbb", ...]con un totale di (length x)elementi. elemcontrolla se xè in questo elenco.


2

Python, 43 40 byte

lambda s:''<s==len(s)/2*"a"+len(s)/2*"b"

ha considerato l'ovvia soluzione grazie a Leaky Nun

altra idea, 45 byte:

lambda s:s and list(s)==sorted(len(s)/2*"ab")

-4 byte usando len / 2 (ricevo un errore quando arriva la metà)

ora fornisce false per la stringa vuota

-3 byte grazie a xnor


Sì, i lambda non devono essere nominati.
Leaky Nun,

lambda s:list(s)==sorted("ab"*len(s)//2)(Python 3)
Leaky Nun,

lambda s:s=="a"*len(s)//2+"b"*len(s)//2(Python 3)
Leaky Nun,

sì, me ne sono reso conto mentre lo pubblicavo. lol, la soluzione ovvia è più breve in Python 2:
KarlKastor,

1
Puoi fare ''<invece di s andescludere il caso vuoto.
xnor
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.