Appliquer les règles de ponctuation en anglais

11

Vous avez été embauché pour écrire du code pour une application de prise de dictée, qui prend les entrées vocales d'une source parlée, les analyse comme des mots et les écrit sur un écran.

La direction ne vous fait pas vraiment confiance avec autant de puissance dans le projet - vous êtes connu pour vous asseoir et jouer au golf toute la journée au lieu de faire votre travail, malheureusement - alors ils vous donnent juste une tâche très simple à effectuer: tourner un Phrase avec ponctuation entrecoupée en une phrase correctement formatée, où «correctement formaté» est défini ci-dessous.

  1. La phrase est la chaîne d'entrée. Un mot est un groupe de caractères non spatiaux contingents. Une ponctuation est un mot dont le premier caractère est ^.

  2. Un mot est mis en majuscule si la première lettre du mot n'est pas une lettre minuscule (les mots en majuscule correspondent à l'expression régulière /[^a-z].*/).

  3. Le premier mot de la phrase doit être en majuscule.

  4. A ^COMMAest le caractère virgule ,et possède un espace suivant mais non précédant. aaa ^COMMA bbbdevient aaa, bbb.

  5. A ^COLONest une virgule qui ressemble :.

  6. A ^SEMICOLONest une virgule qui ressemble ;.

  7. A ^PERIODest une virgule qui ressemble .. Le mot suivant a ^PERIODdoit être en majuscule.

  8. A ^BANGest une période qui ressemble !.

  9. A ^DASHest le tiret -et a un espace à la fois avant et après.

  10. A ^HYPHENest également le caractère de tiret -mais n'a aucun espace suivant ou précédent.

  11. An ^EMDASHest un trait d'union (pas un tiret!) Qui est orthographié --.

  12. An ^OPENQUOTEest un caractère de citation "qui a un espace précédant mais non suivant. Le mot suivant un ^OPENQUOTEdoit être en majuscule. Si un ^OPENQUOTEest précédé d'un mot qui n'est pas un signe de ponctuation, ajoutez un ^COMMAentre ce mot et le ^OPENQUOTE. Si an ^OPENQUOTEest précédé d'une ponctuation qui met le mot suivant en majuscule, cela passe au ^OPENQUOTEmot suivant.

  13. A ^CLOSEQUOTEest le digraphe ,"qui a un espace suivant mais non précédant. Si un ^CLOSEQUOTEest précédée par un ^COMMA, ^PERIODou ^BANGque Ponctuation disparaît et ^CLOSEQUOTEest orthographié ,", ."ou !"respectivement. Si la ponctuation disparue spécifiait une capitalisation, cette capitalisation doit toujours se produire sur le mot disponible suivant.

  14. Les espaces initiaux ou de fin dans le résultat final complet doivent être supprimés et toute chaîne de deux espaces ou plus dans une ligne doit être entièrement réduite en un seul caractère d'espace.

  15. Tout cas non couvert ci-dessus (par exemple ^COMMA ^COMMAou ^SEMICOLON ^CLOSEQUOTEou ^UNDEFINEDPUNCTUATION) ne se produira pas dans une entrée bien formée et est donc un comportement indéfini.

L'équipe de développement vous informe des éléments suivants:

  • Le projet est écrit dans la langue [votre langue ici] et doit être aussi court que possible afin qu'il prenne le moins de place possible lorsqu'il s'agit d'une application pour Android / iPhone. Vous essayez d'expliquer que ce n'est pas ainsi que fonctionne le développement d'applications, mais ils n'écoutent pas. Mais bon, quelle coïncidence! Vous êtes un golfeur incroyable dans [votre langue ici] !

  • L'application ne disposera d'aucune autorisation d'accès Web et aucune bibliothèque installée n'effectuera cette mise en forme pour vous. Vous pouvez probablement convaincre le chef d'équipe de vous autoriser une bibliothèque d'expressions régulières s'il en existe une pour votre langue, si vous pensez en avoir besoin.

  • La prise en charge des devis imbriqués qui utilisent correctement les guillemets doubles / simples est prévue pour une version ultérieure de l'application, mais pas la version sur laquelle vous travaillez maintenant, alors ne vous inquiétez pas.

  • La gestion est un grand fan du développement piloté par les tests, et donc l'équipe de développement a déjà eu un malheureux singe clavier pour écrire des tests pour votre partie du programme: (nouvelles lignes ajoutées pour plus de lisibilité, les traiter comme des espaces)

    Contribution:

    hello ^COMMA   world ^BANG
    

    Production:

    Hello, world!
    

    Contribution:

    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
    

    Production:

    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
    

    Contribution:

    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
    

    Production:

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

