ポリリズムで助けて


17

私はミュージシャンであり、人生でもっとポリリズムが必要です!

ポリリズムは、2つのイベント(拍手、音、ホタルの点滅など)が2つの異なる定期的な間隔で発生するときに、音楽(および自然)で発生します。2種類のイベントは、同じ間隔で異なる回数発生します。

同じ時間内に左手で2回、右手で3回タップすると、次のようになります。

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

上部のハイフンは、多発性パターンの長さを示します。これは、最小公倍数または2と3です。これは、パターンが繰り返されるポイントとして理解できます。

「メタリズム」もあります。これは、どちらかの手がタップされたときに生成されるパターンです。

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

これはシンプルで非常に一般的なポリリズムで、比率は3:2です。

頭の中でできるシンプルなポリリズムをしたくないので、それを解決するために何かが必要です。紙の上で長い形式でやることもできますし...


ルール:

  • 上記のように、ポリリズムダイアグラムを生成および表示するコードを記述します。
  • 古い言語は、最小限のバイトで試してください。
  • コードは2つの引数を取ります。
    • 左手でのタップ数(正の整数)
    • 右手でのタップ数(正の整数)
  • 2つの引数の最小公倍数である長さを計算します。
  • 一番上の行は、2つの空白文字とそれに続く長さ(長さ* '-')を表示するハイフンで構成されます
  • 2行目と3行目には、右手と左手のパターンが表示されます。
    • RまたはLで始まり、どちらのハンドであるかを示し、その後にスペースが続きます。
    • その手の間隔は、長さを引数で割ったものです。
    • タップは、選択した任意の文字で示される3番目の文字から始まります。それ以降は、同じ文字の「間隔」文字が離れて表示されます。
    • 長さの行より長くなることはありません。
  • 4行目はメタリズムです。
    • 大文字のMで始まり、その後にスペースが続きます。
    • 3番目のキャラクターからは、右手または左手のいずれかのタップがあるすべての位置にキャラクター(選択した任意のキャラクター)が表示されます。
  • 末尾の空白は無関係です。

テストケース:

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

2つの個別の値として受け入れなければrなりlませんか?たとえば、代わりに2要素の配列を受け入れることはできますか?それらの順序はどうですか、それは厳密にr続きlますか?
ソク

@Sok「2つの引数」の解釈として受け入れられる
-AJFaraday

図を実際に印刷する必要がありますか、それとも単に返すことができますか?
モニカの復職-notmaynard

@iamnotmaynardの復帰は問題ありません。
AJFaraday

回答:


6

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

オンラインでお試しください!

どうやって?

g()

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

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

この文字列は保存されます。s

場合と呼ばれる、それが生成するタップ位置にそれぞれハイフンを置換することによって文字列を内空間またはいずれかと: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バイト

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ます。
ケビンクルーッセン

@KevinCruijssenすべてのバイトがカウントされます:-)ありがとう!
OOBalance

4

パイソン2187 185 183 174 166 156の 148 147 145バイト

-タップ文字として使用

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

オンラインでお試しください!


保存済み:

  • -2バイト、Jonathan Frechのおかげ

[i%(w/y)and i%(w/z)>0]可能性があります[i%(w/y)!=0<i%(w/z)]
ジョナサンフレッチ

@JonathanFrechありがとう:)
TFeld


3

パイソン2185の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。誰もがそれらを見たいと、彼らはあなたの編集履歴に保存されるようにまた、あなたは、コードの以前のバージョンを削除することができます
ジョー・キングを

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

私のJava 回答のポート。で呼び出し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#Interactive Compiler)、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ます。

ζ↙

-sの必要な行を自動的に出力する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

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