Applica le regole di punteggiatura inglesi


11

Sei stato assunto per scrivere del codice per un'app di dettatura, che prende l'input vocale da una fonte parlata, lo analizza come parole e lo scrive su uno schermo.

La direzione non si fida davvero di te con tutto quel potere nel progetto - sei noto di stare seduto a giocare a golf code tutto il giorno invece di fare il tuo lavoro, sfortunatamente - quindi ti danno solo un compito davvero semplice da eseguire: trasformare un Frase con punteggiatura intervallata in una frase correttamente formattata, dove "formattato correttamente" è definito di seguito.

  1. La frase è la stringa di input. Una parola è un gruppo di caratteri contrapposti non spaziali. Una punteggiatura è una parola il cui primo carattere è ^.

  2. Una parola è maiuscola se la prima lettera della parola non è una lettera minuscola (le parole maiuscole corrispondono alla regex /[^a-z].*/).

  3. La prima parola della frase deve essere in maiuscolo.

  4. A ^COMMAè il carattere virgola ,e ha uno spazio che segue ma non precedente. aaa ^COMMA bbbdiventa aaa, bbb.

  5. A ^COLONè una virgola che sembra :.

  6. A ^SEMICOLONè una virgola che sembra ;.

  7. A ^PERIODè una virgola che sembra .. La parola che segue a ^PERIODdeve essere in maiuscolo.

  8. A ^BANGè un periodo che sembra !.

  9. A ^DASHè il carattere trattino -e ha uno spazio sia precedente che successivo.

  10. A ^HYPHENè anche il carattere trattino -ma non ha spazio che segue o precede.

  11. An ^EMDASHè un trattino (non un trattino!) Che si scrive --.

  12. An ^OPENQUOTEè un carattere di citazione "che ha uno spazio che precede ma non segue. La parola che segue a ^OPENQUOTEdeve essere in maiuscolo. Se un ^OPENQUOTEè preceduto da una Parola che non è Punteggiatura, aggiungi una ^COMMAtra quella parola e la ^OPENQUOTE. Se una ^OPENQUOTEè preceduta da una punteggiatura che rende maiuscola la parola successiva, questa passa ^OPENQUOTEalla parola successiva.

  13. A ^CLOSEQUOTEè il digrafo ,"che ha uno spazio che segue ma non precedente. Se una ^CLOSEQUOTEè preceduta da una ^COMMA, ^PERIODo ^BANG, che punteggiatura scompare e la ^CLOSEQUOTEsi scrive ,", ."o !", rispettivamente. Se la punteggiatura che scompare specificava una maiuscola, quella maiuscola deve ancora avvenire sulla successiva parola disponibile.

  14. Gli spazi iniziali o finali del risultato finale completo devono essere rimossi e qualsiasi stringa di due o più spazi di una riga deve essere compressa in un singolo carattere di spazio.

  15. Ogni caso non descritti sopra (es ^COMMA ^COMMAo ^SEMICOLON ^CLOSEQUOTEo ^UNDEFINEDPUNCTUATION) non avviene nello ingresso ben formato ed è quindi un comportamento indefinito.

