Bantu saya dengan polyrhythms saya

17

Saya seorang musisi, dan saya membutuhkan lebih banyak polyrhythms dalam hidup saya!

Polyrhythm terjadi dalam musik (dan di alam) ketika dua peristiwa (tepukan, catatan, kunang-kunang berkedip dll.) Terjadi pada dua interval reguler yang berbeda. Dua jenis peristiwa terjadi beberapa kali dalam interval yang sama.

Jika saya mengetuk dengan tangan kiri saya dua kali, dan dengan tangan kanan saya 3 kali, dalam ruang waktu yang sama, tampilannya sedikit seperti ini:

  ------
R . . .
L .  .  

Tanda hubung di bagian atas menunjukkan panjang pola polimmik, yang merupakan kelipatan umum terendah atau 2 dan 3. Ini dapat dipahami sebagai titik di mana pola berulang.

Ada juga 'metaritme', yang merupakan pola yang dihasilkan ketika kedua tangan mengetuk:

  ------
R . . .
L .  .  
M . ...

Ini adalah polyrhythm yang sederhana, dan sangat umum, dengan rasio 3: 2.

Katakan saja saya tidak ingin melakukan polyrhythm sederhana yang dapat saya kerjakan di kepala saya, jadi saya perlu sesuatu untuk menyelesaikannya untuk saya. Saya bisa melakukannya dalam bentuk panjang di atas kertas, atau ...


Aturan:

  • Tulis beberapa kode untuk menghasilkan dan menampilkan diagram polyrhythm, seperti dijelaskan di atas.
  • Bahasa lama apa saja, cobalah untuk byte paling sedikit.
  • Kode Anda mengambil dua argumen:
    • Jumlah keran dengan tangan kiri (bilangan bulat positif)
    • Jumlah keran dengan tangan kanan (bilangan bulat positif)
  • Ini akan menentukan panjangnya, yang merupakan kelipatan umum terendah untuk kedua argumen.
  • Baris teratas akan terdiri dari dua karakter spasi putih diikuti oleh tanda hubung menampilkan panjang (panjang * '-')
  • Baris kedua dan ketiga akan menunjukkan pola untuk tangan kanan dan kiri:
    • Ini akan mulai dengan R atau L, menunjukkan tangan yang mana, diikuti oleh spasi.
    • Interval untuk tangan itu adalah panjang dibagi dengan argumennya.
    • Ketukan akan dimulai pada karakter ketiga, dilambangkan dengan karakter apa pun yang Anda pilih. Mulai saat itu akan menampilkan karakter 'interval' karakter yang sama terpisah.
    • Tidak akan lebih panjang dari garis panjang.
  • Baris keempat adalah metaritme:
    • Ini akan mulai dengan huruf besar M, diikuti oleh spasi.
    • Dari karakter ketiga dan seterusnya, itu akan menampilkan karakter (karakter apa pun yang Anda pilih) di setiap posisi di mana ada ketukan di kanan atau di tangan kiri.
  • Trailing whitespace tidak relevan.

Kasus uji:

r = 3, l = 2

  ------
R . . .
L .  .  
M . ...

r = 4, l = 3

  ------------
R .  .  .  .    
L .   .   .    
M .  .. . ..

r = 4, l = 5

  --------------------
R .    .    .    .                     
L .   .   .   .   .      
M .   ..  . . .  ..

r = 4, l = 7

  ----------------------------
R .      .      .      .      
L .   .   .   .   .   .   .   
M .   .  ..   . . .   ..  .

r = 4, l = 8

  --------
R . . . . 
L ........
M ........

Selamat bermain golf!

AJFaraday
sumber
Kasing uji Anda menyertakan banyak spasi tambahan, dapatkah kami menghilangkannya / menambahkan lebih banyak?
wastl
Apakah kita harus menerima rdan lsebagai dua nilai yang terpisah? Bisakah kita menerima array dua elemen saja, misalnya? Bagaimana dengan urutan mereka, apakah itu rdiikuti dengan ketat l?
Sok
@ Sok Itu bisa diterima sebagai interpretasi dari 'dua argumen'
AJFaraday
Apakah itu perlu benar-benar mencetak diagram, atau dapatkah hanya mengembalikannya?
Pasang kembali Monica - notmaynard
@iamnotmaynard kembali baik-baik saja.
AJFaraday

