Ini ditulis sebagai bagian dari Push Puzzle Pemrograman Premier Periodik Pertama .
Permainan
Kata awal dan akhir dengan panjang yang sama disediakan. Tujuan permainan ini adalah untuk mengubah satu huruf dalam kata awal untuk membentuk kata valid yang berbeda, mengulangi langkah ini hingga kata akhir tercapai, menggunakan jumlah langkah paling sedikit. Misalnya, diberi kata TREE dan FLED, hasilnya adalah:
TREE
FREE
FLEE
FLED
2
Spesifikasi
- Artikel Wikipedia untuk OWL atau SOWPODS mungkin merupakan titik awal yang berguna sejauh daftar kata pergi.
- Program harus mendukung dua cara untuk memilih kata-kata awal dan akhir:
- Ditentukan oleh pengguna melalui baris perintah, stdin, atau apa pun yang sesuai dengan bahasa pilihan Anda (sebutkan apa yang Anda lakukan).
- Memilih 2 kata secara acak dari file.
- Kata-kata awal dan akhir, serta semua kata sementara harus sama panjangnya.
- Setiap langkah harus dicetak pada garisnya.
- Baris terakhir dari output Anda harus berupa jumlah langkah sementara yang diperlukan untuk mendapatkan antara kata-kata awal dan akhir.
- Jika kecocokan tidak ditemukan antara kata-kata awal dan akhir, output harus terdiri dari 3 baris: kata awal, kata akhir, dan kata OY.
- Masukkan Notasi O Besar untuk solusi Anda dalam jawaban Anda
- Harap sertakan 10 pasangan kata awal dan akhir yang unik (dengan outputnya, tentu saja) untuk menunjukkan langkah-langkah yang dihasilkan program Anda. (Untuk menghemat ruang, sementara program Anda harus menampilkan ini pada setiap baris, Anda dapat mengkonsolidasikan ini menjadi satu baris untuk posting, mengganti baris baru dengan spasi dan koma di antara setiap proses.
Sasaran / Kriteria Menang
- Solusi Big O tercepat / terbaik menghasilkan langkah-langkah sementara terpendek setelah satu minggu akan menang.
- Jika hasil seri dari kriteria Big O, kode terpendek akan menang.
- Jika masih ada seri, solusi pertama untuk mencapai revisi tercepat dan terpendek akan menang.
Tes / Output Sampel
DIVE
DIME
DAME
NAME
2
PEACE
PLACE
PLATE
SLATE
2
HOUSE
HORSE
GORSE
GORGE
2
POLE
POSE
POST
PAST
FAST
3
Validasi
Saya sedang mengerjakan skrip yang dapat digunakan untuk memvalidasi output.
Itu akan:
- Pastikan setiap kata valid.
- Pastikan setiap kata tepat 1 huruf berbeda dari kata sebelumnya.
Tidak akan:
- Periksa apakah jumlah langkah terpendek digunakan.
Setelah saya mendapatkan yang tertulis, tentu saja saya akan memperbarui posting ini. (:
code-challenge
word-puzzle
1p5
Rebecca Chernoff
sumber
sumber
HOUSE
keGORGE
dilaporkan sebagai 2. Saya menyadari ada 2 kata menengah, sehingga tidak masuk akal, tapi # operasi akan lebih intuitif.The fastest/best Big O solution producing the shortest interim steps after one week will win.
Karena Anda tidak dapat menjamin, bahwa solusi tercepat adalah sementara, yang menggunakan langkah paling sedikit, Anda harus memberikan preferensi, jika satu solusi menggunakan langkah yang lebih sedikit, tetapi mencapai tujuan nanti.BAT
danCAT
tidak memiliki langkah, kan?Jawaban:
Karena panjang terdaftar sebagai kriteria, inilah versi golf di 1681 karakter (mungkin masih dapat ditingkatkan 10%):
Versi ungolfed, yang menggunakan nama paket dan metode dan tidak memberikan peringatan atau memperluas kelas hanya untuk alias mereka, adalah:
Seperti yang Anda lihat, analisis biaya berjalan adalah
O(filelength + num_words * hash + V * n * (n + hash) + E * hash)
. Jika Anda akan menerima asumsi saya bahwa penyisipan / pencarian tabel hash adalah waktu yang konstan, ituO(filelength + V n^2 + E)
. Statistik grafik tertentu dalam SOWPODS berarti yangO(V n^2)
benar - benar mendominasiO(E)
sebagian besarn
.Output sampel:
IDOLA, IDOLS, IDYLS, ODYLS, ODALS, OVAL, OVEL, OVENS, EVENS, ETENS, STENS, SKENS, KULIT, SPINS, SPINE, 13
WICCA, PROSY, OY
BRINY, BRIN, TRIN, TAIN, TARNS, BENANG, YAWNS, YAWPS, YAPPS, 7
GALES, GAS, GAS, GEST, GESTE, GESSE, DESSE, 5
SURES, SELAMA, DUNE, DINES, DING, DINGY, 4
LICHT, LIGHT, BIGHT, BIGOT, BIGOS, BIROS, GIROS, GIRNS, GURNS, GUANS, GUANA, RUANA, 10
SARGE, SERGE, SERRE, SERRS, SEER, DEER, DYERS, OYERS, OVERS, OVEL, OVAL, ODAL, ODYLS, ODYLS, IDYLS, 12
KEIRS, SEIRS, SEER, BEERS, BRERS, BRERE, BREME, CREME, CREPE, 7
Ini adalah salah satu dari 6 pasangan dengan jalur terpendek terpanjang:
GAINEST, FAINEST, FAIREST, SAIREST, SAIDEST, SADDEST, MADDEST, MIDDEST, MILDEST, WILDEST, WILIEST, WALIEST, WANIEST, CANIEST, CANTEST, CONTEST, KONFES, KONFES, KONFER, KONTAK, COPERS, COVER. POPPITS, Poppies, POPSIES, MOPSIES, MOUSIES, mousse, POUSSES, plusses, PLISSES, Prisses, menekan, PREASES, UREASES, UNEASES, UNCASES, UNCASED, UNBASED, UNBATED, UNMATED, UNMETED, UNMEWED, ENMEWED, ENDEWED, INDEWED, diindeks, INDEKS, INDEN, INDENTS, INSENTS, INCENTS, INFESTS, INFECTS, INJECTS, 56
Dan salah satu pasangan 8-huruf yang larut dalam kasus terburuk:
ENROBING, UNROBING, UNROPING, UNCOPING, UNCAPING, UNCAGING, ENCAGING, ENRAGING, ENRACING, ENLACING, UNLACING, UNLAYING, UPLAYING, SPLAYING, SPAYING, SABAR, STROYING, STROYING, STROKE, STOCK, STUCING, MENGAMBING, MENGUMPUTAN, MENGUMPULKAN, MENGUMPULKAN, MENGUMPULKAN, MENGUMPULKAN, MENGUMPULKAN, MENGUAT, MENGUMPULKAN, MENGUMPULKAN, MENGUMPULKAN, MENGUMPULKAN. CRIMPING, CRISPING, CRISPINS, CRISPENS, CRISPERS, CRIMPERS, CRAMPERS, CLAMPERS, CLASPERS, CLASHER, SLASHER, SLATHERS, SLITHERS, SMITHERS, SOOTHERS, SOUTHERS, MOUTHERS, MOUTCHERS, PUTERS, PUTERS, PUTERS LUNCHERS, LYNCHERS, LYNCHETS, LINCHETS, 52
Sekarang saya pikir saya sudah mendapatkan semua persyaratan dari pertanyaan, diskusi saya.
Untuk CompSci, pertanyaannya jelas berkurang menjadi jalur terpendek dalam grafik G yang simpulnya adalah kata-kata dan ujung-ujungnya menghubungkan kata-kata yang berbeda dalam satu huruf. Menghasilkan grafik secara efisien bukanlah hal sepele - Saya benar-benar memiliki ide yang perlu saya tinjau kembali untuk mengurangi kompleksitas menjadi O (V n hash + E). Cara saya melakukannya melibatkan pembuatan grafik yang menyisipkan simpul tambahan (sesuai dengan kata-kata dengan satu karakter wildcard) dan bersifat homeomorfik dengan grafik yang dimaksud. Saya memang mempertimbangkan menggunakan grafik itu daripada mengurangi ke G - dan saya kira itu dari sudut pandang golf yang seharusnya saya lakukan - atas dasar bahwa simpul wildcard dengan lebih dari 3 tepi mengurangi jumlah tepi dalam grafik, dan kasus berjalan terburuk standar algoritma jalur terpendek adalah
O(V heap-op + E)
.Namun, hal pertama yang saya lakukan adalah menjalankan beberapa analisis grafik G untuk panjang kata yang berbeda, dan saya menemukan bahwa mereka sangat jarang untuk kata-kata dari 5 huruf atau lebih. Grafik 5 huruf memiliki 12478 simpul dan 40759 tepi; menambahkan node tautan membuat grafik semakin buruk. Pada saat Anda hingga 8 huruf ada lebih sedikit tepi daripada node, dan 3/7 dari kata-kata itu "menyendiri". Jadi saya menolak gagasan optimasi itu karena tidak terlalu membantu.
Gagasan yang terbukti bermanfaat adalah memeriksa tumpukan itu. Saya bisa jujur mengatakan bahwa saya telah menerapkan beberapa tumpukan yang cukup eksotis di masa lalu, tetapi tidak ada yang eksotis seperti ini. Saya menggunakan bintang-A (karena C tidak memberikan manfaat mengingat tumpukan yang saya gunakan) dengan heuristik yang jelas dari jumlah huruf yang berbeda dari target, dan sedikit analisis menunjukkan bahwa setiap saat tidak ada lebih dari 3 prioritas yang berbeda di tumpukan. Ketika saya memunculkan simpul yang prioritasnya adalah (biaya + heuristik) dan melihat tetangganya, ada tiga kasus yang saya pertimbangkan: 1) biaya tetangga adalah biaya + 1; heuristik tetangga adalah heuristik-1 (karena huruf yang diubahnya menjadi "benar"); 2) biaya + 1 dan heuristik + 0 (karena huruf yang diubahnya berubah dari "salah" ke "masih salah"; 3) biaya +1 dan heuristik +1 (karena huruf yang diubahnya berubah dari "benar" menjadi "salah"). Jadi, jika saya menenangkan tetangga, saya akan memasukkannya pada prioritas yang sama, prioritas + 1, atau prioritas + 2. Sebagai hasilnya, saya dapat menggunakan array 3-elemen dari daftar tertaut untuk heap.
Saya harus menambahkan catatan tentang asumsi saya bahwa pencarian hash konstan. Baiklah, Anda mungkin berkata, tetapi bagaimana dengan perhitungan hash? Jawabannya adalah bahwa saya mengamortisasi mereka:
java.lang.String
menyimpannyahashCode()
, jadi total waktu yang dihabiskan untuk menghitung hash adalahO(V n^2)
(dalam menghasilkan grafik).Ada perubahan lain yang memengaruhi kompleksitas, tetapi pertanyaan apakah ini merupakan pengoptimalan atau tidak bergantung pada asumsi Anda tentang statistik. (IMO menempatkan "solusi Big O terbaik" sebagai kriteria adalah kesalahan karena tidak ada kompleksitas terbaik, karena alasan sederhana: tidak ada variabel tunggal). Perubahan ini memengaruhi langkah pembuatan grafik. Dalam kode di atas, itu:
Itu
O(V * n * (n + hash) + E * hash)
. TetapiO(V * n^2)
bagian tersebut berasal dari menghasilkan string n-karakter baru untuk setiap tautan dan kemudian menghitung kode hash-nya. Ini dapat dihindari dengan kelas pembantu:Kemudian paruh pertama pembuatan grafik menjadi
Dengan menggunakan struktur kode hash kita dapat menghasilkan tautan
O(V * n)
. Namun, ini memiliki efek knock-on. Melekat dalam asumsi saya bahwa pencarian hash adalah waktu yang konstan adalah asumsi bahwa membandingkan objek untuk kesetaraan itu murah. Namun, uji persamaan LinkO(n)
dalam kasus terburuk. Kasus terburuk adalah ketika kita memiliki tabrakan hash antara dua tautan yang sama yang dihasilkan dari kata-kata yang berbeda - yaitu terjadiO(E)
kali pada paruh kedua generasi grafik. Selain itu, kecuali jika terjadi tabrakan hash antara tautan yang tidak sama, kami baik-baik saja. Jadi kami telah diperdagangkan diO(V * n^2)
untukO(E * n * hash)
. Lihat poin saya sebelumnya tentang statistik.sumber
Jawa
Kompleksitas : ?? (Saya tidak memiliki gelar CompSci, jadi saya akan menghargai bantuan dalam hal ini.)
Input : Berikan Pair of words (lebih dari 1 pair jika Anda mau) di baris perintah. Jika tidak ada baris Perintah yang ditentukan 2 kata acak yang berbeda dipilih.
sumber
System.nanoTime()
.c pada unix
Menggunakan algoritma dijkstra.
Sebagian besar dari kode adalah implementasi pohon kostum n-ary, yang berfungsi untuk menahan
Siapa pun tertarik melihat bagaimana kerjanya mungkin harus membaca
findPath
,process
danprocessOne
(dan komentar mereka terkait). Dan mungkinbuildPath
danbuildPartialPath
. Sisanya adalah pembukuan dan perancah. Beberapa rutin yang digunakan selama pengujian dan pengembangan tetapi tidak dalam versi "produksi" telah ditinggalkan.Saya menggunakan
/usr/share/dict/words
pada saya kotak Mac OS 10.5, yang memiliki begitu banyak lama, entri esoterik yang membiarkan berjalan secara acak menghasilkan banyak dariOY
s.Beberapa output:
Analisis kompleksitas adalah non-sepele. Pencarian adalah pendalaman berulang dua sisi, berulang.
W
.S_min = (<number of different letter>-1)
karena jika kita hanya terpisah satu huruf, kita menilai perubahan pada 0 langkah menengah. Maksimum sulit untuk diukur melihat TRICKY - SWOOSH berjalan di atas. Setiap setengah dari pohon akanS/2-1
keS/2
B
.Jadi jumlah minimum operasi sekitar
2 * (S/2)^B * W
, tidak terlalu bagus.sumber
O(|V|+|E|)
bukanO(|E|+|V| log |V|)
?