Terapkan aturan tanda baca bahasa Inggris

11

Anda telah disewa untuk menulis beberapa kode untuk aplikasi pengambilan dikte, yang mengambil input suara dari sumber yang diucapkan, mem-parsingnya sebagai kata-kata, dan menuliskannya di layar.

Manajemen tidak benar-benar mempercayai Anda dengan semua kekuatan yang ada di proyek ini — Anda dikenal hanya duduk-duduk dan bermain golf sepanjang hari alih-alih melakukan pekerjaan Anda, sayangnya — jadi mereka hanya memberi Anda tugas yang sangat sederhana untuk dilakukan: putar Kalimat dengan Tanda baca diselingi menjadi kalimat yang diformat dengan benar, di mana 'diformat dengan benar' didefinisikan di bawah ini.

  1. Kalimat adalah serangkaian input. A Word adalah sekelompok karakter non-spasi yang bisa menular. Tanda baca adalah kata yang karakter pertamanya adalah ^.

  2. Sebuah huruf besar ditulis dengan huruf besar jika huruf pertama dari kata tersebut bukan huruf kecil (kata dengan huruf besar cocok dengan regex /[^a-z].*/).

  3. Kata pertama dari Kalimat harus ditulis dengan huruf besar.

  4. A ^COMMAadalah karakter koma ,dan memiliki spasi berikut tetapi tidak sebelumnya. aaa ^COMMA bbbmenjadi aaa, bbb.

  5. A ^COLONadalah tanda koma :.

  6. A ^SEMICOLONadalah tanda koma ;.

  7. A ^PERIODadalah tanda koma .. Kata berikut a ^PERIODharus ditulis dengan huruf besar .

  8. A ^BANGadalah periode yang terlihat seperti !.

  9. A ^DASHadalah karakter tanda hubung -dan memiliki spasi sebelum dan sesudahnya.

  10. A ^HYPHENjuga karakter dasbor -tetapi tidak memiliki spasi mengikuti atau mendahului.

  11. An ^EMDASHadalah tanda hubung (bukan tanda hubung!) Yang dieja --.

  12. An ^OPENQUOTEadalah karakter kutipan "yang memiliki ruang mendahului tetapi tidak mengikuti. Kata berikut ^OPENQUOTEharus ditulis dengan huruf besar . Jika suatu ^OPENQUOTEdidahului oleh kata yang bukan tanda baca, tambahkan a ^COMMAantara kata itu dan ^OPENQUOTE. Jika a ^OPENQUOTEdidahului oleh Tanda Baca yang membuat kata berikutnya menjadi kapital, ini melompati ^OPENQUOTEke kata berikutnya.

  13. A ^CLOSEQUOTEadalah digraf ,"yang memiliki spasi mengikuti tetapi tidak mendahului. Jika ^CLOSEQUOTEdidahului oleh ^COMMA, ^PERIODatau ^BANG, bahwa Tanda Baca menghilang dan ^CLOSEQUOTEdieja ,", ."atau !"masing-masing. Jika Tanda baca yang hilang menentukan huruf besar, huruf besar itu masih harus muncul pada kata berikutnya yang tersedia.

  14. Ruang awal atau akhir dalam hasil akhir penuh harus dihilangkan, dan string apa pun dari dua ruang atau lebih dalam satu baris harus diciutkan menjadi karakter spasi tunggal.

  15. Kasus apa pun yang tidak dicakup di atas (misalnya ^COMMA ^COMMAatau ^SEMICOLON ^CLOSEQUOTEatau ^UNDEFINEDPUNCTUATION) tidak akan terjadi pada input yang terbentuk dengan baik dan dengan demikian perilaku tidak terdefinisi.

Tim pengembangan memberi tahu Anda tentang hal-hal berikut:

  • Proyek ini sedang ditulis dalam bahasa [ bahasa Anda di sini] , dan harus sesingkat mungkin sehingga membutuhkan ruang sesedikit mungkin ketika itu merupakan aplikasi untuk Android / iPhone. Anda mencoba menjelaskan bahwa itu bukan cara kerja pengembangan aplikasi, tetapi mereka tidak mendengarkan. Tapi hei, kebetulan sekali! Anda adalah pegolf luar biasa dalam [bahasa Anda di sini] !

  • Aplikasi tidak akan memiliki izin akses web apa pun, dan tidak akan ada pustaka yang diinstal yang melakukan pemformatan ini untuk Anda. Anda mungkin dapat meyakinkan pimpinan tim untuk mengizinkan Anda perpustakaan regex jika ada untuk bahasa Anda, jika Anda merasa perlu.

  • Dukungan untuk kutipan bersarang yang menggunakan tanda kutip ganda / tunggal dengan benar direncanakan untuk versi aplikasi yang lebih baru, tetapi bukan versi yang sedang Anda kerjakan sekarang, jadi jangan khawatir.

  • Manajemen adalah penggemar berat pengembangan yang digerakkan oleh pengujian, dan tim pengembang telah membuat beberapa keyboard monyet yang malang menulis beberapa tes untuk bagian program Anda: (baris baru ditambahkan agar mudah dibaca, perlakukan sebagai ruang)

    Memasukkan:

    hello ^COMMA   world ^BANG
    

    Keluaran:

    Hello, world!
    

    Memasukkan:

    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
    

    Keluaran:

    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
    

    Memasukkan:

    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
    

    Keluaran:

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

