Correggi le mie parole balbettate


12

La balbuzie è un problema che molti di noi potrebbero aver sperimentato o almeno visto. Sebbene la maggior parte dei famosi software di riconoscimento vocale abbia seri problemi con il parlare balbettato, immaginiamo un software che capisca la balbuzie, ma non riesca a risolverli e li scriva solo così com'è.

Un esempio di testo scritto da un software del genere può essere così: "per favore, stai attento" . In questo esempio "attento" è la parola originale e "ca ca" sono le parole balbettate.

Sfida

Scrivi un programma o una funzione che corregge le parole balbettate rimuovendole dall'input mantenendo le parole originali. Ad esempio, la versione fissa di "per favore fai attenzione" sarebbe "per favore fai attenzione" .

Questo è , la risposta più breve in ogni lingua vince!

Cosa sono le parole balbettate?

La balbuzie ha molte varianti diverse. Ma per semplicità di questa sfida, la limiteremo alle seguenti regole:

  • Le parole disturbate possono essere una parte incompleta o l'intera parola originale. Per "parte incompleta" intendo che la parola originale dovrebbe iniziare esattamente con la parola balbettata. Ad esempio "ope" e "open" possono entrambi essere una parola balbettata per "open" , ma "pen" non può esserlo poiché "open" non inizia con "pen" .
  • Le parole balbettate devono contenere almeno una delle vocali "aeiou" . Ad esempio "stella" può essere una parola balbettata per "inizio" in quanto contiene "a" , ma "st" non può essere una parola balbettata in quanto non contiene alcuna delle vocali menzionate.
  • Le parole disturbate possono apparire solo prima della parola originale e devono essere ripetute almeno due volte per essere valide (la parola originale non conta nelle ripetizioni). Ad esempio "oo open" ha balbettato parole ma "o open o" no, perché la "o" dopo la parola originale non conta e "o" prima che la parola originale non venga ripetuta almeno due volte. "vai vai vai vai vai vai" ha cinque ripetizioni di parole balbettate prima della parola originale ed è valida.
  • Un singolo insieme di parole ripetute balbettate non può contenere forme miste e le parole dovrebbero essere esattamente l'una come l'altra. Ad esempio "op o op open" non conta come parole balbettate. D'altra parte "o op op open" ha balbettato parole perché la prima "o" è vista come una parola completamente diversa qui e le due "op" sono contate come parole balbettate di "open" .
  • Nel caso di più insiemi validi di parole ripetute balbettate l'una dopo l'altra, rimane solo l'ultima parola originale. Ad esempio, in "ooo op op op open" , la parte "oo o" è vista come parole balbettate della prima "op" , quindi dovrebbero essere rimosse e quindi "op op op" è visto come parole balbettate di "open " e dovrebbero essere rimossi anche, quindi solo " aperto " sarà lasciato dopo la rimozione di parole balbettate. Puoi presumere che più insiemi validi di ripetute parole balbettate avvengano solo da sinistra a destra, quindi la correzione di "op op ooo open" comporterebbe "op op open" (aka

Ingresso

  • L'input è una stringa a riga singola contenente solo lettere inglesi ASCII (az), cifre (0-9) e spazi. Il maiuscolo non è importante e puoi decidere di accettare lettere minuscole o maiuscole o entrambe, ma il case dovrebbe rimanere lo stesso e non puoi modificarlo nell'output.
  • È possibile utilizzare un elenco di lettere (come ["l","i","s","t"," ","o","f"," ","l","e","t","t","e","r","s"]) anziché la stringa, ma non è possibile utilizzare un elenco di parole. Se la tua lingua ha una struttura di input diversa, usala. Il punto è che l'input non dovrebbe essere separato da parole, quindi il costo di separazione delle parole in alcune lingue potrebbe effettivamente innescare altre soluzioni creative.
  • L'input potrebbe contenere nessuna, una o più parole balbettate al suo interno.
  • Le parole e / o i numeri sono separati da un singolo spazio e l'input non conterrà spazi doppi uno accanto all'altro.

