Giúp tôi với đa âm điệu của tôi


17

Tôi là một nhạc sĩ, và tôi cần nhiều nhịp điệu hơn trong cuộc sống của mình!

Một đa nhịp xảy ra trong âm nhạc (và trong tự nhiên) khi hai sự kiện (vỗ tay, ghi chú, đom đóm nhấp nháy, v.v.) xảy ra ở hai khoảng thời gian đều đặn khác nhau. Hai loại sự kiện xảy ra một số lần khác nhau trong cùng một khoảng thời gian.

Nếu tôi chạm bằng tay trái hai lần và bằng tay phải 3 lần, trong cùng một khoảng thời gian, nó trông hơi giống như thế này:

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

Các dấu gạch nối ở trên cùng biểu thị độ dài của mẫu đa nhịp, là bội số chung thấp nhất hoặc 2 và 3. Điều này có thể được hiểu là điểm mà mẫu lặp lại.

Ngoài ra còn có một 'nhịp tim', đó là mô hình được tạo ra khi một trong hai tay đang gõ:

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

Đây là một đa nhịp đơn giản và rất phổ biến, với tỷ lệ 3: 2.

Hãy nói rằng tôi không muốn thực hiện một chứng loạn nhịp tim đơn giản mà tôi có thể giải quyết trong đầu, vì vậy tôi cần một cái gì đó để giải quyết nó cho tôi. Tôi có thể làm nó ở dạng dài trên giấy, hoặc ...


Quy tắc:

  • Viết một số mã để tạo và hiển thị sơ đồ đa nhịp, như được mô tả ở trên.
  • Bất kỳ ngôn ngữ cũ, hãy thử cho ít byte nhất.
  • Mã của bạn có hai đối số:
    • Số lượng vòi bằng tay trái (số nguyên dương)
    • Số lượng vòi bằng tay phải (số nguyên dương)
  • Nó sẽ tính ra độ dài, là bội số chung thấp nhất cho hai đối số.
  • Dòng trên cùng sẽ bao gồm hai ký tự khoảng trắng theo sau là dấu gạch nối hiển thị độ dài (chiều dài * '-')
  • Dòng thứ hai và thứ ba sẽ hiển thị mẫu cho tay phải và tay trái:
    • Nó sẽ bắt đầu bằng R hoặc L, biểu thị đó là tay nào, theo sau là khoảng trắng.
    • Khoảng thời gian cho bàn tay đó là độ dài chia cho đối số của nó.
    • Các vòi sẽ bắt đầu ở ký tự thứ ba, được biểu thị bằng bất kỳ ký tự nào bạn chọn. Từ đó trở đi, nó sẽ hiển thị cùng một ký tự 'khoảng' ký tự.
    • Nó sẽ không dài hơn dòng chiều dài.
  • Dòng thứ tư là nhịp tim:
    • Nó sẽ bắt đầu bằng chữ M viết hoa, theo sau là khoảng trắng.
    • Từ ký tự thứ ba trở đi, nó sẽ hiển thị một ký tự (bất kỳ ký tự nào bạn chọn) ở mọi vị trí có chạm vào tay phải hoặc tay trái.
  • Trailing khoảng trắng là không liên quan.

Các trường hợp thử nghiệm:

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 ........

Chúc bạn chơi golf vui vẻ!


Các trường hợp thử nghiệm của bạn bao gồm rất nhiều khoảng trắng ở cuối, chúng ta có thể bỏ qua chúng / thêm nữa không?
lãng phí

Chúng ta có phải chấp nhận rlnhư hai giá trị riêng biệt không? Thay vào đó, chúng ta có thể chấp nhận một mảng hai yếu tố không? Làm thế nào về thứ tự của họ, được rằng Nghiêm rtiếp theo l?
Sok

@Sok Điều đó được chấp nhận như một cách giải thích cho 'hai đối số'
AJFaraday

Có cần phải thực sự in sơ đồ ra, hoặc đơn giản là có thể trả lại nó?
Tái lập lại Monica - notmaynard

@iamnotmaynard trở lại là tốt.
AJFaraday

Câu trả lời:


6

JavaScript (ES6), 131 byte

Đầu ra 0là ký tự vòi .

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)

Hãy thử trực tuyến!

Làm sao?

Chúng tôi sử dụng cùng một hàm trợ giúp cho hai mục đích khác nhau.g()

Khi được gọi không có đối số hoặc đối số bằng , nó sẽ xây dựng đệ quy chuỗi gạch nối có độ dài với một dòng cấp dữ liệu:0 k = lcm ( l , r )g()0k=lcm(l,r)

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

Chuỗi này được lưu trong .s

Khi được gọi với , nó sẽ tạo ra một chuỗi nhấn bằng cách thay thế mỗi dấu gạch nối ở vị trí trong bằng dấu cách hoặc :1 n 3 x s 0g()1n3xs0

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

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);}

