帮助我的多节律


17

我是一名音乐家,一生中需要更多的节奏!

当两个事件(拍手,音符,萤火虫闪烁等)以两个不同的规则间隔发生时,音乐(和自然界)中就会发生多节奏。两种事件在同一时间间隔内发生的次数不同。

如果我在同一时间间隔内用左手敲击两次,用右手敲击3次,看起来会像这样:

  ------
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作为两个单独的值吗?例如,我们可以接受两个元素的数组吗?他们的顺序怎么样,严格r遵守l吗?
Sok

@Sok作为“两个论点”的解释是可以接受的
AJFaraday

它是否需要实际打印该图,还是可以简单地将其返回?
恢复莫妮卡-notmaynard

@iamnotmaynard返回很好。
AJFaraday

Answers:


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

当不带任何参数或等于0的参数调用,它将递归构建长度为k = lcm l r 的连字符字符串G0ķ=厘米[R以尾随换行符:

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

该字符串保存在 s

G1个ñ3Xs0

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,因此它使用helper方法而不是String.repeat())。

我的最初版本使用拍子之间的间隔而不是拍子的数量。立即修复。谢谢 Kevin Cruijssen打高尔夫球1个字节。

取消高尔夫:

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

Python 2中187 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谢谢:)
TF


3

Python 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 '18

该长度应该是最小的公倍数。在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);}

我的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#交互式编译器),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();

发布

  • 1.0 - 254 bytes-初始溶液。

笔记

  • 没有

1

木炭,52字节

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

在线尝试!链接是详细版本的代码。说明:

≔θζW﹪ζη≧⁺θζ

以该第一倍数计算的投入LCM R这是整除L

ζ↙

打印LCM,它会自动输出-s 的必要行。然后移动以从右到左打印节奏。

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

将数字从LCM循环到0,并创建一个代表左右手拍子的列表数组。

Fζ⊞ι⌈ι

循环播放节拍并添加节奏。

↓Eζ⭆ι§ .λ

向下打印反转的节拍,但是由于这是一个数组,因此它们最终向左结束。

←↓RLM

打印标题。



1

Python 2,117个字节

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

在线尝试!


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有数字,我认为这时更有价值。


1

C ++(gcc),197字节

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

在线尝试!


建议++p%a+p%b而不是++p%a||p%b
ceilingcat '18
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.