내 리듬을 도와주세요


17

나는 음악가이고 내 인생에 더 많은 리듬이 필요합니다!

두 가지 이벤트 (박수, 음표, 반딧불이 깜박임 등)가 서로 다른 두 간격으로 발생하는 경우 음악 및 자연에서 폴리 리듬이 발생합니다. 두 종류의 이벤트는 같은 간격으로 다른 횟수로 발생합니다.

같은 시간 간격으로 왼손으로 두 번, 오른손으로 세 번 두드리면 다음과 같이 보입니다.

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

상단의 하이픈은 다항식 패턴의 길이를 나타내며, 이는 가장 낮은 공배수 또는 2와 3입니다. 이는 패턴이 반복되는 지점으로 이해 될 수 있습니다.

'메타 리듬'도 있는데, 이는 양손을 두 드릴 때 생성되는 패턴입니다.

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

이것은 3 : 2 비율의 단순하고 매우 일반적인 폴리 리듬입니다.

머리에서 운동 할 수있는 간단한 폴리 리듬을하고 싶지 않다고하자. 나는 종이에 긴 형식을 만들 수도 있고 ...


규칙 :

  • 위에서 설명한대로 폴리 리듬 다이어그램을 생성하고 표시하는 코드를 작성하십시오.
  • 오래된 언어라면 가장 적은 바이트를 사용하십시오.
  • 코드에는 두 가지 주장이 있습니다.
    • 왼손으로 탭 수 (양의 정수)
    • 오른손 탭 수 (양의 정수)
  • 두 인수에 대해 가장 낮은 공배수 인 길이를 계산합니다.
  • 맨 위 줄은 두 개의 공백 문자와 길이 (길이 * '-')를 표시하는 하이픈으로 구성됩니다.
  • 두 번째와 세 번째 줄은 오른손과 왼손의 패턴을 보여줍니다.
    • 그것은 R 또는 L로 시작하고, 어느 손인지, 공백이 오는 것을 나타냅니다.
    • 손 간격은 길이를 인수로 나눈 값입니다.
    • 탭은 선택한 문자로 표시되는 세 번째 문자에서 시작됩니다. 그때부터 동일한 문자 '간격'문자를 구분하여 표시합니다.
    • 길이 줄보다 길지 않습니다.
  • 네 번째 줄은 메타 리듬입니다.
    • 대문자 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 ........

행복한 골프!


테스트 사례에는 후행 공백이 많이 포함되어 있습니다. 생략하거나 더 추가 할 수 있습니까?
wastl

우리는 받아 들여야 함 rl두 개의 값으로? 예를 들어, 2 요소 배열을 대신 사용할 수 있습니까? 그 엄격 어떻게 그 순서에 대해,되어 r다음에 l?
Sok

@Sok '두 가지 주장'의 해석으로 받아 들여집니다
AJFaraday

실제로 다이어그램을 인쇄해야합니까, 아니면 단순히 반환 할 수 있습니까?
Monica Monica 복원-notmaynard

@iamnotmaynard 반환은 괜찮습니다.
AJFaraday

답변:


6

자바 스크립트 (ES6), 131 바이트

문자 0로 출력 합니다.

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)

온라인으로 사용해보십시오!

어떻게?

우리는 두 가지 다른 목적으로 동일한 도우미 함수 를 사용합니다.()

가 인수없이 또는 0 과 같은 인수없이 호출 되면 후행 줄 바꿈을 사용하여 길이가 k = lcm ( l , r ) 인 하이픈 문자열을 재귀 적으로 작성합니다 .()0케이=lcm(,아르 자형)

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

이 문자열은 저장됩니다 .에스

()1엑스에스0

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

4

자바 11 226 234 233 219 바이트

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

긴 종류; 너무 나쁜 Java에는 lcm()기능 이 없습니다 . 여기에서 온라인으로 시도 하십시오 (TIO에는 아직 Java 11이 없으므로이 대신 도우미 메소드를 사용합니다 String.repeat()).