Jawaban:

6

JavaScript (ES6), 131 byte

Output 0sebagai karakter tap .

r=>l=>`  ${g=n=>n?s.replace(/./g,(_,x)=>[,a=x%(k/r),x%=k/l,a*x][n]&&' '):++k%l|k%r?'-'+g():`-
`,s=g(k=0)}R ${g(1)}L ${g(2)}M `+g(3)

Cobalah online!

Bagaimana?

g()

g()0k=lcm(l,r)

g = _ => ++k % l | k % r ? '-' + g() : `-\n`

s

g()1n3xs0

g = n => s.replace(/./g, (_, x) => [, a = x % (k / r), x %= k / l, a * x][n] && ' ')
Arnauld
sumber
4

Java 11, 226 234 233 219 byte

String h(int r,int l,int m){var s="";for(;m>0;)s+=m%r*(m--%l)<1?'.':32;return s;}

r->l->{int a=r,b=l,m;for(;b>0;b=a%b,a=m)m=b;m=r*l/a;return"  "+repeat("-",m)+"\nR "+h(m/r,m+1,m)+"\nL "+h(m/l,m+1,m)+"\nM "+h(m/r,m/l,m);}

Agak panjang; sayang sekali Java tidak memiliki lcm()fungsi. Coba online di sini (TIO belum memiliki Java 11, jadi ini menggunakan metode pembantu bukan String.repeat()).

Versi awal saya mengambil interval antara ketukan alih-alih jumlah ketukan. Diperbaiki sekarang Terima kasih kepada Kevin Cruijssen untuk bermain golf 1 byte.

Tidak Disatukan:

String h(int r, int l, int m) { // helper function returning a line of metarhythm; parameters are: tap interval (right hand), tap interval (left hand), length
    var s = ""; // start with an empty String
    for(; m > 0; ) // repeat until the length is reached
        s += m % r * (m-- % l) < 1 ? '.' : 32; // if at least one of the hands taps, add a dot, otherwise add a space (ASCII code 32 is ' ')
    return s; // return the constructed line
}

r -> l -> { // lambda taking two integers in currying syntax and returning a String
    int a = r, b = l, m; // duplicate the inputs
    for(; b > 0; b = a % b, a = m) // calculate the GCD of r,l using Euclid's algorithm:
        m=b; // swap and replace one of the inputs by the remainder of their division; stop once it hits zero
    m = r * l / a; // calculate the length: LCM of r,l using a=GCD(r,l)
    return // build and return the output:
    "  " + "-".repeat(m) // first line, m dashes preceded by two spaces
    + "\nR " + h(m / r, m + 1, m) // second line, create the right-hand rhythm; by setting l = m + 1 for a metarhythm, we ensure there will be no left-hand taps
    + "\nL " + h(m / l, m + 1, m) // third line, create the left-hand rhythm the same way; also note that we pass the tap interval instead of the number of taps
    + "\nM " + h(m / r, m / l, m); // fourth line, create  the actual metarhythm
}
Ketidakseimbangan
sumber
Tidak banyak, tetapi -1 byte dengan mengubah ?".":" "ke ?'.':32.
Kevin Cruijssen
@KevinCruijssen Setiap byte penting :-) Terima kasih!
OOBalance
4

Python 2 , 187 185 183 174 166 156 148 147 145 byte

Digunakan -sebagai karakter ketuk

a,b=r,l=input()
while b:a,b=b,a%b
w=r*l/a
for x,y,z in zip(' RLM',(w,r,l,r),(w,r,l,l)):print x,''.join('- '[i%(w/y)!=0<i%(w/z)]for i in range(w))

Cobalah online!


Diselamatkan:

  • -2 byte, terima kasih kepada Jonathan Frech
