ユークリッドリズムの生成


8

ユークリッドアルゴリズムが従来の音楽リズムを生成できることをご存知ですか?これと似ていますが、少し異なるアルゴリズムを説明することで、これがどのように機能するかを説明します。

正の整数n、ビートの総数、正の整数k、鳴らされるビートの数(ノート)を選択します。リズムはnビットのシーケンスと考えることができますk。ビットは1です。アルゴリズムの考え方は、1を0の間でできるだけ均等に分散することです。

たとえば、n = 8およびk = 5を使用すると、5つの1と3つの0から始まり、それぞれが独自のシーケンスになります。

[1] [1] [1] [1] [1] [0] [0] [0]

どの時点でも、2種類のシーケンスがあります。最初のシーケンスは「コア」シーケンスで、最後のシーケンスは「残りの」シーケンスです。ここで、コアは[1]s、残りは[0]sです。残りのシーケンスが複数ある限り、それらをコアに分散します。

[1 0] [1 0] [1 0] [1] [1]

コアは[1 0]で残りは[1]であり、再び配布します。

[1 0 1] [1 0 1] [1 0]

現在のコアは[1 0 1]、残りは[1 0]です。残りのシーケンスが1つしかないため、停止して文字列を取得します

10110110

これは、4回繰り返されたように聞こえます。

n = 16andを使用した別の例を次に示し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

最後のステップで、2つのコアシーケンスと残りのシーケンスなしで終了したことに注意してください。ここでは、2回繰り返されます。

入力

STDIN、コマンドラインなどから読み取る関数または完全なプログラムを書くことができます。入力は2つの正の整数nとk <= nになります。これらはどちらの順序でもかまいません。

出力

あなたの仕事は、生成されたリズムをn文字の長い文字列として出力することです。ノートと休符を表すために、2つの異なる印刷可能なASCII文字(0x20〜0x7E)を選択できます。

テストケース

以下のテストケースはx、音符を表すために使用し、.休符を表すためにを使用します。入力は次の順序nで与えられ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.

得点

これはコードゴルフなので、最小バイトのコードが勝ちます。

回答:


5

CJam、37 34 30 27 24バイト

user23013によって保存された3バイト。

q~,f>{_(a-W<}{e`:a:e~z}w

これは、k最初、n2番目の入力を受け取ります。それは使用しています1して0、それぞれ、メモや休符を示すために。

ここで試してください。または、ここにテストハーネスがあります(入力順序を入れ替える)指定されたテストケースの全てを実行し、また使用に出力を再フォーマットxし、.基準溶液と容易に比較するために。(テストハーネスの入力に表示される結果は、コードを実行する前に破棄されます。プログラムに影響を与えずに安全に削除できます。)

説明

q~                       e# Read and eval the input, dumping k and n on the stack.
  ,                      e# Create a range [0 .. n-1]
   f>                    e# For each of them, check if it's less than k.
                         e# This gives k 1s and n-k 0s.
     {      }{        }w e# While the first block yields a truthy result, execute
                         e# the second block.
      _                  e# Duplicate the array.
       (a-               e# Remove all instances of core sequences.
          W<             e# Remove one remainder sequence if there is one. This
                         e# gives an empty array (falsy) whenever there are less
                         e# than two remainder sequences.
              e`         e# Run-length encode. I.e. this turns an array into a list
                         e# of pairs of run-length and element.
                :a:e~    e# Wrap each RLE pair in an array and RLD it. This
                         e# partitions the array into cores and remainders.
                     z   e# Zip the two parts, interleaving cores and remainders.

このプロセスは非常に深くネストされた配列ですが、重要な部分は、すべてのコア(およびすべての残り)は常に同じネスト構造を持っているため、それらはまだ互いに等しいということです。CJamはプログラムの最後にスタックの内容を自動的に出力し、配列区切り文字を完全に省略しているため、この構造は出力にも影響しません。


2バイトまたは3バイト短い:q~\,f>。
— jimmy23013

@ user23013ああ、それはすごいです!ありがとうございました。:)
— マーティンエンダー、2015年

3バイトの場合、入力はどちらの順序でもかまいません。
— jimmy23013

@ user23013そうそう、私はそれを忘れていました。
— マーティンエンダー

1

Haskell、125バイト

r=replicate
g z(a:b)(c:d)=g((a++c):z)b d
g z x y=(z,x++y)
f(x,y)|length y>1=f$g[]x y|1<2=concat$x++y
n#k=f(r k "x",r(n-k)".")

使用例:42 # 13-> x...x..x..x..x...x..x..x..x...x..x..x..x..。

fコアと残りのリストという2つのパラメーターを取ります。両方のリストを圧縮して(を介してg)、自分自身を再度呼び出すか、残りが短すぎる場合は停止します。メイン関数#は開始リストを作成して呼び出しますf。


1

Python、85

f=lambda n,k,a='1',b='0':n-k<2and a*k+b*(n-k)or[f(n-k,k,a+b,b),f(k,n-k,a+b,a)][2*k>n]

自然な再帰ソリューション。パラメータ(n,k,a,b)は、のコアとk aそれに続くの残りを表しますn-k b'。

への両方の再帰呼び出しfが評価され、指数関数的な数の呼び出しが発生するため、このソリューションは非効率的です。

flikeの条件付き呼び出しを圧縮してみました

f(max(n-k,k),min(n-k,k),a+b,[a,b][2*k<n])
f(*[n-k,k,k,n-k,b,a][2*k>n::2]+[a+b])

しかし、どれも短くはなりませんでした。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.