Tahukah Anda bahwa algoritma Euclidean mampu menghasilkan irama musik tradisional ? Kita akan melihat bagaimana ini bekerja dengan menggambarkan algoritma yang serupa, tetapi sedikit berbeda dengan yang ada di koran.
Pilih bilangan bulat positif n
, jumlah ketukan, dan bilangan bulat positif k
, jumlah ketukan yang dibunyikan (catatan). Kita dapat menganggap ritme sebagai urutan n
bit, k
di antaranya adalah 1s. Ide dari algoritma ini adalah untuk mendistribusikan 1s secara merata di antara 0s.
Misalnya, dengan n = 8
dan k = 5
, kita mulai dengan 5 yang dan 3 nol, masing-masing dalam urutannya sendiri:
[1] [1] [1] [1] [1] [0] [0] [0]
Pada titik mana pun kita akan memiliki dua jenis urutan - yang pada awalnya adalah urutan "inti" dan yang pada akhirnya adalah urutan "sisa". Di sini inti adalah [1]
s dan sisanya adalah [0]
s. Selama kami memiliki lebih dari satu urutan sisanya, kami mendistribusikannya di antara inti:
[1 0] [1 0] [1 0] [1] [1]
Sekarang intinya [1 0]
dan sisanya [1]
, dan kami distribusikan lagi:
[1 0 1] [1 0 1] [1 0]
Sekarang intinya adalah [1 0 1]
dan sisanya adalah [1 0]
. Karena kami hanya memiliki satu urutan sisa, kami berhenti dan mendapatkan string
10110110
Ini adalah apa yang terdengar seperti, diulang 4 kali:
Berikut contoh lain, dengan n = 16
dan k = 6
:
[1] [1] [1] [1] [1] [1] [0] [0] [0] [0] [0] [0] [0] [0] [0] [0]
[1 0] [1 0] [1 0] [1 0] [1 0] [1 0] [0] [0] [0] [0]
[1 0 0] [1 0 0] [1 0 0] [1 0 0] [1 0] [1 0]
[1 0 0 1 0] [1 0 0 1 0] [1 0 0] [1 0 0]
[1 0 0 1 0 1 0 0] [1 0 0 1 0 1 0 0]
1001010010010100
Perhatikan bagaimana kami mengakhiri pada langkah terakhir dengan dua urutan inti dan tidak ada urutan yang tersisa. Ini dia, diulang dua kali:
Memasukkan
Anda dapat menulis fungsi atau pembacaan program lengkap dari STDIN, baris perintah atau yang serupa. Input akan berupa dua bilangan bulat positif n
dan k <= n
, yang dapat Anda asumsikan dalam urutan mana pun.
Keluaran
Tugas Anda adalah menampilkan ritme yang dihasilkan sebagai n
string panjang karakter. Anda dapat memilih dua karakter ASCII yang dapat dicetak yang berbeda (0x20 hingga 0x7E) untuk mewakili catatan dan sisanya.
Uji kasus
Kasus uji berikut digunakan x
untuk mewakili catatan dan huruf .
s untuk mewakili huruf istirahat. Masukan diberikan dalam urutan n
, lalu k
.
1 1 -> x
3 2 -> xx.
5 5 -> xxxxx
8 2 -> x...x...
8 5 -> x.xx.xx.
8 7 -> xxxxxxx.
10 1 -> x.........
11 5 -> x.x.x.x.x..
12 7 -> x.xx.x.xx.x.
16 6 -> x..x.x..x..x.x..
34 21 -> x.xx.x.xx.xx.x.xx.x.xx.xx.x.xx.x.x
42 13 -> x...x..x..x..x...x..x..x..x...x..x..x..x..
42 18 -> x..x.x.x..x.x.x..x.x.x..x.x.x..x.x.x..x.x.
Mencetak gol
Ini adalah kode-golf, sehingga kode dalam byte paling sedikit menang.
q~\,f>
.Haskell, 125 byte
Contoh penggunaan:
42 # 13
->x...x..x..x..x...x..x..x..x...x..x..x..x..
.f
mengambil dua parameter: inti dan daftar sisa. Entah ritsleting kedua daftar (viag
) dan menyebut dirinya lagi atau berhenti jika sisanya terlalu pendek. Fungsi utama#
membuat daftar awal dan panggilanf
.sumber
Python, 85
Solusi rekursif alami. Parameter
(n,k,a,b)
mewakili inti dari yangk
a
diikuti oleh sisa darin-k
b'
.Solusi ini tidak efisien karena kedua panggilan rekursif
f
dievaluasi, menyebabkan jumlah panggilan yang eksponensial.Saya mencoba untuk mengompresi permintaan bersyarat
f
liketapi ternyata tidak ada yang lebih pendek.
sumber