Sunting: teka-teki ini juga dikenal sebagai "Riddle Einstein"
The Siapa yang memiliki Zebra (Anda dapat mencoba versi online di sini ) adalah contoh dari set klasik teka-teki dan saya bertaruh bahwa kebanyakan orang di Stack Overflow dapat memecahkannya dengan pena dan kertas. Tetapi seperti apakah solusi terprogram itu?
Berdasarkan petunjuk yang tercantum di bawah ini ...
- Ada lima rumah.
- Setiap rumah memiliki warna yang unik.
- Semua pemilik rumah memiliki kebangsaan yang berbeda.
- Mereka semua memiliki hewan peliharaan yang berbeda.
- Mereka semua minum minuman yang berbeda.
- Mereka semua merokok dengan rokok yang berbeda.
- Pria Inggris itu tinggal di rumah merah.
- Pelatih asal Swedia itu memiliki seekor anjing.
- Orang Denmark minum teh.
- Rumah hijau ada di sebelah kiri rumah putih.
- Mereka minum kopi di rumah kaca.
- Pria yang merokok Pall Mall memiliki burung.
- Di rumah kuning mereka merokok Dunhill.
- Di tengah rumah mereka minum susu.
- Orang Norwegia tinggal di rumah pertama.
- Pria yang merokok Blend tinggal di rumah di sebelah rumah dengan kucing.
- Di rumah sebelah rumah tempat mereka memiliki kuda, mereka merokok Dunhill.
- Pria yang merokok Tuan Biru minum bir.
- Jerman merokok Pangeran.
- Orang Norwegia itu tinggal di sebelah rumah biru.
- Mereka minum air di rumah di sebelah rumah tempat mereka merokok Blend.
... siapa yang memiliki Zebra?
language-agnostic
logic
constraint-programming
zebra-puzzle
activout.se
sumber
sumber
Jawaban:
Berikut ini solusi dalam Python berdasarkan kendala-pemrograman:
Keluaran:
Dibutuhkan 0,6 detik (CPU 1.5GHz) untuk menemukan solusinya.
Jawabannya adalah "Jerman memiliki zebra."
Untuk menginstal
constraint
modul melaluipip
: pip install python-constraintUntuk menginstal secara manual:
unduh:
$ wget https://pypi.python.org/packages/source/p/python-constraint/python-constraint-1.2.tar.bz2#md5=d58de49c85992493db53fcb59b9a0a45
ekstrak (Linux / Mac / BSD):
$ bzip2 -cd python-constraint-1.2.tar.bz2 | tar xvf -
ekstrak (Windows, dengan 7zip ):
> 7z e python-constraint-1.2.tar.bz2
> 7z e python-constraint-1.2.tar
Install:
$ cd python-constraint-1.2
$ python setup.py install
sumber
pip install python-constraint
? Saya melakukannya beberapa saat yang lalu dan tampaknya memberikan hasil yang diharapkan.Dalam Prolog, kita bisa instantiate domain hanya dengan memilih elemen dari itu :) (membuat pilihan yang saling eksklusif , untuk efisiensi). Menggunakan SWI-Prolog,
Berjalan cukup cepat:
sumber
Satu poster sudah menyebutkan bahwa Prolog adalah solusi potensial. Ini benar, dan itu solusi yang akan saya gunakan. Dalam istilah yang lebih umum, ini adalah masalah yang sempurna untuk sistem inferensi otomatis. Prolog adalah bahasa pemrograman logika (dan interpreter terkait) yang membentuk sistem seperti itu. Ini pada dasarnya memungkinkan kesimpulan fakta dari pernyataan yang dibuat menggunakan First Order Logic . FOL pada dasarnya adalah bentuk yang lebih maju dari logika proposisional. Jika Anda memutuskan untuk tidak menggunakan Prolog, Anda dapat menggunakan sistem serupa dari kreasi Anda sendiri menggunakan teknik seperti modus ponens untuk melakukan penarikan kesimpulan.
Anda tentu saja perlu menambahkan beberapa aturan tentang zebra, karena tidak disebutkan di mana pun ... Saya percaya maksudnya adalah Anda dapat mengetahui 4 hewan peliharaan lainnya dan dengan demikian menyimpulkan yang terakhir adalah zebra? Anda ingin menambahkan aturan yang menyatakan bahwa zebra adalah salah satu hewan peliharaan, dan setiap rumah hanya dapat memiliki satu hewan peliharaan. Mendapatkan pengetahuan "akal sehat" semacam ini ke dalam sistem inferensi adalah rintangan utama untuk menggunakan teknik ini sebagai AI sejati. Ada beberapa proyek penelitian, seperti Cyc, yang berusaha memberikan pengetahuan umum melalui kekuatan kasar. Mereka telah bertemu dengan sejumlah kesuksesan yang menarik.
sumber
Kompatibel dengan SWI-Prolog:
Di penerjemah:
sumber
Begini caranya. Pertama saya akan menghasilkan semua n-tuple yang dipesan
5 ^ 6 dari mereka, 15625, mudah dikelola. Lalu saya akan menyaring kondisi boolean sederhana. ada sepuluh dari mereka, dan masing-masing yang Anda harapkan untuk menyaring 8/25 dari kondisi (1/25 dari kondisi berisi Swedia dengan anjing, 16/25 berisi non-Swedia dengan non-anjing) . Tentu saja mereka tidak mandiri tetapi setelah menyaring mereka tidak boleh ada banyak yang tersisa.
Setelah itu, Anda punya masalah grafik yang bagus. Buat grafik dengan setiap node yang mewakili salah satu n-tupel yang tersisa. Tambahkan tepi ke grafik jika kedua ujungnya berisi duplikat dalam beberapa posisi n-tuple atau melanggar batasan 'posisi' (ada lima dari mereka). Dari sana Anda hampir sampai di rumah, cari grafik untuk satu set independen lima node (dengan tidak ada node yang terhubung oleh tepi). Jika jumlahnya tidak terlalu banyak, Anda bisa saja menghasilkan semua 5-tupel n-tupel dan menyaringnya lagi.
Ini bisa menjadi kandidat yang baik untuk golf kode. Seseorang mungkin dapat menyelesaikannya dalam satu baris dengan sesuatu seperti haskell :)
renungan: Filter pass awal juga dapat menghilangkan informasi dari batasan posisi. Tidak banyak (1/25), tetapi masih signifikan.
sumber
Solusi Python lain, kali ini menggunakan PyKE Python (Python Knowledge Engine). Memang, ini lebih verbose daripada menggunakan modul "kendala" Python dalam solusi oleh @JFSebastian, tetapi memberikan perbandingan yang menarik bagi siapa pun yang mencari mesin pengetahuan mentah untuk jenis masalah ini.
clues.kfb
relations.krb
driver.py (sebenarnya lebih besar, tapi ini intinya)
Output sampel:
Sumber: https://github.com/DreadPirateShawn/pyke-who-owns-zebra
sumber
Berikut adalah kutipan dari solusi lengkap menggunakan NSolver , yang diposting di Einstein's Riddle di C # :
sumber
Berikut ini adalah solusi langsung dalam CLP (FD) (lihat juga clpfd):
Menjalankannya, menghasilkan:
sumber
neighbor(X,Y) :- abs(X-Y) #= 1.
Dalam PAIP (Bab 11), Norvig memecahkan teka-teki zebra menggunakan Prolog yang tertanam dalam Lisp .
sumber
ES6 (Javascript) solusi
Dengan banyak generator ES6 dan sedikit lodash . Anda akan membutuhkan Babel untuk menjalankan ini.
Hasil:
Run time sekitar 2,5-an untuk saya, tetapi ini dapat ditingkatkan banyak dengan mengubah urutan aturan. Saya memutuskan untuk menjaga agar kejelasannya tetap asli.
Terima kasih, ini adalah tantangan keren!
sumber
Ini benar-benar masalah penyelesaian kendala. Anda dapat melakukannya dengan semacam propagasi kendala umum dalam pemrograman logika seperti bahasa. Kami memiliki demo khusus untuk masalah Zebra di sistem ALE (atribut logic engine):
http://www.cs.toronto.edu/~gpenn/ale.html
Berikut tautan ke pengodean puzzle Zebra yang disederhanakan:
http://www.cs.toronto.edu/~gpenn/ale/files/grammars/baby.pl
Untuk melakukan ini secara efisien adalah masalah lain.
sumber
Cara termudah untuk memecahkan masalah seperti itu secara terprogram adalah dengan menggunakan loop bersarang atas semua permutasi dan periksa untuk melihat apakah hasilnya memenuhi predikat dalam pertanyaan. Banyak predikat dapat diangkat dari loop dalam ke loop luar untuk mengurangi kompleksitas komputasi secara dramatis hingga jawabannya dapat dihitung dalam waktu yang wajar.
Berikut ini adalah solusi F # sederhana yang berasal dari artikel di F # Journal :
Output yang diperoleh dalam 9ms adalah:
sumber
Contoh Microsoft Solver Foundation dari: https://msdn.microsoft.com/en-us/library/ff525831%28v=vs.93%29.aspx?f=255&MSPPError=-2147217396
sumber
Ini adalah solusi MiniZinc untuk teka-teki zebra seperti yang didefinisikan dalam Wikipedia:
Larutan:
sumber