Produzione

  • Una stringa o un elenco di lettere o la struttura appropriata nella tua lingua con tutte le parole balbettate rimosse dall'input.
  • Le parole di output devono essere separate esattamente da uno spazio (uguale all'input).
  • Sono consentiti la nuova riga o lo spazio iniziale e finale singolo.

Sono vietate le scappatoie standard .

Casi test

Nessuna parola balbettata:

"hello world" => "hello world"

Una singola istanza di parole ripetute balbettate:

"ope ope ope ope open the window" => "open the window"

Istanze multiple di parole ripetute balbettate:

"there is is is is something un un under the the the table" => "there is something under the table"

Nessuna parola balbettata, non abbastanza ripetuta:

"give me the the book" => "give me the the book"

Nessuna parola balbettata, non hanno nessuna delle vocali menzionate:

"h h help m m m me" => "h h help m m m me"

I numeri non sono parole balbettate, non hanno nessuna delle vocali menzionate:

"my nu nu number is 9 9 9 9876" => "my number is 9 9 9 9876"

Ma una parola con vocali e numeri può avere parole balbettate:

"my wi wi windows10 is slow" => "my windows10 is slow"

Diverse forme di parole balbettate nello stesso gruppo di ripetizione non vengono conteggiate:

"this is an ant antarctica does not have" => "this is an ant antarctica does not have"

Per più insiemi continui di parole balbettate, una dopo l'altra, mantieni solo l'ultima parola originale:

"what a be be be beauti beauti beautiful flower" => "what a beautiful flower"

Questo non è un caso di più insiemi continui di parole balbettate l'una dopo l'altra:

"drink wat wat wa wa water" => "drink wat wat water"

Ingresso vuoto:

"" => ""

Più casi dai commenti:

"a ab abc" => "a ab abc"
"a ab ab abc" => "a abc"
"ab ab abc abcd" => "abc abcd"
"a a ab a able" => "ab a able"
"i have ave ave average" => "i have average"
"my wi wi windows 10 is cra cra crap" => "my windows 10 is crap"

Un elenco facile da copiare dei casi di test sopra riportati:

"hello world",
"ope ope ope ope open the window",
"there is is is is something un un under the the the table",
"give me the the book",
"h h help m m m me",
"my nu nu number is 9 9 9 9876",
"my wi wi windows10 is slow",
"this is an ant antarctica does not have",
"what a be be be beauti beauti beautiful flower",
"drink wat wat wa wa water",
"",
"a ab abc",
"a ab ab abc",
"ab ab abc abcd",
"a a ab a able",
"i have ave ave average",
"my wi wi windows 10 is cra cra crap"

2
"drink wat wat wa wa water" => "drink wat wat water"sembra davvero che la regola dovrebbe applicarsi in modo ricorsivo in modo che diventi "bere acqua"
Giona

2
@Giona se leggi l'ultimo elemento in Cosa sono le parole balbettate? Ho spiegato questa questione. "Wat Wat" non sono parole balbettate per "wa" e risolviamo solo una volta, quindi una volta ottenuto "bevi acqua wat wat", non ripariamo di nuovo per rimuovere le parole balbettate appena formate. Ma in un caso inverso come "wa wa wat wat water" il risultato sarà "water" perché "wa wa" sono parole balbettate per il primo "wat" e "wat wat" sono anche parole balbettate di "acqua".
Night2

Ok abbastanza bene, stavo solo dicendo che avrebbe senso continuare a risolvere fino a quando non ci riuscivi più, ma posso vedere l'argomento per concentrarsi anche su una singola iterazione.
Giona,

Risposte:


6

C (gcc), 183 180 178 byte

f(s,t,u,T,e,r)char*s,*t,*u,*r;{for(;s=index(u=s,32);T>1&strpbrk(u,"aeiou")-1<s&&memmove(s=u,t-e,r-t-~e))for(e=++s-u,r=u+strlen(t=u),T=0;(t+=e)<r&!memcmp(u,t,e-1)&t[-1]==32;++T);}

Provalo online!

Bene, C certamente non può competere con la brevità di regex ...

Questo è particolarmente difficile da leggere perché ho finito per far collassare l'intera funzione in una singola coppia nidificata di forloop (senza corpo!). Ciò rende l'ordine di valutazione tutto traballante: il codice vicino all'inizio viene effettivamente eseguito per ultimo.

Il mio trucco preferito qui è strpbrk(u,"aeiou")-1<s. Questo è usato per verificare se la parola ripetuta contiene vocali. uindica l'inizio della parola ripetuta e sindica la seconda ripetizione della parola; per esempio:

"my nu nu number is 9 9 9 9876"
    ^  ^
    u  s

strpbrkquindi trova il primo carattere "aeiou"che appare dopo u. (In questo caso, è 'u'immediatamente dopo.) Quindi possiamo verificare che ciò accada prima sper verificare che la parola contenga una vocale. Ma c'è un piccolo problema: strpbrkrestituisce NULL(cioè 0) se non c'è vocale nell'intera stringa. Per risolvere questo problema, sottraggo semplicemente 1, che si trasforma 0in 0xffffffffffffffff(sulla mia macchina) a causa dell'overflow. Essendo il valore massimo di un puntatore, questo è decisamente maggiore di s, causando il fallimento del controllo.

Ecco una versione leggermente più vecchia (prima della trasformazione che confondeva il flusso di controllo) con commenti:

f(s,t,u,c,n,e)char*s,*t,*u,*e;{
    // set s to the position of the *next* check; u is the old position
    for(;s=index(u=s,32);) {
        // count the length of this word (incl. space); also fix s
        n=++s-u;
        // find the end of the string; assign temp pointer to start
        e=u+strlen(t=u);
        // count repetitions of the word
        for(c=0;                // number of repetitions
            (t+=n)              // advance temp pointer by length of word
            <e&&                // check that we haven't hit the end...
            !strncmp(u,t,n-1)&& // ...and the word matches...
            t[-1]==32;          // ...and the previous character was space
            ++c);               // if so, increment count
        // decide whether to remove stuttering
        c>1&&                    // count must be at least 2
        strpbrk(u,"aeiou")-1<s&& // word must contain a vowel
        // if so, move everything after the last occurrence back to the
        // beginning, and also reset s to u to start scanning from here again
        memmove(s=u,t-n,e-t+n+1);
    }
}

Grazie a @ user1475369 per 3 byte e @ceilingcat per 2 byte.


-3 byte sostituendo T>1&&strpbrkcon T>1&strpbrk, r&&!strncmpcon r&!strncmpe &&t[-1]con &t[-1].
girobuz,


@ceilingcat Il tuo collegamento fallisce alcuni dei casi di test, ma 2 di queste 3 ottimizzazioni funzionano; Grazie!
Maniglia della porta

Suggerisci bcmp()invece dimemcmp()
ceilingcat il

4

Perl 5 (-p), 34 byte

Basato sulla risposta eliminata di Arnauld.

s/(\b(\w*[aeiou]\w*) )\1+(?=\2)//g

Provalo online!


Questo produce "zab" per "za a ab". Non credo che ci dovrebbe essere una balbuzie rilevata in quell'input.
ricorsivo

@recursive grazie, risolto.
Grimmy,

2
Ho esaminato i casi di test e ho escogitato un regex, solo per trovarlo già qui. Naturalmente questo significa che la banale porta Retina è di 30 byte.
Neil,

3

05AB1E , 30 29 28 byte

-1 byte grazie a Kevin Cruijssen

#Rγε®y¬©žMÃĀiнkĀDygαΘ+∍]R˜ðý

Provalo online!

05AB1E, non avendo regex, sicuramente non sembra lo strumento migliore per questo compito. Tuttavia, in qualche modo riesce a battere appena Retina.

#                     # split on spaces
 R                    # reverse the list of words
  γ                   # group consecutive identical words together

ε                   ] # for each group of words y:
 ®                    #  push the previous word on the stack (initially -1)
  y                   #  push another copy of y
   ¬                  #  push the first element without popping
    ©                 #  save the current word for the next loop
     žM               #  built-in constant aeiou
       ÃĀi          ] #  if the length of the intersection is non-zero:
           н          #   take the first element of y
            kĀ        #   0 if the previous word starts with this word, 1 otherwise
              D       #   duplicate
               yg     #   length of y (the number of consecutive identical words)
                 α    #   subtract the result of the startsWith check
                  Θ   #   05AB1E truthify (1 -> 1, anything else -> 0)
                   +  #   add the result of the startsWith check
                    ∍ #   set the length of y to that value
                      #  otherwise leave y unchanged

