7
\$\begingroup\$

This challenge is based on a video in which Andrew Huang discusses unusual time signatures...

https://www.youtube.com/watch?v=JQk-1IXRfew

In it, he advises that you can understand time signatures by dividing them into 3's and 2's. So you count to a small number a few times, instead of counting to a large number.

Here's the pattern he builds which repeats after 19 steps:

  • 5 groups of 3
  • 2 groups of 2

This is how it looks:

#..#..#..#..#..#.#.

Actually, as you'd play each beat alternatively, the accented beats move from left to right, because there's an odd number of steps. So now this pattern is:

R..L..R..L..R..L.L.
L..R..L..R..L..R.R.

If we reduce this to an algorithm, it can be described like this.

Step 1: where are the accents

  • From your number of steps, start by taking groups of 3 from the start until there's 4 or fewer steps remaining.

E.g. for a pattern 8 steps long.

8 steps - take three, 5 steps remaining

#..

5 steps - take 3, 2 steps remaining

#..#..

Once we're down to 4 steps or fewer, there's 3 possibilities.

  • 4 steps - 2 groups of 2
  • 3 steps - 1 group of 3
  • 2 steps - 1 group of 2

So from our above example:

#..#..#. 

Step 2: Which hand are the accents on

Let's assume that each individual step will be played on alternate hands, starting with the right.

So for 8 steps, the (underlying) pattern will go

rlrlrlrl

The pattern we output will only tell use which hand the accents are on. With the above example:

R..L..R.

That's fine, it's repeatable.

but

If it's an odd number, you've got the same hand for both the first and last steps, and you can't keep alternating when you repeat the pattern. Instead, the second pattern will be on the other hand. Here's the pattern on an 11 step pattern.

R..L..R..L.
L..R..L..R.

To clarify, if the pattern length is odd, we need to see the repeated, alternated pattern. If the length is even, we only need to see it once.

Hopefully that's clear enough:


The Rules

  • It's code golf, go for the shortest code.
  • Your code will accept one pattern, a positive integer higher than 1.
  • It will output some text describing a pattern diagram, as described above.
  • Any language you like.
  • Please include a link to an online interpreter.

Test cases

2

R.

3

R..
L..

4

R.R.

7

R..L.L.
L..R.R.

9

R..L..R..
L..R..L..

10

R..L..R.R.

19

R..L..R..L..R..L.L.
L..R..L..R..L..R.R.

22

R..L..R..L..R..L..R.R.
\$\endgroup\$
  • \$\begingroup\$ @Grimy I’ve read back and I see my mistake now. I’ve edited the question. \$\endgroup\$ – AJFaraday Aug 8 at 21:04
3
\$\begingroup\$

Retina 0.8.2, 66 bytes

.+
$*
1
RL
^(.+)RL\1$
$1R¶L$1
^(.+)\1$
$1
(.)(..?)(?!.\b)
$1$.2$*.

Try it online! Link includes test cases. Explanation:

.+
$*

Convert the input to unary.

1
RL

Alternate between hands.

^(.+)RL\1$
$1R¶L$1

If there are an odd number of beats then divide the output in the middle.

^(.+)\1$
$1

But if there are an even number of beats then just use one copy.

(.)(..?)(?!.\b)
$1$.2$*.

Try to match groups of three beats, but without leaving a lone beat at the end, and replace the offbeats with .s.

\$\endgroup\$
3
\$\begingroup\$

Jelly, 25 bytes

Ṗ;’m3Ṭ»¬€ḤÐe,N$ṫḂṚị“LR.”Y

A monadic Link accepting an integer greater than one which yields a list of characters.

Try it online!

How?