Il team di sviluppo ti informa di quanto segue:

  • Il progetto è stato scritto nella lingua [la tua lingua qui] e dovrebbe essere il più breve possibile in modo da occupare il minor spazio possibile quando si tratta di un'app per Android / iPhone. Cerchi di spiegare che non è così che funziona lo sviluppo di app, ma non ascoltano. Ma hey, che coincidenza! Sei un golfista straordinario nella [tua lingua qui] !

  • L'app non avrà autorizzazioni di accesso al web e non ci saranno librerie installate che eseguono questa formattazione per te. Probabilmente puoi convincere il team a consentirti di avere una libreria regex se ne esiste una per la tua lingua, se pensi di averne bisogno.

  • Il supporto per le citazioni nidificate che utilizzano correttamente le virgolette doppie / singole è pianificato per una versione successiva dell'app, ma non per la versione su cui stai lavorando ora, quindi non preoccuparti.

  • Il management è un grande fan dello sviluppo test-driven, e quindi il team di sviluppo ha già avuto una scimmia tastiera sfortunata scrivere alcuni test per la tua parte del programma: (nuove righe aggiunte per la leggibilità, trattale come spazi)

    Ingresso:

    hello ^COMMA   world ^BANG
    

    Produzione:

    Hello, world!
    

    Ingresso:

    once upon a time ^COMMA there was a horse ^PERIOD that horse cost me $50
    ^PERIOD ^OPENQUOTE eat your stupid oats ^COMMA already ^BANG ^CLOSEQUOTE
    I told the horse ^PERIOD the horse neighed back ^OPENQUOTE no ^CLOSEQUOTE
    and died ^PERIOD THE END
    

    Produzione:

    Once upon a time, there was a horse. That horse cost me $50. "Eat your
    stupid oats, already!" I told the horse. The horse neighed back, "No,"
    and died. THE END
    

    Ingresso:

    begin a ^PERIOD b ^COMMA c ^COLON d ^SEMICOLON e ^BANG f ^HYPHEN g ^DASH h
    ^EMDASH i ^OPENQUOTE j ^PERIOD ^OPENQUOTE k ^SEMICOLON ^OPENQUOTE l
    ^CLOSEQUOTE m ^BANG ^CLOSEQUOTE n ^PERIOD 0x6C6F6C end
    

    Produzione:

    Begin a. B, c: d; e! F-g - h--i, "j. "K; "l," m!" N. 0x6C6F6C end
    

Questo è un codice golf: vince il punteggio più basso. È possibile scrivere una funzione di un argomento stringa o un programma che legge da STDIN e che scrive su STDOUT.


Cosa succede se voglio usare javascript? Non ci sono input standard in esso. Posso usare prompt()?
nicael,

@nicael OP menziona l'uso di un argomento stringa, quindi per il mio esempio JS ho appena creato una funzione che accetta un argomento e ho assunto che argomento fosse la stringa di parole simile a STDIN
Eric Lagergren,

1
Mi chiedo se esolang sia chiamato "[la tua lingua qui]"
Akangka il

Risposte:


4

JavaScript: 653 611 547 514 487 byte

Oh mio Dio. Brendan Eich, mi dispiace tanto per questo.

PS: ho aggiunto uno spazio bianco per la leggibilità, ma eliminando tutti gli spazi bianchi consentiti si ottiene il conteggio dei byte elencati.

Teoricamente potrei accorciare alcune parti come la -e-a qualcosa di simile -eo -e, ma ciò potrebbe causare un problema se la parola precedente termina, o la parola successiva inizia con la lettera 'e' (o qualunque parola io decida di usare). Suppongo che potrei usare un carattere ASCII. Lo esaminerò.

Solo 487 FF22 +