TFeld
sumber
[i%(w/y)and i%(w/z)>0]bisa jadi [i%(w/y)!=0<i%(w/z)].
Jonathan Frech
@JonathanFrech Terima kasih :)
TFeld
3

Perl 6 , 85 80 78 byte

-2 byte terima kasih kepada Jo King.

'  'R L M»Z~'-'x($!=[lcm] @_),|(@_.=map:{' '~(0~' 'x$!/$_-1)x$_}),[~|] @_}

Cobalah online!

Mengembalikan daftar empat baris.

nwellnhof
sumber
3

Python 2 , 185 228 223 234 249 byte

def f(r,l):
     c='.';d=' ';M,R,L=[r*l*[d]for _ in d*3]
     for i in range(r*l):
      if i%r<1:L[i]=M[i]=c
      if i%l<1:R[i]=M[i]=c
      if r<R.count(c)and l<L.count(c):R[i]=L[i]=M[i]=d;break
     print d,i*'-','\nR',''.join(R),'\nL',''.join(L),'\nM',''.join(M)

Cobalah online!

sonrad10
sumber
Saya baru saja menyalin-menempelkan ini ke TIO dan mengambil format yang dihasilkan dari sana. Ternyata itu dilakukan dalam byte lebih sedikit dari yang Anda pikirkan;)
AJFaraday
@Feld r=4, l=8bekerja dengan baik untuk saya
sonrad10
Panjangnya seharusnya merupakan kelipatan umum terendah. Dengan r = 4, l = 8, itu seharusnya 8, tetapi tampaknya output Anda jauh lebih lama (8 * 4?).
OOBalance
1
Itu masih tidak memberikan LCM; misalnya untuk 15,25, itu memberi 375, tetapi seharusnya 75.
OOBalance
1
Saya yakin cek terakhir bisa diganti oleh i%r+i%l+0**i<1. Selain itu, Anda dapat menghapus versi kode sebelumnya, karena kode tersebut akan disimpan dalam riwayat edit siapa pun yang ingin melihatnya
Jo King
2

Jelly , 32 byte

æl/Ḷ%Ɱµa/ṭ=0ị⁾. Z”-;ⱮZ“ RLM”żK€Y

Cobalah online!

Mengambil input sebagai daftar [L,R].

æl/       Get LCM of this list.
   Ḷ      Range [0..LCM-1]
    %Ɱ    Modulo by-each-right (implicitly the input, [L,R]):
           [[0%L ... (LCM-1)%L], [0%R ... (LCM-1)%R]]
µ         Take this pair of lists, and:
 a/ṭ      Append their pairwise AND to the pair.
    =0    Is zero? Now we have a result like:
              [[1 0 0 1 0 0 1 0 0 1 0 0 1 0 0]
               [1 0 0 0 0 1 0 0 0 0 1 0 0 0 0]
               [1 0 0 1 0 1 1 0 0 1 1 0 1 0 0]]

ị⁾.       Convert this into dots and spaces.
Z”-;ⱮZ    Transpose, prepend a dash to each, transpose. Now we have
              ['---------------'
               '.  .  .  .  .  '
               '.    .    .    '
               '.  . ..  .. .  ']

“ RLM”ż       zip(' RLM', this)
       K€     Join each by spaces.
         Y    Join the whole thing by newlines.
Lynn
sumber
1

C (gcc), 204 byte

p(s){printf(s);}
g(a,b){a=b?g(b,a%b):a;}
h(r,l,m){for(;m;)p(m%r*(m--%l)?" ":".");}
f(r,l,m,i){m=r*l/g(r,l);p("  ");for(i=m;i-->0;)p("-");p("\nR ");h(m/r,m+1,m);p("\nL ");h(m/l,m+1,m);p("\nM ");h(m/r,m/l,m);}

Port jawaban Java saya . Panggil dengan f(number_of_right_hand_taps, number_of_left_hand_taps). Cobalah online di sini .

Ketidakseimbangan
sumber
200 byte
ceilingcat
1