내 초기 버전은 탭 수가 아닌 탭 간 간격을 사용했습니다. 지금 수정했습니다. 1 바이트 골프 를 한 Kevin Cruijssen 에게 감사합니다 .

언 골프 드 :

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
}

로 변경 ?".":" "하여 많지는 않지만 -1 바이트 ?'.':32입니다.
Kevin Cruijssen

@KevinCruijssen 모든 바이트 수 :-) 감사합니다!
OOBalance



3

파이썬 (2) , 185 (228) 223 234 249 바이트

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)

온라인으로 사용해보십시오!


방금 이것을 TIO에 복사하여 붙여 넣고 생성 된 형식을 가져 왔습니다. 생각보다 적은 바이트 수로 완료되었습니다.)
AJFaraday

@Tfeld은 r=4, l=8나를 위해 잘 작동합니다
sonrad10

길이는 가장 낮은 공배수입니다. r = 4, l = 8을 사용하면 8이어야하지만 출력이 훨씬 길어 보입니다 (8 * 4?).
OOBalance

1
그래도 LCM은 제공하지 않습니다. 예를 들어 15,25, 그것은 제공 375하지만, 그래야합니다 75.
OOBalance

1
나는 마지막 수표를로 대체 할 수 있다고 생각합니다 i%r+i%l+0**i<1. 또한 이전 버전의 코드는 제거하고자하는 사람의 편집 기록에 유지되므로 이전 버전의 코드를 제거 할 수 있습니다.
Jo King

2

젤리 , 32 바이트

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

온라인으로 사용해보십시오!

입력을 목록으로 취합니다 [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 바이트

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

내 자바 답변 포트 . 로 전화하십시오 f(number_of_right_hand_taps, number_of_left_hand_taps). 여기에서 온라인으로 사용해보십시오 .



1

Pyth, 53 바이트

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

확실히 골프장. 내가 시간이 있으면 그렇게 할 것입니다.
여기 사용해보십시오

설명

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 # (Visual C # 대화식 컴파일러) , 254 바이트


골프 온라인으로 해보십시오!

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

언 골프

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

전체 코드

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

자료

  • V1.0 - 254 bytes- 초기 솔루션입니다.

노트

  • 없음

1

, 52 바이트

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

온라인으로 사용해보십시오! 링크는 자세한 버전의 코드입니다. 설명:

≔θζW﹪ζη≧⁺θζ

R로 나눌 수 있는 첫 번째 배수를 취하여 입력의 LCM을 계산하십시오 L.

ζ↙

필요한 행을 자동으로 출력하는 LCM을 인쇄하십시오 -. 그런 다음 이동하여 리듬을 오른쪽에서 왼쪽으로 인쇄하십시오.

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

LCM에서 0까지 숫자를 반복하고 오른손과 왼손의 비트를 나타내는 목록 배열을 만듭니다.

Fζ⊞ι⌈ι

비트를 반복하고 메타 리듬을 추가하십시오.

↓Eζ⭆ι§ .λ

반전 된 비트는 아래쪽으로 인쇄하지만 이것이 배열이므로 왼쪽으로 끝납니다.

←↓RLM

헤더를 인쇄하십시오.




1

Pyth, 49 바이트

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

형식의 입력이 필요합니다 [r,l]. -탭을 표시하는 데 사용 합니다. 여기 에서 온라인으로 시도 하거나 모든 테스트 사례를 한 번에 확인 하십시오 .

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 바이트

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

온라인으로 사용해보십시오!

나는 여기에 개선의 여지가 있다고 생각하지만 몇 가지 다른 접근법을 시도했지만 이것이 유일한 방법입니다. 내부 함수 정의를 제거하면 꽤 행복해질 것입니다 .cat ()의 많은 구조 변경을 시도했습니다. 내가 게시하자마자 나는 내가 할 수있는 것을 깨달았다. 여전히 몇 가지 효율성 절감 효과가 있습니다.

이름이 짧은 라이브러리에는 다른 LCM 함수가 있지만 TIO에는 숫자가 있으며이 시점에서 더 가치가 있다고 생각했습니다.


당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.