Penipu di Kebun Binatang

42

Anda ingin membuka kebun binatang baru. Itu akan luar biasa. Tetapi menjadi pelit seperti Anda, Anda hanya ingin membeli hewan tiga huruf (semua orang tahu bahwa biaya hewan sebanding dengan panjang namanya). Itulah impian Anda membuat orang membayar untuk melihat elephant. Tapi tiba-tiba Anda punya ide cemerlang. Jika Anda hanya menempatkan hewan dengan benar di kandang, Anda dapat membuat ilusi optik sebuah elephant! Inilah tampilan top-down dari "kompleks gajah" baru Anda:

elk
  eel
   pig
    hog
     ant

--------  (fence)
    ^
    | viewing direction

Haha, para pengunjung yang mudah tertipu!

Ya, beginilah cara kerja persepsi.

Tantangan

Diberi kata tidak kosong yang hanya terdiri dari huruf-huruf bahasa Inggris huruf kecil, tentukan apakah itu dapat dibentuk dari tumpang tindih dengan 30 kata kata hewan tiga huruf berikut:

ant ape asp ass bat bee boa cat cod cow 
dab dog eel elk emu fly fox gnu hog ide 
jay kea kob koi olm owl pig rat ray yak

Ya, ada lebih dari 30, tapi itu angka bulat yang bagus.

Anda dapat secara opsional menerima daftar ini sebagai input (dalam daftar string atau format string apa pun, asalkan tidak diproses sebelumnya). Anda mungkin ingin melakukan ini, kecuali membaca dan memproses daftar input ini jauh lebih mahal daripada hardcoding dan mengompresnya dalam bahasa pilihan Anda. Perhatikan bahwa bahkan jika Anda mengambil daftar sebagai input, Anda dapat mengasumsikan bahwa itu akan selalu menjadi daftar ini, jadi jika kode Anda bergantung pada daftar yang disahkan yang panjangnya 30 elemen dan tidak mengandung kata z, itu tidak masalah.

Setiap kata dapat digunakan beberapa kali. Hewan tidak dapat dipotong pada ujungnya, hanya sebagian disembunyikan oleh hewan lain. Jadi oxbukan string yang mungkin, meskipun kita punya fox.

Output harus truthy jika hal ini mungkin, dan falsy sebaliknya.

Anda dapat menulis suatu program atau fungsi, mengambil input melalui STDIN (atau alternatif terdekat), argumen baris perintah atau argumen fungsi dan mengeluarkan hasilnya melalui STDOUT (atau alternatif terdekat), nilai pengembalian fungsi atau parameter fungsi (keluar).

Kode Anda harus menangani salah satu kasus uji dalam beberapa detik.

Aturan standar berlaku.

Lebih banyak contoh

  • Kata satu atau dua huruf jelas salah.
  • Begitu juga kata tiga huruf yang tidak ada dalam daftar di atas.
  • Meskipun kami punya gnudan rat, gnatpalsu karena tidak ada cara untuk mengaturnya sehingga Anda hanya melihat dua huruf masing-masing (kami tidak ingin memotong hewan menjadi tiga).

Beberapa contoh kebenaran:

pigment

    ant
  bee
 olm
pig
antioxidant

   fox
 koi  ide
ant     ant

Uji Kasus

Sebagian besar kasus uji diambil dari menjalankan implementasi referensi terhadap kamus. Beberapa "kata" terakhir dihasilkan secara acak dan hanya ada untuk memastikan bahwa pengiriman cukup efisien.

Benar:

ant
owl
bass
pride
bobcat
peafowl
elephant
hedgehogs
crocodile
antidemocrat
aspidoganoidei
biodegradability
angioelephantiasis
propreantepenultimate
acategnukeaidabeleenaspcodcoidyakwakoasshogattkjaypigkobolcodidaskearaywelkwboaxbeeuflapaspoapemaassaaspeewoglmabiemuwjadogacagnuepigjaycownbatjaemuifoxkeaeekekeagratsseeluejdoghogaolmgpigbeaeelemulasphogjaydabemukgnunueifoasdoglrayyadogpewlayroassasslgnuaspyyakkbokeaodxilopgnuasppigkobelratelkolmakob
koigdgaspslycoyakehrdabowbatdkkeapogkobelrowlyarpidepetlfoxeboaiderbeefoxbgnuapeocowgiecowlkoieeltbategspemuideatdogbeeecatgeaoccattbbeassgnasolkeaflyelkaognubeeabrratoccolmobodoglyelraywelkoxantowleedrayflypeappigogatraoyakccpiganaaspkobabjaspkointantybjbeeanolmuijaylratojaynueidflyjarayabatmmpigtfly
eolmantjkobeeaorayogaowldfoxayeassapibatmflylyraelaspsseolmbelkkaoantlmufodasgnueantaidenthyakcodoxuepigodggnuantatlcatnuuelkpemucbapeeoiahdogplkowletbatdrayarayoaelkgrayodcatgkantewkobeljaybeeyfkobtbdabadoghbatfoxtflygaspdeidogtowlkeaolmyraelfleelejayehogowlccatoxeabiemkobpigolmdkobrcidekyakabboyidep

Falsy:

a
ox
ram
bear
koala
antelope
albatross
zookeeper
salamander
caterpillar
hippopotamus
koigdgaspslycoyakehrdabowbatdkkeapogkobelrowlyarpidepetlfoxeboaiderbeefoxbgnuapeocowgiecowlkoieeltbategspemuideatdogbeezcatgeaoccattbbeassgnasolkeaflyelkaognubeeabrratoccolmobodoglyelraywelkoxantowleedrayflypeappigogatraoyakccpiganaaspkobabjaspkointantybjbeeanolmuijaylratojaynueidflyjarayabatmmpigtfly
koigdgaspslycoyakehrdabowbatdkkeapogkobelrowlyarpidepetlfoxeboaiderbeefoxbgnuapeocowgiecowlkoieeltbategspemuideatdogbeeecatgeaoccattbbeassgnasolkeaflxelkaognubeeabrratoccolmobodoglyelraywelkoxantowleedrayflypeappigogatraoyakccpiganaaspkobabjaspkointantybjbeeanolmuijaylratojaynueidflyjarayabatmmpigtfly
beyeodpgspeclxlkbkaylldnceepkocbdmymsaogsowpbawbauaioluaaagaetdoaoialeoxaagspoelegflpylptylnolnatrjabaorkdteeydloiebbptatdtfdfgoodtbkoafmounbduaffcrfelcnawmxaskgaoenaattbaobgbgabnhkesbgaaaaotafkiiieatworginaeowaehuddegooaalowaoososaksahoimkulbtoadyyelkcmkacbuostadppcuglbnmotedfgfkoleldonknemomnmoutykg
Martin Ender
sumber
Saya masih menerima saran untuk judul yang lebih baik ...
Martin Ender
You may optionally receive this list as input- Apakah itu berarti itu tidak diperhitungkan dalam skor, sedangkan hard-coding akan melakukannya?
marinus
@marinus Ya. Jadi, Anda mungkin ingin menganggapnya sebagai input tambahan, kecuali membaca lebih dari satu string pada input benar - benar rumit dalam bahasa pilihan Anda. (Saya tidak ingin mengizinkan hardcoding + "jika Anda melakukannya, kurangi dari skor Anda", karena dengan begitu Anda akan membuat orang-orang melakukan hardcoding dan mengompresnya, yang pada dasarnya akan memberi mereka bonus untuk skor mereka.)
Martin Ender
Apakah " berfungsi (keluar) parameter " termasuk parameter dengan referensi ?
mınxomaτ
5
Saya tidak percaya saya melewatkan komentar "angka bulat" di kotak pasir. Malu pada Anda, tuan! Di sekitar bagian ini 32 adalah angka bulat, bukan 30. (Dan itu tidak sepenuhnya mencoba bahwa Anda meninggalkan nama untuk hewan jantan - lihat babi).
Peter Taylor