Ini adalah kode golf: skor terendah menang. Anda dapat menulis fungsi dari satu argumen string, atau program membaca dari STDIN dan menulis ke STDOUT.

algoritme hiu
sumber
Bagaimana jika saya ingin menggunakan javascript? Tidak ada input standar di dalamnya. Bisakah saya menggunakan prompt()?
nicael
@nicael OP menyebutkan menggunakan satu argumen string, jadi untuk contoh JS saya, saya hanya membuat fungsi yang mengambil satu argumen dan mengasumsikan argumen itu adalah string kata yang mirip dengan STDIN
Eric Lagergren
1
Saya ingin tahu apakah ada esolang bernama "[bahasa Anda di sini]"
Akangka

Jawaban:

4

JavaScript: 653 611 547 514 487 byte

Ya ampun. Brendan Eich Saya sangat menyesal untuk ini.

PS: Saya telah menambahkan spasi putih untuk keterbacaan, tetapi menghapus semua ruang putih yang diijinkan menghasilkan jumlah byte yang terdaftar.

Secara teoritis saya dapat mempersingkat beberapa bagian seperti -e-ke sesuatu seperti -eatau -e, tetapi itu dapat menyebabkan masalah jika kata sebelumnya berakhir dengan, atau kata berikut dimulai dengan huruf 'e' (atau kata mana yang saya putuskan untuk digunakan). Saya kira saya bisa menggunakan karakter ASCII. Saya akan melihat itu.

487 FF22 + Hanya

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

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

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

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

Bagaimana itu bekerja:

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

JSFiddle (untuk solusi lintas-browser 653 byte)

JSFiddle (untuk solusi 595 FF 22+ saja )

JSFiddle (untuk solusi 547 FF 22+ saja )

JSFiddle (untuk solusi 514 FF 22+ saja )

JSFiddle (untuk solusi 487 FF 22+ saja )

Ini adalah pertama kalinya saya harus menulis JS yang menggunakan lebih dari satu regex, dan biasanya regex saya sudah ditentukan sebelumnya.

Saya akan terus memotong byte sebanyak yang saya bisa.

Eric Lagergren
sumber
Anda dapat mempersingkat penggantian pertama Anda seperti ini: c.replace(/\^((COMMA)|(SEMICOLON)|(COLON)|(PERIOD)|(BANG))/g,(m,_,a,b,c,d,e)=>a?',':b?';':c?':':d?'.':'!'))... dan seterusnya. Sintaks panah pendek, tetapi bahkan 'fungsi' harus menyimpan karakter yang sama
edc65
Kamu benar. Saya menguji regexp saya dengan Chrome, dan itu tidak mendukung panah gemuk. Saya sedang berusaha menyelesaikannya dengan FF sekarang, tapi saya benci bagaimana regexps tidak benar-benar memiliki operator "dan" seperti mereka melakukan "atau". @ edc65
Eric Lagergren
@ edc65 jadi saya pikir saya harus menggunakan dua =>s untuk membuatnya bekerja, tetapi menggunakan panah menyelamatkan saya 40 byte!
Eric Lagergren
Ganti ganti dengan R = 'ganti' ... [R] ;-)
edc65
Baru saja melakukan itu :) Mendapatnya ke 563 @ edc65
Eric Lagergren
1

PHP, 412 byte

(Tidak disatukan di sini untuk kejelasan; lihat ideone untuk versi golf .)

Fungsi preg_replace () PHP akan menerima argumen array, yang cukup berguna di sini. Saya pikir kode berikut melakukan semua yang diperlukan. Setidaknya melewati semua kasus uji.

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
sumber
Bekerja dengan sempurna! ideone.com/AYtTiI Meskipun yang saya bingung adalah apakah kita seharusnya memiliki koma sebelum kutipan terbuka? Karena, secara tata bahasa, tanda kutip lebih dari ucapan, namun hanya ucapan yang koma sebelum tanda kutip. Saya berasumsi karena ada ^ COMMA kita akan membiarkan pengguna memasukkan koma
Eric Lagergren