Pyth, 53 byte

j.b+NYc"  L R M "2++*\-J/*FQiFQKm*d+N*\ t/JdQsmeSd.TK

Pasti kamar untuk golf. Akan melakukannya ketika saya punya waktu.
Coba di sini

Penjelasan

j.b+NYc"  L R M "2++*\-J/*FQiFQKm*d+N*\ t/JdQsmeSd.TK
                       J/*FQiFQ                        Get the LCM.
                    *\-                                Take that many '-'s.
                               Km*d+N*\ t/dJQ          Fill in the taps.
                                             smeSd.TK  Get the metarhythm.
                  ++                                   Append them all.
      c"  L R M "2                                     Get the prefixes.
 .b+NY                                                 Prepend the prefixes.
j                                                      Join with newlines.

sumber
1

C # (Visual C # Interactive Compiler) , 254 byte


Golf Cobalah secara online!

(r,l)=>{int s=l>r?l:r,S=s;while(S%l>0|S%r>0)S+=s;string q(int a){return"".PadRight(S/a,'.').Replace(".",".".PadRight(a,' '));}string R=q(S/r),L=q(S/l),M="";s=S;while(S-->0)M=(R[S]+L[S]>64?".":" ")+M;return"  ".PadRight(s+2,'-')+$"\nR {R}\nL {L}\nM {M}";}

Tidak disatukan

( r, l ) => {
    int
        s = l > r ? l : r,
        S = s;

    while( S % l > 0 | S % r > 0 )
        S += s;

    string q( int a ) {
        return "".PadRight( S / a, '.' ).Replace( ".", ".".PadRight( a, ' ' ) );
    }

    string
        R = q( S / r ),
        L = q( S / l ),
        M = "";

    s = S;

    while( S-- > 0 )
        M = ( R[ S ] + L[ S ] > 64 ? "." : " " ) + M;

    return "  ".PadRight( s + 2, '-') + $"\nR {R}\nL {L}\nM {M}";
}

Kode lengkap

Func<Int32, Int32, String> f = ( r, l ) => {
    int
        s = l > r ? l : r,
        S = s;

    while( S % l > 0 | S % r > 0 )
        S += s;

    string q( int a ) {
        return "".PadRight( S / a, '.' ).Replace( ".", ".".PadRight( a, ' ' ) );
    }

    string
        R = q( S / r ),
        L = q( S / l ),
        M = "";

    s = S;

    while( S-- > 0 )
        M = ( R[ S ] + L[ S ] > 64 ? "." : " " ) + M;

    return "  ".PadRight( s + 2, '-') + $"\nR {R}\nL {L}\nM {M}";
};

Int32[][]
    testCases = new Int32[][] {
        new []{ 3, 2 },
        new []{ 4, 3 },
        new []{ 4, 5 },
        new []{ 4, 7 },
        new []{ 4, 8 },
    };

foreach( Int32[] testCase in testCases ) {
    Console.Write( $" Input: R: {testCase[0]}, L: {testCase[1]}\nOutput:\n{f(testCase[0], testCase[1])}" );
    Console.WriteLine("\n");
}

Console.ReadLine();

Rilis

  • v1.0 - 254 bytes- Solusi awal.

Catatan

  • Tidak ada
auhmaan
sumber
1

Arang , 52 byte

≔θζW﹪ζη≧⁺θζζ↙≔⮌Eζ⟦¬﹪×ιθζ¬﹪×ιηζ⟧ζFζ⊞ι⌈ι↓Eζ⭆ι§ .λ←↓RLM

Cobalah online!Tautan adalah untuk mengucapkan versi kode. Penjelasan:

≔θζW﹪ζη≧⁺θζ

Hitung LCM dari input dengan mengambil kelipatan pertama Ryang habis dibagiL .

ζ↙

Cetak LCM, yang secara otomatis menampilkan baris yang diperlukan - s yang . Kemudian pindah untuk mencetak ritme dari kanan ke kiri.

≔⮌Eζ⟦¬﹪×ιθζ¬﹪×ιηζ⟧ζ

Lingkarkan angka-angka dari LCM ke 0 dan buat array daftar yang mewakili ketukan tangan kanan dan kiri.

Fζ⊞ι⌈ι

Lingkari ketukan dan tambahkan metarhythm.

↓Eζ⭆ι§ .λ

Cetak ketukan terbalik ke bawah, tetapi karena ini adalah array, mereka berakhir ke kiri.

←↓RLM

Cetak tajuk.

Neil
sumber
1

Ruby , 130 126 byte

->*a{puts"  "+?-*s=a[0].lcm(a[1])
r,l=a.map!{|e|(?.+' '*(s/e-1))*e}
[?R,?L,?M].zip(a<<r.gsub(/ /){l[$`.size]}){|e|puts e*" "}}

Cobalah online!

Pasang kembali Monica - notmaynard
sumber
1

Python 2 , 117 byte

a,b=input();n=a
while n%b:n+=a
for i in-1,1,2,3:print'_RLM '[i],''.join(' -'[i%2>>m*a%n|i/2>>m*b%n]for m in range(n))

Cobalah online!

Tidak
sumber
1

Pyth, 49 byte

J/*FQiFQjC+c2" RLM    "ms@L" -"!M++0d*Fdm%Ld/LJQJ

Mengharapkan input dalam formulir [r,l]. Penggunaan -untuk menampilkan ketukan. Cobalah online di sini , atau verifikasi semua uji sekaligus di sini .

J/*FQiFQjC+c2" RLM    "ms@L" -"!M++0d*Fdm%Ld/LJQJ   Implicit: Q=eval(input())
 /*FQiFQ                                            Compute LCM: (a*b)/(GCD(a,b))
J                                                   Store in J
                                        m       J   Map d in [0-LCM) using:
                                            /LJQ      Get number of beats between taps for each hand
                                         %Ld          Take d mod each of the above
                                                    This gives a pair for each beat, with 0 indicating a tap
                       m                            Map d in the above using:
                                     *Fd              Multiply each pair (effecively an AND)
                                 ++0d                 Prepend 0 and the original pair
                               !M                     NOT each element
                        s@L" -"                       Map [false, true] to [' ', '-'], concatenate strings
                                                    This gives each column of the output
           c2" RLM    "                             [' RLM','    ']
          +                                         Prepend the above to the rest of the output
         C                                          Transpose
        j                                           Join on newlines, implicit print
Sok
sumber
1

R , 161 149 146 byte

function(a,b){l=numbers::LCM(a,b)
d=c(0,' ')
cat('  ',strrep('-',l),'\nR ',d[(x<-l:1%%a>0)+1],'\nL ',d[(y<-l:1%%b>0)+1],'\nM ',d[(x&y)+1],sep='')}

Cobalah online!

Saya pasti merasa ada ruang untuk perbaikan di sini, tetapi saya mencoba beberapa pendekatan berbeda dan ini adalah satu-satunya yang macet. Menyingkirkan definisi fungsi internal akan membuat saya cukup bahagia, dan saya mencoba banyak restrukturisasi kucing () untuk mewujudkannya. Nevermind, begitu saya memposting saya menyadari apa yang bisa saya lakukan. Masih pasti beberapa penghematan efisiensi dapat ditemukan.

Ada fungsi LCM lain di perpustakaan dengan nama yang lebih pendek, tetapi TIO memiliki angka dan saya menganggapnya lebih berharga saat ini.

Kriminal kriminal
sumber
1

C ++ (gcc) , 197 byte

int f(int a,int b){std::string t="  ",l="\nL ",r="\nR ",m="\nM ";int c=-1,o,p=0;for(;++p%a||p%b;);for(;o=++c<p;t+="-")l+=a*c%p&&++o?" ":".",r+=b*c%p&&++o?" ":".",m+=o-3?".":" ";std::cout<<t+l+r+m;}

Cobalah online!

Annyo
sumber
Sarankan ++p%a+p%balih-alih++p%a||p%b
ceilingcat