C'est un golf de code: le score le plus bas l'emporte. Vous pouvez écrire une fonction d'un argument de chaîne ou un programme lisant à partir de STDIN et écrivant à STDOUT.

algorithmshark
la source
Et si je veux utiliser javascript? Il n'y a pas d'entrée standard. Puis-je utiliser prompt()?
nicael
@nicael OP mentionne l'utilisation d'un argument de chaîne, donc pour mon exemple JS, je viens de créer une fonction qui prend un argument et j'ai supposé que l'argument était la chaîne de mots similaire à STDIN
Eric Lagergren
1
Je me demande s'il y a un esolang nommé "[votre langue ici]"
Akangka

Réponses:

4

JavaScript: 653 611 547 514 487 octets

Oh mon Dieu. Brendan Eich Je suis vraiment désolé pour ça.

PS: J'ai ajouté un espace blanc pour la lisibilité, mais supprimer tous les espaces blancs autorisés entraîne le nombre d'octets répertorié.

Théoriquement, je pourrais raccourcir certaines parties comme le -e-à quelque chose comme -eou -e, mais cela pourrait causer un problème si le mot précédent se termine par, ou si le mot suivant commence par la lettre `` e '' (ou le mot que je décide d'utiliser). Je suppose que je pourrais utiliser un caractère ASCII. J'examinerai cela.

487 FF22 + seulement

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]())))

514 FF22 + seulement

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 + seulement

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))

611 FF 22+ uniquement

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))

Comment ça fonctionne:

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

JSFiddle (pour la solution multi-navigateur de 653 octets)

JSFiddle (pour la solution 595 FF 22+ uniquement )

JSFiddle (pour la solution 547 FF 22+ uniquement )

JSFiddle (pour la solution 514 FF 22+ uniquement )

JSFiddle (pour la solution 487 FF 22+ uniquement )

C'est la première fois que je dois écrire JS qui utilise plus d'une expression régulière, et généralement mon expression régulière est prédéfinie.

Je continuerai à raser autant d'octets que possible.

Eric Lagergren
la source
Vous pouvez raccourcir vos premiers remplacements comme ceci: c.replace(/\^((COMMA)|(SEMICOLON)|(COLON)|(PERIOD)|(BANG))/g,(m,_,a,b,c,d,e)=>a?',':b?';':c?':':d?'.':'!'))... et ainsi de suite. La flèche sintax est courte, mais même la «fonction» devrait enregistrer les mêmes caractères
edc65
Vous avez raison. J'ai testé mon expression rationnelle avec Chrome et il ne prend pas en charge les grosses flèches. Je travaille à ce que tout soit réglé avec FF en ce moment, mais je déteste que les regexps n'aient pas vraiment d'opérateur "et" comme ils font un "ou". @ edc65
Eric Lagergren
@ edc65 donc je pense que je vais devoir utiliser deux =>s pour le faire fonctionner, mais en utilisant les flèches, j'ai économisé 40 octets!
Eric Lagergren
Remplacer remplacer par R = 'remplacer' ... [R] ;-)
edc65
Je viens de le faire :) 563 @ edc65
Eric Lagergren
1

PHP, 412 octets

(Non golfé ici pour plus de clarté; voir l'idéone pour la version golfée .)

La fonction preg_replace () de PHP acceptera les arguments de tableau, ce qui est plutôt utile ici. Je pense que le code suivant fait tout ce qui est requis. Il passe au moins tous les cas de 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;
}
r3mainer
la source
Marche parfaitement! ideone.com/AYtTiI Bien que ce qui me dérange, c'est que sommes-nous censés avoir des virgules avant les guillemets ouverts? Parce que, grammaticalement, les guillemets valent plus que la parole, mais seule la parole a la virgule avant les guillemets. J'ai supposé qu'il y avait un ^ COMMA nous laisserions l'utilisateur entrer la virgule
Eric Lagergren