Ṗ;’m3Ṭ»¬€ḤÐe,N$ṫḂṚị“LR.”Y - Link: integer (>1), N     e.g. 13
Ṗ                         - popped range (N)               [1,2,3,4,5,6,7,8,9,10,11,12]
  ’                       - decrement (N)                  12
 ;                        - concatenate                    [1,2,3,4,5,6,7,8,9,10,11,12,12]
    3                     - literal three
   m                      - modulo slice                   [1,    4,    7,    10,      12]
     Ṭ                    - un-truth                       [1,0,0,1,0,0,1,0,0, 1, 0 ,1]
                          -                                     ...12th entry is a 1 ^
        €                 - for each of [1..N]:
       ¬                  -   logical NOT                  [0,0,0,0,0,0,0,0,0, 0, 0, 0, 0]
      »                   - maximum                        [1,0,0,1,0,0,1,0,0, 1, 0 ,1, 0]
          Ðe              - for entries at even indices:
         Ḥ                -   double                       [1,0,0,2,0,0,1,0,0, 2, 0, 2, 0]
              $           - last two links as a monad:
             N            -   negate                       [-1,0,0,-2,0,0,-1,0,0,-2,0,-2,0]
            ,             -   pair                         [[1,0,0,2,...],[-1,0,0,-2,...]]
                Ḃ         - modulo 2 (N)                   1
               ṫ          - tail from index                [[1,0,0,2,...],[-1,0,0,-2,...]]
                          -    ...Jelly indexing is 1-based & modular
                          -       so 0 would have resulted in [[-1,0,0,-2,...]]  
                 Ṛ        - reverse                        [[-1,0,0,-2,...],[1,0,0,2,...]]
                          -    ...which for a list of length 1 is a no-op
                   “LR.”  - literal list of characters     ['L', 'R', '.']
                  ị       - index into (1-based & modular) ["R..L..R..L.L.","L..R..L..R.R."]
                        Y - join with newlines             "R..L..R..L.L.\nL..R..L..R.R." 
                          -    ...which is just the entry for a list of length 1
\$\endgroup\$
2
\$\begingroup\$

05AB1E (legacy), 47 43 42 41 40 bytes

„RL×2äIÈ.£εÐ3äн€3sg3%i2TSǝR}£εćsg'.׫]J»

Not too happy with it..

Switched to the legacy version to save a byte (the legacy version replaces the values when using , whereas the new version leaves them in the list: Try €3 in the legacy or try €3 in the new version).
-1 byte thanks to @Grimy.

Try it online or verify all test cases.

Explanation:

„RL×          # Repeat "RL" the (implicit) input-integer amount of times
    2ä        # Divide it into 2 equal halves
      IÈ      # Check if the input-integer is even (1 if truthy; 0 if falsey)
        .£    # And remove that many items
              # Some examples of what we now have:
              #  7 → ["RLRLRLR","LRLRLRL"]
              #  9 → ["RLRLRLRLR","LRLRLRLRL"]
              #  10 → ["RLRLRLRLRL"]
ε             # Map each string in this list to:
 Ð            #  Triplicate the string
  3ä          #  Divide the string into 3 equal parts
    н         #  And only leave the first one
     €3       #  And convert each value to a 3
              #  (basically a golf from my previous ceil(length/3) amount of 3s list)
 sg           #  Swap to take the string again, and get its length
   3%i     }  #  If this length modulo-3 is exactly 1:
      2TSǝ    #   Replace the first two items (at indices 0 and 1) with 2s
          R   #   And reverse it: [3,3,3,...,2,2]
 £            #  Split the string according to this list
              #  Some examples again:
              #   ["RLRLRLR","LRLRLRL"] → [["RLR","LR","LR"],["LRL","RL","RL"]]
              #   ["RLRLRLRLR","LRLRLRLRL"] → [["RLR","LRL","RLR"],["LRL","RLR","LRL"]]
              #   ["RLRLRLRLRL"] → [["RLR","LRLR","RL","RL"]
 ε            #  Then map each inner substring to:
  ć           #   Extract head; pop and push remainder and head
   sg         #   Swap to get the remainder, and get it's length (either 1 or 2)
     '.×     '#   Create a string with that many "."
        «     #   And merge it to the extracted head
]             # After both the inner and outer map:
 J            # Join each inner list together to a single string
  »           # And then join the strings by newlines
              # (after which the result is output implicitly)
