Perbaiki kata-kataku yang tergagap

12

Gagap adalah masalah yang banyak dari kita mungkin pernah mengalami atau setidaknya melihatnya. Meskipun sebagian besar perangkat lunak pengenalan suara yang terkenal memiliki masalah serius dengan gagap berbicara, mari kita bayangkan sebuah perangkat lunak yang mengerti gagap, tetapi tidak dapat memperbaikinya dan hanya menulis apa adanya.

Contoh teks tertulis oleh perangkat lunak seperti itu bisa seperti ini: "harap berhati-hati" . Dalam contoh ini "hati-hati" adalah kata aslinya dan "ca ca" adalah kata-kata yang gagap.

Tantangan

Tulis program atau fungsi yang memperbaiki kata-kata yang tergagap dengan menghapusnya dari input sambil mempertahankan kata-kata aslinya. Misalnya versi tetap dari "harap berhati-hati" akan "harap berhati-hati" .

Ini adalah , jawaban terpendek dalam setiap bahasa menang!

Apa kata yang tergagap?

Gagap memiliki banyak variasi berbeda. Tetapi untuk menyederhanakan tantangan ini, kami akan membatasinya pada aturan berikut:

  • Kata-kata yang tergagap bisa menjadi bagian yang tidak lengkap atau keseluruhan dari kata aslinya. Dengan "bagian yang belum selesai" yang saya maksudkan adalah bahwa kata aslinya harus dimulai tepat dengan kata yang gagap. Misalnya "ope" dan "terbuka" keduanya bisa menjadi kata yang gagap untuk "terbuka" , tetapi "pena" tidak dapat menjadi satu karena "terbuka" tidak dimulai dengan "pena" .
  • Kata-kata yang gagap harus mengandung setidaknya satu dari vokal "aeiou" . Misalnya "bintang" bisa menjadi kata yang gagap untuk "mulai" karena mengandung "a" , tetapi "st" tidak bisa menjadi kata yang gagap karena tidak mengandung salah satu vokal yang disebutkan.
  • Kata-kata yang tergagap hanya dapat muncul sebelum kata aslinya dan harus diulang setidaknya dua kali agar valid (kata aslinya tidak dihitung dalam pengulangan). Misalnya "oo open" memiliki kata-kata yang gagap tetapi "o open o" tidak, karena "o" setelah kata aslinya tidak dihitung dan "o" sebelum kata aslinya tidak diulang setidaknya dua kali. "go go go go go" memiliki lima pengulangan kata yang gagap sebelum kata aslinya dan valid.
  • Satu set kata-kata gagap yang diulang tidak dapat mengandung bentuk campuran dan kata-kata tersebut harus persis seperti satu sama lain. Misalnya "op o op open" tidak dihitung sebagai kata yang gagap. Di sisi lain "o op op open" memiliki kata-kata yang gagap karena "o" yang pertama dilihat sebagai kata yang sama sekali berbeda di sini dan dua "op" dihitung sebagai kata-kata "open" yang tergagap .
  • Seandainya beberapa set kata-kata gagap yang diulang berulang setelah satu sama lain, hanya kata asli terakhir yang tetap. Misalnya, dalam "ooo op op op open" , bagian "oo o" dipandang sebagai kata-kata yang tergagap pada "op" pertama , sehingga kata-kata itu harus dihapus dan kemudian "op op op" dilihat sebagai kata-kata yang tergagap-gagap dari "buka". " dan mereka harus dihapus juga, jadi hanya " terbuka "yang akan ditinggalkan setelah penghapusan kata-kata yang gagap. Anda dapat berasumsi bahwa beberapa set kata-kata yang gagap diulang hanya berlaku dari kiri ke kanan, jadi memperbaiki "op op ooo open" akan menghasilkan "op op open" (alias

Memasukkan

  • Input adalah string baris tunggal yang hanya mengandung huruf Inggris ASCII (az), digit (0-9) dan karakter spasi. Casing huruf tidak penting dan Anda dapat memutuskan untuk menerima huruf kecil atau besar atau keduanya, tetapi casing harus tetap sama dan Anda tidak dapat mengubahnya di output.
  • Anda dapat menggunakan daftar huruf (seperti ["l","i","s","t"," ","o","f"," ","l","e","t","t","e","r","s"]) daripada string, tetapi Anda tidak dapat menggunakan daftar kata. Jika bahasa Anda memiliki struktur input yang berbeda, gunakan itu. Intinya adalah bahwa input tidak boleh dipisahkan oleh kata-kata, jadi biaya memisahkan kata dalam beberapa bahasa sebenarnya dapat memicu solusi kreatif lainnya.
  • Input mungkin tidak mengandung, satu atau beberapa kata yang tergagap di dalamnya.
  • Kata dan atau angka dipisahkan oleh satu ruang dan input tidak akan berisi ruang ganda tepat di sebelah satu sama lain.

Keluaran

  • String atau daftar huruf atau struktur yang sesuai dalam bahasa Anda dengan semua kata yang tergagap dihapus dari input.
  • Kata-kata keluaran harus dipisahkan dengan tepat satu spasi (sama dengan input).
  • Baris atau spasi baru yang mengarah dan tertinggal tunggal diperbolehkan.

Celah standar dilarang.

Uji kasus

Tidak ada kata yang tergagap:

"hello world" => "hello world"

Satu contoh kata yang gagap diulang:

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

Beberapa contoh kata yang gagap diulang:

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

Tidak ada kata yang gagap, tidak cukup diulang:

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

Tidak ada kata yang tergagap, tidak memiliki vokal yang disebutkan:

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

Angka bukanlah kata yang gagap, mereka tidak memiliki vokal yang disebutkan:

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

