Minggu lalu, kami berupaya membuat string 1-D terpendek menggunakan 10.000 kata teratas dalam bahasa Inggris . Sekarang, mari kita coba tantangan yang sama dalam 2D!
Yang perlu Anda lakukan adalah mengambil semua kata-kata di atas, dan menempatkannya dalam kotak sekecil mungkin, memungkinkan tumpang tindih. Misalnya, jika kata-kata Anda adalah ["ape","pen","ab","be","pa"]
, maka persegi panjang yang mungkin adalah:
.b..
apen
Kotak di atas akan memberikan skor 5.
Aturan:
- Tumpang tindih beberapa huruf dalam sebuah kata diperbolehkan
- Kata-kata bisa masuk ke salah satu dari 8 arah
- Kata-kata tidak bisa membungkus
- Anda dapat menggunakan karakter apa pun untuk lokasi kosong
Anda perlu membuat pencarian kata yang berisi 10.000 kata teratas ini dalam bahasa Inggris (menurut Google). Skor Anda sama dengan jumlah karakter dalam pencarian kata Anda (tidak termasuk karakter yang tidak digunakan). Jika ada dasi, atau jika kiriman terbukti optimal, maka kiriman yang pertama kali diposting menang.
sumber
Jawaban:
Rust,
3143030081 karakter yang digunakanIni adalah semacam algoritma serakah: kita mulai dengan kotak kosong, dan berulang kali menambahkan kata yang dapat ditambahkan dengan huruf baru paling sedikit, dengan ikatan yang terputus dengan memilih kata-kata yang lebih panjang. Untuk menjalankan ini dengan cepat, kami mempertahankan antrian prioritas penempatan kata kandidat (diimplementasikan sebagai vektor vektor deques, dengan vektor untuk setiap jumlah huruf baru, berisi deque untuk setiap panjang kata). Untuk setiap surat yang baru ditambahkan, kami meminta semua penempatan kandidat yang berjalan melalui surat itu.
Kompilasi dan jalankan bersama
rustc -O wordsearch.rs; ./wordsearch < google-10000-english.txt
. Di laptop saya, ini berjalan dalam 70 detik, menggunakan 531 MiB RAM.Keluaran cocok dalam segi empat dengan 248 kolom dan 253 baris.
Kode
sumber
C ++, 27243 kisi karakter (248x219, diisi 50,2%)
(Posting ini sebagai jawaban baru karena saya ingin menjaga 1D terikat yang awalnya saya posting sebagai referensi)
Ini
terang-terangan robeksangat terinspirasi oleh jawaban @ AndersKaseorg di struktur utamanya, tetapi memiliki beberapa tweak. Pertama, saya menggunakan program asli saya untuk menggabungkan string sampai tumpang tindih terbaik yang tersedia hanya 3 karakter. Kemudian saya menggunakan metode yang dijelaskan AndersKaseorg untuk secara progresif mengisi kisi 2D menggunakan string yang dihasilkan ini. Batasannya juga sedikit berbeda: masih mencoba untuk menambah karakter paling sedikit setiap kali, tetapi ikatannya terputus dengan memilih kotak persegi pertama, kemudian kotak kecil, dan akhirnya dengan menambahkan kata terpanjang.Perilaku yang ditampilkannya adalah bergantian antara periode mengisi ruang dan memperluas grid dengan cepat (sayangnya kehabisan kata-kata hanya setelah tahap ekspansi cepat, jadi ada banyak ruang kosong di tepinya). Saya menduga dengan beberapa penyesuaian fungsi biaya, itu bisa dibuat untuk mendapatkan lebih dari 50% pengisian ruang.
Ada 2 executable di sini (untuk menghindari kebutuhan untuk menjalankan kembali seluruh proses ketika secara iteratif meningkatkan algoritma). Output dari satu dapat disalurkan langsung ke yang lain:
Dan akhirnya, hasilnya:
Hasil alternatif (setelah memperbaiki beberapa bug dalam program yang membiaskan arah tertentu dan mengubah fungsi biaya, saya mendapatkan solusi yang lebih ringkas namun kurang optimal): 29275 karakter, 198x195 (diisi 75,8%):
Sekali lagi saya belum melakukan banyak hal untuk mengoptimalkan program-program ini, jadi butuh beberapa saat. Tapi Anda bisa melihatnya mengisi di grid, yang cukup menghipnotis.
sumber
C ++, 34191 karakter "grid" (dengan intervensi manusia minimal, 6 atau 7 dapat dengan mudah diselamatkan)
Ini harus diambil lebih sebagai terikat untuk kasus 2D, karena jawabannya masih berupa string 1D. Ini hanya kode saya dari tantangan sebelumnya, tetapi dengan kemampuan baru untuk membalik string apa pun. Ini memberi kita lebih banyak ruang untuk menggabungkan kata-kata (terutama karena itu membatasi kasus terburuk superstring yang tidak tumpang tindih menjadi 26; satu untuk setiap huruf alfabet).
Untuk sedikit daya tarik visual 2D, ia menempatkan linebreak di hasilnya jika dapat melakukannya secara gratis (yaitu antara kata-kata 0-tumpang tindih).
Cukup lambat (masih belum ada caching). Ini kodenya:
Hasil: http://pastebin.com/UTe2WMcz (4081 karakter lebih sedikit dari tantangan sebelumnya)
Cukup jelas bahwa beberapa penghematan sepele dapat dilakukan dengan meletakkan garis
xd
danwv
vertikal, memotong garis monster. Kemudianhhidetautisbneudui
bisa bersinggungan dengand
, danlxwwwowaxocnnaesdda
denganw
. Ini menghemat 4 karakter.nbcllilhn
dapat diganti menjadis
tumpang tindih yang ada (jika ada dapat ditemukan) untuk menyimpan 2 lainnya (atau hanya 1 jika tidak ada tumpang tindih seperti itu dan harus ditambahkan secara vertikal sebagai gantinya). Akhirnyamjjrajaytq
dapat ditambahkan secara vertikal di suatu tempat untuk menyelamatkan 1. Ini berarti dengan intervensi manusia minimal, 6-7 karakter dapat diselamatkan dari hasilnya.Saya ingin mendapatkan ini menjadi 2D dengan metode berikut, tapi saya berjuang untuk menemukan cara untuk mengimplementasikannya tanpa membuat algoritma O (n ^ 4), yang cukup tidak praktis untuk dihitung!
sumber
PHP
ini melakukan pekerjaan terapi; tetapi 10.000 mungkin terlalu banyak kata untuk rekursi. Script sedang berjalan sekarang. (masih berjalan 24 jam kemudian)
berfungsi dengan baik pada direktori kecil, tetapi saya dapat membuat versi iteratif minggu depan.
$f=array("pen","op","po","ne","pro","aaa","abcd","dcba"); will output
abcdalthough this is not an optimal result (scoring was changed ... I´m working on a generator). One optimal result is this:
terbukaIni juga tidak terlalu cepat; hanya menghilangkan substring dan memilah sisa-sisa dengan panjang,
sisanya adalah kekuatan kasar: mencoba untuk memasukkan kata-kata ke dalam persegi panjang, coba pada persegi panjang yang lebih besar jika gagal.
btw: Substring membutuhkan 4,5 menit pada mesin saya untuk direktori besar
dan memotongnya menjadi 6.190 kata; jenisnya membutuhkan waktu 11 detik.
sumber