˜                     # flatten the modified list of groups of words
 R                    # reverse the list of words
  ðý                  # join with spaces

1
È possibile rimuovere il gprima del Ā. La verifica in stile Python comporterà già 0stringhe vuote e stringhe 1non vuote.
Kevin Cruijssen,

@KevinCruijssen bella scoperta!
Grimmy,

1

Perl 6 , 45 byte

{S:g/<|w>(\S*<[aeiou]>\S*)\s$0+%%\s{}<?$0>//}

Provalo online!

Una semplice risposta regex che sostituisce tutte le corrispondenze di stutter con la stringa vuota.


1

Stax , 26 byte

å╬↓<▀.₧▀"╦n▐∞↨vß%ù:Qa3@=↔_

Esegui ed esegui il debug

Porta diretta dalla risposta perl di @Grimy. Stax è in grado di ridurre letteralmente il pattern regex e ha una costante di vocali che è in grado di ridursi [aeiou].


1

Pulito , 184 byte

import StdEnv,Data.List,Text
$s=join[' '](f(group(split[' ']s)))
f[[a]:t]=[a:f t]
f[h=:[a:_]:t=:[[b:_]:_]]|intersect['aeiou']a==[]=h++f t|isPrefixOf a b=f t=if(h>[a,a])[a]h++f t
f[]=[]

Provalo online!

Definisce $ :: [Char] -> [Char], che divide la stringa di input su spazi e raggruppa elementi identici che vengono quindi compressi dall'helper f :: [[[Char]]] -> [[Char]], unendosi prima di tornare.

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.