\$\endgroup\$
  • \$\begingroup\$ I made another 05AB1E answer with a very different approach (still WIP). \$\endgroup\$ – Grimy Aug 9 at 11:07
1
\$\begingroup\$

JavaScript (ES6),  84 81 78  75 bytes

f=(n,x,N)=>n?'RL.'[!--n|N%3%(3-!~-n)?2:N&1^x]+f(n,x,-~N):N&!x?`
`+f(N,1):''

Try it online!

Commented

f = (               // f is a recursive function taking:
  n,                //   n = input
  x,                //   x = flag set to 1 if we're processing the 2nd row
  N                 //   N = counter incremented each time n is decremented
) =>                //
  n ?               // if n is not 0:
    'RL.'[          //   output the next character:
      !--n |        //     decrement n; if this is the last character
      N % 3 %       //     or N mod 3 is either
      (3 - !~-n) ?  //     odd if n = 1 or not equal to 0 otherwise:
        2           //       output '.'
      :             //     else:
        N & 1 ^ x   //       output either 'L' or 'R' depending on N and x
    ] +             //   end of character output
    f(n, x, -~N)    //   append the result of a recursive call with N+1
  :                 // else:
    N & !x ?        //   if x = 0 and N is odd:
      `\n` +        //     append a linefeed
      f(N, 1)       //     and restart with x = 1
    :               //   else:
      ''            //     stop recursion
\$\endgroup\$
1
\$\begingroup\$

Julia 1.0, 83 80 75 bytes

n->(f(r,s,h='R'-6s)=r∈0:2:4 ? "$h."^(r>>1) : "$h.."*f(r-3,1-s)).(n,0:n%2)

Try it online!

\$\endgroup\$
1
\$\begingroup\$

05AB1E, 28 27 26 25 bytes

Ƀ¶IÅœRΣP}θRv„LR¼¾èyG¼'.J

-1 byte thanks to Kevin Cruijssen

Try it online!

Explanation:

A signature subdivision can be seen as an integer partition. For example, #..#.#. is the partition [3, 2, 2] of 7.

A remarkable property of the subdivisions specified by this challenge is that they maximize product. For example, 3*2*2 = 12, and no other partition of 7 has a product > 12 (only [3, 4] ties it). This can be proved true in the general case.

Ƀ                  # loop (input%2) + 1 times

¶                   # newline
 IŜ                # integer partitions of the input
    R               # reverse, so that [2, 2, 3, ..., 3] comes after [3, ..., 3, 4]
     ΣP}            # sort by product (stable sort)
        θ           # take the last element
         R          # reverse it, so that the 2s are at the end

v                   # for each integer y in the partition
 „LR                # literal string "LR"
    ¼¾è             # increment counter_variable, then use it to index into "LR"
       yG           # loop y-1 times
         ¼          # increment counter_variable
          '.        # literal "."
            J       # join all the strings in the stack
\$\endgroup\$
  • 1
    \$\begingroup\$ Oh, I like the Åœʒ4‹P}θ! I thought about using partitioning with a filter on the length somehow, but couldn't get it to work. This is a lot better than that though. :) And nice approach in general! \$\endgroup\$ – Kevin Cruijssen Aug 9 at 11:24
  • 1
    \$\begingroup\$ 27 bytes by joining and implicitly printing. \$\endgroup\$ – Kevin Cruijssen Aug 9 at 11:38
  • 1
    \$\begingroup\$ @KevinCruijssen since you liked Åœʒ4‹P}θ, you're gonna love ÅœRΣP}θ \$\endgroup\$ – Grimy Aug 9 at 14:47
  • \$\begingroup\$ Oh, you're indeed right, I love that one. Nice use of reversing and using the stable sort. :D Unfortunately I can't upvote again. But I just noticed you've posted the other answer for which I said you should post it yourself, so I've upvoted that one instead. ;) \$\endgroup\$ – Kevin Cruijssen Aug 9 at 15:48

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.