Loại dài; Java quá tệ không có lcm()chức năng. Dùng thử trực tuyến tại đây (TIO chưa có Java 11, vì vậy, phương thức này sử dụng phương thức trợ giúp thay vì String.repeat()).

Phiên bản ban đầu của tôi lấy khoảng thời gian giữa các vòi thay vì số lượng vòi. Đã sửa bây giờ. Cảm ơn Kevin Cruijssen vì đã chơi golf 1 byte.

Ung dung:

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
}

Nó không nhiều, nhưng -1 byte bằng cách thay đổi ?".":" "thành ?'.':32.
Kevin Cruijssen

@KevinCruijssen Mỗi byte đều được tính :-) Cảm ơn!
OOBalance

4

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

Sử dụng -làm nhân vật nhấn

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))

Hãy thử trực tuyến!


Đã lưu:

  • -2 byte, nhờ Jonathan Frech

[i%(w/y)and i%(w/z)>0]có thể [i%(w/y)!=0<i%(w/z)].
Jonathan Frech



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)

Hãy thử trực tuyến!


Tôi vừa sao chép nó vào TIO và lấy định dạng được tạo từ đó. Hóa ra nó được thực hiện trong ít byte hơn bạn nghĩ;)
AJFaraday

@Tfeld r=4, l=8hoạt động tốt với tôi
sonrad10

Độ dài được cho là bội số chung thấp nhất. Với r = 4, l = 8, đó phải là 8, nhưng có vẻ như đầu ra của bạn dài hơn nhiều (8 * 4?).
OOBalance

1
Điều đó vẫn không cung cấp cho LCM; ví dụ cho 15,25, nó cho 375, nhưng nó nên được 75.
OOBalance

1
Tôi tin rằng kiểm tra cuối cùng có thể được thay thế bởi i%r+i%l+0**i<1. Ngoài ra, bạn có thể xóa các phiên bản mã trước đó, vì chúng sẽ được lưu giữ trong lịch sử chỉnh sửa của bất kỳ ai muốn xem chúng
Jo King

2

Thạch , 32 byte

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

Hãy thử trực tuyến!

Lấy đầu vào như một danh sách [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.

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);}

Cổng câu trả lời Java của tôi . Gọi với f(number_of_right_hand_taps, number_of_left_hand_taps). Hãy thử trực tuyến tại đây .



1

Bình thường, 53 byte

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

Chắc chắn phòng để chơi golf. Sẽ làm như vậy khi tôi có thời gian.
Hãy thử nó ở đây

Giải trình

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.

1

C # (Trình biên dịch tương tác Visual C #) , 254 byte


Chơi thử trực tuyến!

(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}";}

Bị đánh cắp

( 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}";
}

Mã đầy đủ

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();

Phát hành

  • v1.0 - 254 bytes- Giải pháp ban đầu.

Ghi chú

  • không ai

1

Than , 52 byte

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

Hãy thử trực tuyến! Liên kết là phiên bản dài dòng của mã. Giải trình:

≔θζW﹪ζη≧⁺θζ

Tính LCM của các đầu vào bằng cách lấy bội số đầu tiên Rchia hết cho L.

ζ↙

In LCM, tự động xuất ra hàng -s cần thiết . Sau đó di chuyển để in nhịp từ phải sang trái.

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

Lặp lại các số từ LCM xuống 0 và tạo một loạt các danh sách đại diện cho nhịp đập của tay phải và tay trái.

Fζ⊞ι⌈ι

Vòng qua các nhịp và thêm nhịp.

↓Eζ⭆ι§ .λ

In các nhịp đảo ngược xuống dưới, nhưng vì đây là một mảng chúng kết thúc bên trái.

←↓RLM

In tiêu đề.




1

Bình thường, 49 byte

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

Mong đợi đầu vào trong mẫu [r,l]. Sử dụng -để hiển thị vòi. Dùng thử trực tuyến tại đây hoặc xác minh tất cả các trường hợp thử nghiệm cùng một lúc tại đây .

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

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='')}

Hãy thử trực tuyến!

Tôi chắc chắn cảm thấy như có chỗ để cải thiện ở đây, nhưng tôi đã thử một vài cách tiếp cận khác nhau và đây là cách duy nhất bị mắc kẹt. Loại bỏ định nghĩa chức năng bên trong sẽ khiến tôi khá vui, và tôi đã thử một loạt các cấu trúc của con mèo () để làm cho nó xảy ra. Nevermind, ngay khi tôi đăng tôi đã nhận ra những gì tôi có thể làm. Vẫn chắc chắn một số tiết kiệm hiệu quả được tìm thấy.

Có các hàm LCM khác trong các thư viện có tên ngắn hơn, nhưng TIO có số và tôi cho rằng điều đó có giá trị hơn vào thời điểm này.


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;}

Hãy thử trực tuyến!


Đề xuất ++p%a+p%bthay vì++p%a||p%b
trần mèo
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.