Latar Belakang
Saya terinspirasi oleh 3Blue1Brown 's baru-baru ini video yang tentang masalah kalung membelah (atau saat ia menyebutnya, masalah kalung itu dicuri) dan hubungannya dengan teorema Borsuk-Ulam .
Dalam masalah ini, dua pencuri telah mencuri kalung berharga yang terdiri dari beberapa jenis permata. Ada bahkan jumlah setiap jenis permata dan pencuri ingin membagi setiap jenis permata secara merata di antara keduanya. Tangkapannya adalah bahwa mereka harus melakukannya dengan membelah kalung itu menjadi beberapa segmen yang berdekatan dan mendistribusikan segmen tersebut di antara mereka berdua.
Berikut adalah contoh dengan empat jenis permata dilambangkan S
, E
, D
, dan R
(untuk safir, zamrud, berlian, dan ruby, masing-masing). Katakanlah kalung itu adalah sebagai berikut:
[S,S,S,E,S,D,E,R,S,R,E,S,S,S,D,R,E,E,R,E,D,E,R,R,D,E,E,E]
Ada 8
safir, 10
zamrud, 4
berlian, dan 6
rubi. Kita dapat membagi kalung itu sebagai berikut:
[[S],[S],[S,E,S,D,E,R,S],[R,E,S,S,S,D,R,E,E,R,E,D,E],[R,R,D,E,E,E]]
Kemudian jika kita memberikan segmen pertama, ketiga, dan kelima untuk satu pencuri dan segmen kedua dan keempat untuk pencuri yang lain, masing-masing akan berakhir dengan 4
safir, 5
zamrud, 2
berlian, dan 3
rubi:
[S], [S,E,S,D,E,R,S], [R,R,D,E,E,E]
[S], [R,E,S,S,S,D,R,E,E,R,E,D,E],
Menggunakan 0
-indexing, pemotongan ini terjadi pada indeks [1,2,9,22]
.
Tujuan
Ternyata pembagian yang adil seperti itu selalu bisa dilakukan menggunakan paling banyak n
pemotongan, di mana n
jumlah jenis permata. Tugas Anda adalah untuk menulis program atau fungsi lengkap yang mengambil kalung sebagai input dan menghasilkan divisi minimal seperti itu (jumlah pemotongan paling sedikit).
Memasukkan
Input mungkin dalam format apa pun yang nyaman. Kalung itu harus menjadi urutan permata dan tidak lebih dari itu; misalnya daftar bilangan bulat, kamus dengan kunci yang mewakili jenis permata dan nilai yang menjadi daftar indeks. Anda bisa memasukkan panjang kalung atau jumlah jenis permata yang berbeda, tetapi Anda tidak boleh mengambil input lain.
Anda dapat mengasumsikan bahwa kalung input valid. Anda tidak perlu menangani kasing di mana ada jumlah permata yang ganjil dari jenis yang diberikan atau kalung itu kosong.
Keluaran
Sekali lagi, output mungkin dalam format yang mudah; misalnya daftar segmen, daftar posisi pemotongan, kamus dengan kunci yang mewakili dua pencuri dan nilai menjadi daftar segmen, dll. Segmen dapat diwakili oleh indeks awal, indeks akhir, daftar indeks berturut-turut, daftar perhiasan, panjangnya, dll. Anda dapat menggunakan 0
- atau 1
- pengindeksan. Jika pemesanan tidak signifikan untuk format Anda, maka output Anda mungkin dalam urutan apa pun. Berikut ini adalah output di atas dalam beberapa format berbeda:
list of segments: [[S],[S],[S,E,S,D,E,R,S],[R,E,S,S,S,D,R,E,E,R,E,D,E],[R,R,D,E,E,E]]
list of cuts: [1,2,9,22]
list of lengths: [1,1,7,13,6]
dictionary: {'thief1' : [(R,R,D,E,E,E),(S),(S,E,S,D,E,R,S)], 'thief2' : [(S),(R,E,S,S,S,D,R,E,E,R,E,D,E)]}
Perhatikan bahwa urutan penting dalam daftar segmen (segmen bergantian antara pencuri) dan daftar panjang (untuk mengidentifikasi segmen), tetapi tidak dalam daftar potongan atau kamus. Sunting: Greg Martin menunjukkan bahwa ini tidak akan menjadi hasil yang valid karena pembagian yang adil dapat diperoleh dalam dua pemotongan
Uji kasus
[1,2,1,2,1,3,1,3,3,2,2,3] -> [[1,2,1],[2,1,3,1],[3,3,2],[2,3]]
[1,1,1,1,2,2,3,3,3,3,3,3] -> [[1,1],[1,1,2],[2,3,3,3],[3,3,3]]
[1,1,1,1,1,1,1,1,1,1,1,1] -> [[1,1,1,1,1,1],[1,1,1,1,1,1]]
[1,1,1,1,2,3,4,2,3,4,2,2] -> [[1,1],[1,1,2,3,4,2],[3,4,2,2]]
Catatan
- Celah standar dilarang.
- Ini adalah kode-golf ; jawaban terpendek (dalam byte) menang.
sumber
[S,S,S,E,S,D,E,R,S,R,E,S,S,S,D,R,E,E,R,E,D,E,R,R,D,E,E,E]
, tampaknya output harus[[S,S,S,E,S,D,E,R],[S,R,E,S,S,S,D,R,E,E,R,E,D,E],[R,R,D,E,E,E]]
, karena yang memiliki luka kurang dari[[S],[S],[S,E,S,D,E,R,S],[R,E,S,S,S,D,R,E,E,R,E,D,E],[R,R,D,E,E,E]]
. Apakah saya memahami spesifikasi dengan benar?Jawaban:
Brachylog , 13 byte
Cobalah online!
Catatan: metapredicate
ᵛ
lebih baru dari tantangan ini.Penjelasan
Partisi disebutkan dalam urutan jumlah blok yang meningkat, sehingga hasilnya akan memiliki blok sesedikit mungkin.
sumber
Jelly , 18 byte
Cobalah online!
Tidak efisien - contoh memiliki 28 jewels yang bekerja wont tanpa sumber daya yang besar sejak langkah pertama pelaksanaan ini akan membangun daftar 2 27 partisi mungkin.
Mengembalikan daftar daftar - segmen dalam urutan untuk mengeluarkannya di antara pencuri alternatif. (Re output TIO: ketika daftar hanya memiliki satu item, cetakan implisit tidak mengganggu kurung,
[]
)Bagaimana?
sumber
Mathematica, 118 byte
Hampir mengalahkan Jelly ... hanya 1 off;)
Fungsi murni mengambil tiga argumen: kalung, sebagai daftar token seperti
{A, A, A, A, B, C, D, B, C, D, B, B}
; panjang kalung; dan jumlah waktu permata yang berbeda. Ini mengembalikan daftar sublists dalam bentuk{{A, A}, {-A, -A, -B, -C, -D, -B}, {C, D, B, B}}
, di mana token tanpa tanda negatif pergi ke satu pencuri dan token dengan tanda negatif pergi ke pencuri yang lain. (Walaupun ini adalah informasi yang berlebihan, algoritma mengarah ke representasi ini, dan menghilangkan tanda-tanda negatif akan menelan biaya beberapa byte.)Pertama-tama kita harus mengimplementasikan fungsi yang mengambil daftar dan sekumpulan
n
tempat-potong dan mengembalikan daftarn+1
sub -daftar yang diperoleh dengan memotong daftar input din
tempat-tempat tersebut; operator infiks biner±
digunakan untuk tujuan ini, dan didefinisikan secara rekursif melaluil_±c_:=Append[-#±Most@c,#2]&@@l~TakeDrop~Last@c;l_±{}:={l};
. Karena tanda negatif tepat setelahnyaAppend
, hasilnya adalah bahwa sublisensi secara bergantian melakukan dan tidak memiliki tanda-tanda negatif yang melekat pada setiap token.Kemudian kami membuat semua set tempat cut yang panjangnya paling banyak jumlah jenis permata, menggunakan
Range@#2~Subsets~#3
, dan menggunakani=#;(i±#)&/@
untuk menerapkan±
operator (dengan daftar input perhiasan) untuk masing-masing set tempat cut ini pada gilirannya.Akhirnya,
SelectFirst[...,Tr[Tr/@#]==0&]&
pilih yang pertama dari pembagian kalung yang adil. Ia melakukannya dengan menambahkan semua elemen dalam semua sublists; Mathematica cukup bijaksana untuk membatalkan salinan positif dan negatif dari setiap token dengan cara yang jelas.sumber
Pyth, 16 byte
Cobalah online: Demonstrasi atau Test Suite
Penjelasan:
sumber
05AB1E , 14 byte
Cobalah secara online atau verifikasi semua kasus uji .
Penjelasan:
sumber