Aplicar regras de pontuação em inglês


11

Você foi contratado para escrever um código para um aplicativo que utiliza ditados, que recebe a entrada de voz de uma fonte falada, a analisa como palavras e a anota na tela.

A gerência realmente não confia em você com tanta força no projeto - você sabe que fica sentado e codifica golfe o dia todo, em vez de fazer seu trabalho, infelizmente - então eles apenas oferecem uma tarefa realmente simples de executar: Frase com Pontuação intercalada em uma frase formatada corretamente, onde 'formatado corretamente' é definido abaixo.

  1. A frase é a sequência de entrada. Uma palavra é um grupo de caracteres não-espaço contíguos. Uma pontuação é uma palavra cujo primeiro caractere é ^.

  2. Uma palavra é maiúscula se a primeira letra da palavra não for minúscula (as palavras maiúsculas correspondem à regex /[^a-z].*/).

  3. A primeira palavra da sentença deve ser maiúscula.

  4. A ^COMMAé o caractere de vírgula ,e tem um espaço a seguir, mas não precedendo. aaa ^COMMA bbbtorna-se aaa, bbb.

  5. A ^COLONé uma vírgula que se parece :.

  6. A ^SEMICOLONé uma vírgula que se parece ;.

  7. A ^PERIODé uma vírgula que se parece .. A palavra após a ^PERIODdeve ser maiúscula.

  8. A ^BANGé um período que parece !.

  9. A ^DASHé o caractere de traço -e tem um espaço anterior e seguinte.

  10. A ^HYPHENtambém é o caractere de hífen, -mas não possui espaço a seguir ou anterior.

  11. An ^EMDASHé um hífen (não um traço!) Que está escrito --.

  12. An ^OPENQUOTEé um caractere de citação "que possui um espaço anterior, mas não segue. A palavra após um ^OPENQUOTEdeve ser maiúscula. Se um ^OPENQUOTEfor precedido por uma palavra que não seja pontuação, adicione um ^COMMAentre essa palavra e o ^OPENQUOTE. Se um ^OPENQUOTEfor precedido por uma Pontuação que coloque a próxima palavra em maiúscula, ela passará ^OPENQUOTEpara a próxima palavra.

  13. A ^CLOSEQUOTEé o dígrafo ,"que possui um espaço a seguir, mas não precedendo. Se um ^CLOSEQUOTEé precedida por um ^COMMA, ^PERIODou ^BANG, que a pontuação desaparece eo ^CLOSEQUOTEestá escrito ,", ."ou !", respectivamente. Se a Pontuação que desapareceu especificou uma capitalização, essa capitalização ainda deve ocorrer na próxima palavra disponível.

  14. Os espaços iniciais ou finais no resultado final completo devem ser removidos e qualquer sequência de dois ou mais espaços em uma linha deve ser recolhida em um único caractere de espaço.

  15. Qualquer caso não coberto acima (por exemplo, ^COMMA ^COMMAou ^SEMICOLON ^CLOSEQUOTEou ^UNDEFINEDPUNCTUATION) não ocorrerá em dados bem formados e, portanto, é um comportamento indefinido.

A equipe de desenvolvimento informa o seguinte:

  • O projeto está sendo escrito no idioma [seu idioma aqui] e deve ser o mais curto possível, para que ocupe o mínimo de espaço possível quando for um aplicativo para Android / iPhone. Você tenta explicar que não é assim que o desenvolvimento de aplicativos funciona, mas eles não ouvem. Mas ei, que coincidência! Você é um jogador incrível no [seu idioma aqui] !

  • O aplicativo não terá permissões de acesso à Web e não haverá bibliotecas instaladas que façam essa formatação para você. Provavelmente, você pode convencer o líder da equipe a permitir uma biblioteca de expressões regulares, se houver alguma para o seu idioma, se achar que precisa de uma.

  • O suporte para cotações aninhadas que usam aspas duplas / simples corretamente está planejado para uma versão posterior do aplicativo, mas não para a versão em que você está trabalhando agora, portanto, não se preocupe.

  • O gerenciamento é um grande fã do desenvolvimento orientado a testes e, portanto, a equipe de desenvolvedores já solicitou que um macaco de teclado infeliz escrevesse alguns testes para sua parte do programa: (novas linhas adicionadas para facilitar a leitura, trate-as como espaços)

    Entrada:

    hello ^COMMA   world ^BANG
    

    Resultado:

    Hello, world!
    

    Entrada:

    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
    

    Resultado:

    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
    

    Entrada:

    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
    

    Resultado:

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