Tetapi sebuah kata dengan kedua vokal dan angka dapat memiliki kata-kata tergagap:

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

Berbagai bentuk kata tergagap dalam kelompok yang sama tidak dihitung:

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

Untuk beberapa set kata yang tersumbat secara terus-menerus tepat satu sama lain, simpan saja kata asli terakhir:

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

Ini bukan kasus beberapa set kata-kata tergagap terus menerus satu sama lain:

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

Masukan kosong:

"" => ""

Lebih banyak kasus dari komentar:

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

Mudah untuk menyalin daftar kasus uji di atas:

"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"
Night2
sumber
2
"drink wat wat wa wa water" => "drink wat wat water"sepertinya aturan itu harus diterapkan secara rekursif sehingga ini menjadi "air minum"
Jonah
2
@Jonah jika Anda membaca item terakhir di bawah Apa kata yang tergagap? Saya sudah menjelaskan masalah ini. "wat wat" bukan kata yang gagap untuk "wa" dan kami hanya memperbaiki sekali, jadi setelah kami mendapatkan "minum air wat wat", kami tidak memperbaiki lagi untuk menghapus kata-kata gagap yang baru terbentuk. Tetapi dalam kasus terbalik seperti "wa wa wat wat water" hasilnya adalah "water" karena "wa wa" adalah kata-kata yang tergagap untuk "wat" dan "wat wat" yang pertama juga merupakan kata-kata "air" yang tergagap.
Night2
Ok cukup adil, saya hanya mengatakan itu akan masuk akal untuk terus memperbaiki sampai Anda tidak bisa lagi, tapi saya bisa melihat argumen untuk fokus pada satu iterasi juga.
Jonah

Jawaban:

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

Cobalah online!

Yah, C tentu tidak bisa bersaing dengan singkatnya regex ...

Yang ini sangat sulit dibaca karena saya akhirnya menciutkan seluruh fungsi menjadi sepasang forloop bersarang (tanpa tubuh!). Itu membuat urutan evaluasi semua miring - kode di dekat awal benar-benar dijalankan terakhir.

Trik favorit saya di sini adalah strpbrk(u,"aeiou")-1<s. Ini digunakan untuk memeriksa apakah kata yang diulang mengandung vokal. umenunjuk ke awal kata yang diulang, dan smenunjuk ke pengulangan kata yang kedua; sebagai contoh:

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

strpbrkkemudian temukan karakter pertama "aeiou"yang muncul setelahnya u. (Dalam hal ini, ini adalah 'u'segera setelah itu.) Kemudian kita dapat memeriksa bahwa ini datang sebelum suntuk memverifikasi kata berisi vokal. Tapi ada sedikit masalah - strpbrkmengembalikan NULL(yaitu 0) jika tidak ada vokal di seluruh string. Untuk memperbaiki ini, saya cukup kurangi 1, yang berubah 0menjadi 0xffffffffffffffff(pada mesin saya) karena melimpah. Menjadi nilai maksimum dari sebuah pointer, ini jelas lebih besar daripada s, menyebabkan cek gagal.

Ini versi yang sedikit lebih tua (sebelum transformasi yang membuat aliran kontrol kacau) dengan komentar:

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

Terima kasih kepada @ user1475369 untuk 3 byte dan @ceilingcat untuk 2 byte.

Gagang pintu
sumber
-3 byte dengan mengganti T>1&&strpbrkdengan T>1&strpbrk, r&&!strncmpdengan r&!strncmp, dan &&t[-1]dengan &t[-1].
girobuz
@ceilingcat Tautan Anda gagal dalam beberapa kasus uji, tetapi 2 dari 3 pengoptimalan tersebut berfungsi; Terima kasih!
Gagang Pintu
Sarankan bcmp()alih-alihmemcmp()
ceilingcat
4

Perl 5 (-p), 34 byte

Berdasarkan jawaban yang dihapus Arnauld.

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

Cobalah online!

Grimmy
sumber
Ini menghasilkan "zab" untuk "za a ab". Saya tidak berpikir seharusnya ada gagap terdeteksi dalam input itu.
rekursif
@ terima kasih berulang, diperbaiki.
Grimmy
2
Saya melihat test case dan menyusun regex, hanya untuk menemukannya sudah ada di sini. Secara alami ini berarti bahwa port Retina yang sepele adalah 30 byte.
Neil
3

05AB1E , 30 29 28 byte

-1 byte terima kasih kepada Kevin Cruijssen

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

Cobalah online!

05AB1E, tanpa regex, jelas tidak terlihat sebagai alat terbaik untuk tugas ini. Namun, entah bagaimana itu berhasil mengalahkan 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
Grimmy
sumber
1
Anda dapat menghapus gsebelum Ā. Python-style truthify sudah menghasilkan 0string kosong dan string 1tidak kosong.
Kevin Cruijssen
@KevinCruijssen temukan bagus!
Grimmy
1

Perl 6 , 45 byte

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

Cobalah online!

Sebuah jawaban regex sederhana yang menggantikan semua kecocokan gagap dengan string kosong.

Jo King
sumber
1

Stax , 26 byte

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

Jalankan dan debug itu

Port langsung dari jawaban perl @ Grimy. Stax mampu mengecilkan pola regex literal, dan memiliki konstanta vokal yang mampu menyusut [aeiou].

rekursif
sumber
1

Bersihkan , 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[]=[]

Cobalah online!

Menentukan $ :: [Char] -> [Char], yang membagi string input pada spasi dan mengelompokkan elemen identik yang kemudian diciutkan oleh helper f :: [[[Char]]] -> [[Char]], bergabung sebelum kembali.

Suram
sumber