Jawaban:

7

Japt, 51 48 45 36 33 19 byte

Disimpan 9 byte berkat @PeterTaylor

;!UeVrE"[$& ]" S² x

Uji secara online!

Mengambil input sebagai string untuk diuji, diikuti oleh daftar kata tiga huruf, dibatasi dengan |. Catatan: ini tidak berfungsi dalam versi terbaru dari interpreter, jadi silakan gunakan tautan daripada menyalin-menempelkan kode.

Bagaimana itu bekerja

Ide dasarnya adalah untuk mengambil string input dan berulang kali mengganti salah satu dari 30 kata di dalamnya dengan dua karakter pengisi. Saya menggunakan spasi sebagai pengisi char. Kami juga ingin mengganti antin elephant, the a  in ela   , the  ntin e   nt, dll. Jadi yang ingin kami lakukan adalah mengubah string 30 kata menjadi regex yang cocok dengan kombinasi ini:

ant|ape|asp|...
Becomes:
[a ][n ][t ]|[a ][p ][e ]|[a ][s ][p ]|...

Kita dapat melakukan ini dengan mudah:

;VrE"[$& ]"
          // Implicit: V = "ant|ape|asp|..."
;         // Set the vars A-J to various values. E is set to "[a-z]".
VrE       // Take V and replace each lowercase letter with:
"[$& ]"   //  "[" + the char + " ]".

Namun, ini memiliki efek yang tidak diinginkan juga mencocokkan tiga ruang, yang tidak memiliki efek pada hasil dan dengan demikian mengakhiri penggantian rekursif. Kami bisa menyiasatinya dengan mengganti pertandingan dengan dua spasi alih-alih tiga:

Ue    S²  // Take U, and recursively replace matches of the regex with " ".repeat(2).

Berikut ini adalah demonstrasi dasar tentang bagaimana dan mengapa ini bekerja (menggunakan .sebagai ganti spasi):

First match at the end: 
eleant
ele..   (ant)
el..    (eel)
...     (elk)
..      (...)
true

First match at the beginning: 
antmua
..mua   (ant)
...a    (emu)
..a     (...)
..      (boa)
true

First match in the middle: 
cantay
c..ay   (ant)
..ay    (cat)
...     (jay)
..      (...)
true

Untuk kasus-kasus uji kebenaran, ini memberi kita ruang semua string. Untuk kasus uji palsu, kami memiliki beberapa huruf yang tersisa dalam campuran. Ini dapat diterjemahkan ke benar / salah seperti:

     x   // Trim all spaces off the ends of the resulting string.
!        // Take the logical NOT of the result.
         // Empty string -> true; non-empty string -> false.

Dan itu saja! Bonus dari metode ini adalah bahwa bahkan kasus uji terbesar selesai di bawah 5 milidetik. ( Diuji di sini )

Produksi ETH
sumber
" Ini bukan hal yang mudah dengan regex saja " - ada apa dengan itu (?!,,,)?
Peter Taylor
@PeterTaylor facepalm Terima kasih, itu menghemat sekitar 10 byte ...
ETHproduksi
1
@PeterTaylor Saya telah menemukan metode yang jauh lebih pendek: cukup ganti dengan dua spasi, bukan tiga. Turun ke 19 byte!
ETHproduksi
Momen facepalm lainnya ?
Neil
@Neil Yap, cukup banyak. Saya berpikir untuk mencoba dua ruang daripada tiga, tetapi saya tidak menyadari itu akan bekerja dengan baik sampai pagi ini ketika memikirkan banyak strategi alternatif.
ETHproduksi
3

GNU grep, 62 + 1 = 63 byte

^(((.+)(?=.*!\3))*(...)(?=.*\4!)((.+)(?=.*\6!))*([^qvz]\B)?)+ 