Este é um código de golfe: a pontuação mais baixa vence. Você pode escrever uma função de um argumento de seqüência de caracteres ou um programa lendo STDIN e gravando em STDOUT.


E se eu quiser usar javascript? Não há entrada padrão nele. Posso usar prompt()?
Nicael 23/06

@nicael OP menciona usando argumento de cadeia de um, por isso para o meu exemplo JS Eu só fiz uma função que leva um argumento e assumiu que o argumento era a seqüência de palavras semelhante ao STDIN
Eric Lagergren

1
Pergunto-me se não é esolang com o nome "[seu idioma aqui]"
Akangka

Respostas:


4

JavaScript: 653611547514487 bytes

Oh meu Deus. Brendan Eich Sinto muito por isso.

PS: Adicionei espaço em branco para facilitar a leitura, mas eliminando todos os resultados de espaço em branco permitidos na contagem de bytes listados.

Teoricamente, eu poderia encurtar algumas partes como a -e-para algo como -eou -e, mas isso pode causar um problema se a palavra anterior terminar com, ou a palavra seguinte começar com a letra 'e' (ou a palavra que eu decidir usar). Suponho que eu poderia usar um caractere ASCII. Eu vou investigar isso.

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

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

Apenas 547 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, ((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))

Apenas 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 entre navegadores

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

Como funciona:

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

JSFiddle (para a solução de navegador cruzado de 653 bytes)

JsFiddle (para o 595 FF 22+ única solução)

JsFiddle (para o 547 FF 22+ única solução)

JsFiddle (para o 514 FF 22+ única solução)

JsFiddle (para o 487 FF 22+ única solução)

É a primeira vez que escrevo JS que usa mais de um regex e, geralmente, meu regex é predefinido.

Continuarei a cortar os bytes o máximo que puder.


Você pode encurtar suas primeiras substituições assim: c.replace(/\^((COMMA)|(SEMICOLON)|(COLON)|(PERIOD)|(BANG))/g,(m,_,a,b,c,d,e)=>a?',':b?';':c?':':d?'.':'!'))... e assim por diante. Arrow sintaxe é curto, mas 'função' ainda deve salvar mesmos caracteres
edc65

Você está certo. Testei meu regexp com o Chrome e ele não suporta flechas grossas. Estou trabalhando para corrigi-lo com o FF agora, mas odeio como os regexps realmente não têm um operador "e" como fazem um "ou". @ edc65
Eric Lagergren

@ edc65 então acho que vou ter que usar dois =>s para fazê-lo funcionar, mas usar as setas me salvou 40 bytes!
Eric Lagergren

Substitua replace por R = 'replace' ... [R] ;-)
edc65

Acabei de fazer isso :) Chegou a 563 @ edc65 #
Eric Lagergren

1

PHP, 412 bytes

(Aqui não é para ser jogado para maior clareza; veja ideone para a versão em golfe ).

A função preg_replace () do PHP aceitará argumentos de matriz, o que é bastante útil aqui. Eu acho que o código a seguir faz tudo o que é necessário. Ele passa em todos os casos de teste pelo menos.

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;
}

Funciona perfeitamente! ideone.com/AYtTiI Embora o que eu estou confuso é que devemos ter vírgulas antes das aspas abertas? Como, gramaticalmente, as aspas são mais do que discurso, mas apenas o discurso tem vírgula antes das aspas. Eu assumi, desde que houve ^ VÍRGULA estaríamos deixando a entrada do usuário a vírgula
Eric Lagergren
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.