R = "replace", C = "charAt", U = "toUpperCase";
alert(a[R](/\^((COMMA)|(SEMICOLON)|(COLON)|(PERIOD)|(BANG)|(DASH)|(HYPHEN)|(EMDASH)|(OPENQUOTE)|(CLOSEQUOTE))/g, ((m, _, a, b, c, d, e, f, g, h, i, j) => a ? "," : b ? ";" : c ? ":" : d ? "." : e ? "!" : f ? "-" : g ? "-h-" : h ? "-e-" : i ? ' "' : '" '))[R](/\s((\.)|(\!)|(\,)|(\;)|(\:)|(\-\h\-\s)|(\-\e\-\s))/g, ((k, l, v, n, o, p, q, r, s) => v ? "." : n ? "!" : o ? "," : p ? ";" : q ? ":" : r ? "-" : "--"))[R](/[^!,"'.]\"\s/g, '"')[R](/.+?[\.\?\!](\s|$)/g, (t => t[C](0)[U]() + t.substr(1)))[R](/\"[a-z]/g, (u => u[C](0) + u[C](1)[U]())))

Solo 514 FF22

alert(function(z) {
    R = "replace", C = "charAt", U = "toUpperCase";
    return z[R](/\^((COMMA)|(SEMICOLON)|(COLON)|(PERIOD)|(BANG)|(DASH)|(HYPHEN)|(EMDASH)|(OPENQUOTE)|(CLOSEQUOTE))/g, ((m, _, a, b, c, d, e, f, g, h, i, j) => a ? "," : b ? ";" : c ? ":" : d ? "." : e ? "!" : f ? "-" : g ? "-h-" : h ? "-e-" : i ? ' "' : '" '))[R](/\s+((\.)|(\!)|(\,)|(\;)|(\:)|(\-\h\-\s+)|(\-\e\-\s+))/g, ((k, l, v, n, o, p, q, r, s) => v ? "." : n ? "!" : o ? "," : p ? ";" : q ? ":" : r ? "-" : "--"))[R](/[^!,"'.]\"\s/g, '"')[R](/.+?[\.\?\!](\s+|$)/g, (t => t[C](0)[U]() + t.substr(1)))[R](/\"[a-z]/g, (u => u[C](0) + u[C](1)[U]()))
}(a))

547 FF22 + Solo

alert(function(z) {
    R = "replace", C = "charAt", U = "toUpperCase";
    return z[R](/\^((COMMA)|(SEMICOLON)|(COLON)|(PERIOD)|(BANG)|(DASH)|(HYPHEN)|(EMDASH)|(OPENQUOTE)|(CLOSEQUOTE))/g, ((m, _, a, b, c, d, e, f, g, h, i, j) => a ? "," : b ? ";" : c ? ":" : d ? "." : e ? "!" : f ? "-" : g ? "-h-" : h ? "-e-" : i ? ' "' : '" '))[R](/\s+((\.)|(\!)|(\,)|(\;)|(\:)|(\-\h\-\s+)|(\-\e\-\s+))/g, ((xx, __, k, l, m, n, o, p, q) => k ? "." : l ? "!" : m ? "," : n ? ";" : o ? ":" : p ? "-" : "--"))[R](/[^!,"'.]\"\s/g, '"')[R](/.+?[\.\?\!](\s+|$)/g, function(r) {
        return r[C](0)[U]() + r.substr(1)
    })[R](/\"[a-z]/g, function(s) {
        return s[C](0) + s[C](1)[U]()
    })
}(a))

Solo 611 FF 22+

alert(function(c) {
    return c.replace(/\^((COMMA)|(SEMICOLON)|(COLON)|(PERIOD)|(BANG)|(DASH)|(HYPHEN)|(EMDASH)|(OPENQUOTE)|(CLOSEQUOTE))/g, ((x, _, a, b, c, d, e, f, g, h, i) = > a ? "," : b ? ";" : c ? ":" : d ? "." : e ? "!" : f ? "-" : g ? "-h-" : h ? "-e-" : i ? ' "' : '" ')).replace(/\s+\./g, ".").replace(/\s+\!/g, "!").replace(/\s+\,/g, ",").replace(/\s+\;/g, ";").replace(/\s+\:/g, ":").replace(/\s\-\h\-\s/g, "-").replace(/[^!,"'.]\"\s/g, '"').replace(/\s+\-\e-\s+/g, "--").replace(/.+?[\.\?\!](\s+|$)/g, function(b) {
        return b.charAt(0).toUpperCase() + b.substr(1)
    }).replace(/\"[a-z]/g, function(b) {
        return b.charAt(0) + b.charAt(1).toUpperCase()
    })
}(a))

653 cross-browser

alert(function(c) {
    return c.replace(/\^COMMA/g, ",").replace(/\^SEMICOLON/g, ";").replace(/\^COLON/g, ":").replace(/\^PERIOD/g, ".").replace(/\^BANG/g, "!").replace(/\^DASH/g, "-").replace(/\^HYPHEN/g, "h-h").replace(/\^EMDASH/g, "-e-").replace(/\^OPENQUOTE/g, ' "').replace(/\^CLOSEQUOTE/g, '" ').replace(/\s+\./g, ".").replace(/\s+\!/g, "!").replace(/\s+\,/g, ",").replace(/\s+\;/g, ";").replace(/\s+\:/g, ":").replace(/\s\h\-\h\s/g, "-").replace(/[^!,"'.]\"\s/g, '"').replace(/\s+\-\e-\s+/g, "--").replace(/.+?[\.\?\!](\s|$)/g, function(b) {
        return b.charAt(0).toUpperCase() + b.substr(1)
    }).replace(/\"[a-z]/g, function(b) {
        return b.charAt(0) + b.charAt(1).toUpperCase()
    })
}(a))

Come funziona:

https://gist.github.com/ericlagergren/1a61b5d772ae49ab3aea

JSFiddle (per la soluzione cross-browser a 653 byte)

JSFiddle (per il 595 FF 22+ unica soluzione)

JSFiddle (per il 547 FF 22+ unica soluzione)

JSFiddle (per il 514 FF 22+ unica soluzione)

JSFiddle (per il 487 FF 22+ unica soluzione)

Questa è la prima volta che ho dovuto scrivere JS che utilizza più di una regex e di solito la mia regex è predefinita.

Continuerò a radere più byte che posso.


Puoi abbreviare i tuoi primi sostituti in questo modo: c.replace(/\^((COMMA)|(SEMICOLON)|(COLON)|(PERIOD)|(BANG))/g,(m,_,a,b,c,d,e)=>a?',':b?';':c?':':d?'.':'!'))... e così via. La sintassi della freccia è breve, ma anche la 'funzione' dovrebbe salvare gli stessi caratteri
edc65

Hai ragione. Ho testato il mio regexp con Chrome e non supporta le frecce grasse. Sto lavorando per chiarire le cose con FF in questo momento, ma odio come regexps non abbia realmente un "e" operatore come fanno un "o". @ edc65
Eric Lagergren,

@ edc65 quindi immagino che dovrò usare due =>s per farlo funzionare, ma usando le frecce mi ha salvato 40 byte!
Eric Lagergren,

Sostituisci sostituisci con R = 'sostituisci' ... [R] ;-)
edc65,