Ini membutuhkan Popsi. Masukan diharapkan hewan yang akan disintesis, diikuti oleh spasi, diikuti oleh daftar 3 huruf hewan yang dibuka, ditutup, dan dibatasi oleh tanda seru. Contoh penggunaan (dengan asumsi program disimpan sebagai zoo):

> grep -Pf zoo
hippopotamus !ant!ape!asp!ass!bat!bee!boa!cat!cod!cow!dab!dog!eel!elk!emu!fly!fox!gnu!hog!ide!jay!kea!kob!koi!olm!owl!pig!rat!ray!yak!

Untuk input yang benar, jalur input akan bergema kembali. Untuk input yang salah, tidak ada output.

Terima kasih kepada Martin karena telah menemukan bug dan mengingatkan saya akan keberadaan \Bkata yang tidak terbatas.

feersum
sumber
Apakah grep tidak memiliki batasan non-kata \Bsehingga Anda dapat menyingkirkan lookahead terakhir? (Jika tidak, beralih ke Retina akan menghemat beberapa byte. Sebenarnya saya pikir itu akan menghemat byte, karena tidak memerlukan Popsi.)
Martin Ender
Saya tidak dapat menguji dengan grep sekarang, tetapi apakah ini benar-benar menangani kasus uji besar palsu dalam beberapa detik? Di Retina, proses mundur membutuhkan waktu cukup lama.
Martin Ender
1
@ MartinBüttner Untuk beberapa kasus falsy terakhir, itu benar-benar menyerah dan dicetak grep: exceeded PCRE's backtracking limit.
feersum
1
Menggunakan GNU sesuatu untuk menyelesaikan ini tampaknya sangat tepat.
Antti29
2

ES6, 122 121 119 104 byte

Saya telah bekerja bagaimana melakukan ini sejauh jawaban ETHproduksi tetapi tidak bisa memikirkan bagaimana menangani ,,,masalah *, jadi tentu saja ketika saya melihat komentar Peter Taylor semuanya menjadi jelas. Kemudian ETHproductions berhasil menemukan cara yang lebih baik untuk menangani masalah yang sangat membantu menghemat 15 byte.

Input adalah kata target dan berbagai kata hewani.

(s,a)=>[...s].map(_=>s=s.replace(RegExp(a.map(a=>a.replace(/./g,"[&$&]")).join`|`),'&&'))&&!/\w/.test(s)

Sunting: Disimpan 1 byte 3 byte berkat produk @ETH.

* Kecuali saya menggunakan & s karena terlihat lebih bagus di laptop saya replace.

Neil
sumber
Sangat bagus! Apakah salah satu dari hal-hal ini berfungsi: 1) menggunakan (`(?!&&&)(${a.map...})`)sebagai string, 2) menghapus tanda kurung setelah melakukan itu, 3) menggunakan eval`/(?!&&&).../` ?
ETHproduk
@ ETHproductions Saya membuat kesalahan dengan menghapus bagian luar ()yang tidak berfungsi; dengan ()kerjanya dan menyelamatkan saya satu byte. evaljuga membutuhkan ()s sehingga tidak menyimpan apa pun lebih lanjut, maaf.
Neil
Saya pikir Anda juga memiliki sepasang tanda kurung tambahan a.replace(...).
ETHproduk
Anda dapat menyimpan banyak: s=s.replace(RegExp(a.map(a=>a.replace(/./g,"[&$&]")).join`|`),'&&')Mengganti dengan dua karakter bukan tiga menghilangkan kemungkinan terjebak mengganti tiga karakter yang sama berulang-ulang.
ETHproduksi
0

JS ES6, 77 byte

s=>/^(((.+)(?=.*!\3))*(...)(?=.*\4!)((.+)(?=.*\6!))*([^qvz][^\b])?)+/.test(s)

(ini anonim fn)

Input sama dengan input contoh grep di atas

username.ak
sumber
Jika Anda mengambil input dengan prompt()bukankah seharusnya Anda menggunakan output alert()? (Atau buat saja ini fungsi.)
Neil
@Neil terima kasih, saya menggunakan anon. fn
username.ak