Dalam episode Futurama, Tahanan Benda anggota kru bertukar tubuh satu sama lain, dengan tangkapan bahwa tidak ada pasangan tubuh yang dapat bertukar pikiran lebih dari satu kali.
Tantangan
Tulis sebuah program atau fungsi yang menerima kumpulan swap pikiran-tubuh yang sah yang telah terjadi, dan mengeluarkan serangkaian pertukaran hukum yang akan mengembalikan setiap pikiran ke tubuh aslinya. Pengidentifikasi untuk koleksi pikiran-tubuh ini harus berupa string yang tidak akan berisi baris baru. Anda dapat menambahkan hingga dua orang (yang diberi nama berbeda) yang belum pernah berganti ke grup input. (Bukti bahwa Anda hanya membutuhkan paling banyak 2 badan tambahan) Namun, Anda harus menambahkan jumlah minimum orang yang diperlukan untuk menyelesaikan masalah.
Input dan output dapat mengambil bentuk yang jelas, namun tidak ada informasi tambahan yang dapat disimpan. Anda mungkin menganggap itu selalu valid. Ini adalah kode golf, jadi pemenangnya adalah pengiriman dengan byte paling sedikit.
Contohnya
[('A','B'),('C','D')] -> [('A','C'),('B','D'),('A','D'),('B','C')]
['A','B'] -> ['C','D','A','C','B','D','A','D','B','C']
[('A','B'),('C','D'),('A','C'),('A','D')] -> [('B', 'E'), ('A', 'E'), ('C', 'B'), ('C', 'E')]
"A\nB\nC\nD\n" -> "A\nC\nB\nD\nA\nD\nB\nC\n"
Yang dari acara:
[("Amy","Hubert"),("Bender","Amy"),("Hubert","Turanga"),("Amy","Wash Bucket"),("Wash Bucket","Nikolai"),("Phillip","John"),("Hermes","Turanga")]
Solusi acara, yang diberikan di bawah ini tidak valid:
[("Clyde","Phillip"),("Ethan","John"),("Clyde","John"),("Ethan",Phillip"),("Clyde","Hubert"),("Ethan","Wash Bucket"),("Clyde","Leela"),("Ethan","Nikolai"),("Clyde","Hermes"),("Ethan","Bender"),("Clyde","Amy"),("Ethan","Hubert"),("Clyde","Wash Bucket")]
Ini tidak valid karena Ethan, dan Clyde tidak perlu karena seberapa sedikit Fry Phillip, Zoidberg John dan Hermes Hermes menggunakan mesin. Solusi yang valid untuk kasus ini disediakan di bawah ini:
[("Philip","Hubert"),("John","Wash Bucket"),("Philip","Turanga"),("John","Nikolai"),("Philip","Hermes"),("John","Bender"),("Philip","Amy"),("John","Hubert"),("Philip","Wash Bucket")]
Perhatikan bahwa ada banyak kemungkinan jawaban untuk setiap input yang valid. Apa pun valid.
[('Nikolai', 'Phillip'), ('Nikolai', 'Hubert'), ('Nikolai', 'Turanga'), ('Nikolai', 'Bender'), ('Phillip', 'Amy'), ('John', 'Wash Bucket'), ('Nikolai', 'John'), ('Phillip', 'Wash Bucket'), ('Hubert', 'John'), ('Bender', 'Hermes')]
Jawaban:
Python 3: 328 karakter (lambat), 470 karakter (cepat)
Mungkin agak terlalu lama untuk jawaban yang serius.
Kode lambat dan pendek:
d(u,s)
berlaku swaps
keu
. Dalam metode utamaf(Q)
, saya pertama-tama menghasilkan daftar semua orangn
menggunakan operasi yang ditetapkan dan mengubah hasilnya kembali ke daftar. Thewhile 1
-loop tentu saja tidak loop tak terbatas. Di dalamnya, saya mencoba juga memecahkan masalah menggunakan orang yang saya milikin
. Jika tidak berhasil, saya menambahkan orang lain dengan menggabungkan semua naman+=[''.join(n)]
. Oleh karena ituwhile 1
-loop dieksekusi paling banyak 3 kali (lihat bukti dalam pertanyaan).Pemecahan masalah dilakukan bruteforce. Saya menghasilkan semua swap yang legal dan mencoba semua permutasi
for t in permutations(i for i in combinations(n,2)if not set((i,i[::-1]))&set(Q))
. Jika setiap orang berada di dalam tubuhnya sendiri, saya mengembalikan urutan swap.Pemakaian:
Contoh dari futurama terlalu lama. Ada 9 orang, jadi ada 36 kemungkinan swap dan 28 di antaranya legal. Jadi ada 26! permutasi hukum.
Kode lebih cepat
Fungsi ini
f(Q)
memiliki pendekatan pendalaman berulang. Pertama mencoba kedalaman = 0, kemudian kedalaman = 1, sampai kedalaman = (l * ll) // 2-len (Q), yang merupakan jumlah maksimum dari langkah hukum. Seperti kode yang lebih lambat, ia kemudian menambahkan orang lain dan mencoba lagi.Fungsi rekursif
r(n,u,Q,t,d)
mencoba untuk menyelesaikan posisi saat iniu
dengand
swap.n
adalah posisi yang dipecahkan,Q
input bergerak dant
bergerak sudah dilakukan. Pertama-tama ia menghitung batas bawah swap yangm
diperlukan (dengan menyelesaikan negara dengan swap legal dan ilegal). Jikam
== 0, semua orang berada di badan yang benar, sehingga ia mencetak solusinyat
. Kalau tidak, ia mencoba semua kemungkinan swaps
, jikam<d
(pemangkasan),d>1
(yang sudah termasuk dalamm<d
,i//l<i%l
(jangan izinkan swap seperti('A','A')
atau('A','B')
dan('B','A')
) dannot set([s,s[::-1]])&set(Q+t)
(s
belum dilakukan).Pemakaian:
Ia menemukan swap optimal untuk masalah futurama dalam waktu sekitar 17 detik pada laptop saya menggunakan pypy dan sekitar 2 menit tanpa pypy. Perhatikan bahwa kedua algoritma menghasilkan solusi yang berbeda, saat memanggilnya dengan parameter yang sama. Ini karena algoritma hashing dari python-
set
.n
menyimpan orang tersebut setiap kali dalam urutan yang berbeda. Oleh karena itu algoritme mungkin lebih cepat atau lebih lambat setiap kali dijalankan.Sunting: Kasing uji futurama asli salah, kasing yang dikoreksi memiliki solusi optimal 9 bukannya 10, dan karenanya lebih cepat. 2 detik dengan pypy, 7 detik tanpa.
sumber