L'ho appena fatto :) Sono arrivato a 563 @ edc65
Eric Lagergren il

1

PHP, 412 byte

(Ungolf qui per chiarezza; vedi ideone per la versione golf .)

La funzione preg_replace () di PHP accetterà argomenti di array, il che è piuttosto utile qui. Penso che il seguente codice faccia tutto ciò che è richiesto. Passa almeno tutti i casi di test.

function x($s) {
    $r='preg_replace';
    $s=$r('/ +/',' ',$s);
    $s=$r(array('/ \^COMMA/','/ \^COLON/','/ \^SEMICOLON/','/ \^PERIOD/','/ \^BANG/',
                '/\^DASH/','/ \^HYPHEN /','/ \^EMDASH /','/\^OPENQUOTE /','/ \^CLOSEQUOTE/'),
          array(',',':',';','.','!','-','-','--','"',',"'),
          $s);
    $s=$r('/(^\W*\w|([\.!]| ")\W+\w)/e','strtoupper("$0")',$s);
    $s=$r('/([,\.!]),/','\1',$s);
    $s=$r('/(\w)( "\w)/e','"$1,".strtoupper("$2")',$s);
    echo $s;
}

Funziona perfettamente! ideone.com/AYtTiI Anche se ciò di cui sono confuso è che dovremmo avere delle virgole prima delle virgolette? Perché, dal punto di vista grammaticale, le virgolette vanno oltre il parlato, ma solo il parlato ha la virgola prima delle virgolette. Supponevo che, dato che c'era un ^ COMMA, avremmo lasciato che l'utente inserisse la virgola
Eric Lagergren,
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.