Aiutami con i miei poliritmi


17

Sono un musicista e ho bisogno di più poliritmi nella mia vita!

Un poliritmo si verifica nella musica (e in natura) quando due eventi (battiti di mani, note, lucciole che lampeggiano ecc.) Si verificano a due diversi intervalli regolari. I due tipi di eventi si verificano un numero diverso di volte nello stesso intervallo.

Se tocco due volte con la mano sinistra e 3 volte con la mano destra, nello stesso lasso di tempo, è un po 'così:

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

I trattini in alto indicano la lunghezza del pattern poliritmico, che è il minimo comune multiplo o 2 e 3. Questo può essere inteso come il punto in cui il pattern si ripete.

C'è anche un 'metaritmo', che è il modello prodotto quando una delle due mani sta toccando:

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

Questo è un poliritmo semplice e molto comune, con un rapporto di 3: 2.

Diciamo solo che non voglio fare un semplice poliritmo che posso elaborare nella mia testa, quindi ho bisogno di qualcosa per risolverlo per me. Potrei farlo a lungo su carta, o ...


Regole:

  • Scrivi del codice per generare e visualizzare un diagramma poliritmico, come descritto sopra.
  • Qualsiasi vecchia lingua, prova per il minor numero di byte.
  • Il tuo codice accetta due argomenti:
    • Numero di tocchi con la mano sinistra (numero intero positivo)
    • Numero di tocchi con la mano destra (numero intero positivo)
  • Elaborerà la lunghezza, che è il minimo comune multiplo per i due argomenti.
  • La riga superiore sarà composta da due caratteri spazi bianchi seguiti da trattini che visualizzano la lunghezza (lunghezza * '-')
  • La seconda e la terza riga mostreranno lo schema delle mani destra e sinistra:
    • Inizierà con una R o una L, indica la mano che è, seguita da uno spazio.
    • L'intervallo per quella mano è la lunghezza divisa per il suo argomento.
    • I tocchi inizieranno al terzo carattere, indicato da qualsiasi personaggio tu scelga. Da quel momento in poi verranno visualizzati gli stessi caratteri "intervallo".
    • Non sarà più lungo della linea di lunghezza.
  • La quarta riga è il metaritmo:
    • Inizierà con una M maiuscola, seguita da uno spazio.
    • Dal terzo carattere in poi, mostrerà un personaggio (qualsiasi personaggio tu scelga) in ogni posizione in cui è presente un tocco sulla mano destra o sinistra.
  • Lo spazio bianco finale è irrilevante.

Casi test:

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

Buon golf!


I tuoi casi di test includono molti spazi vuoti finali, possiamo ometterli / aggiungere altro?
wastl,

Dobbiamo accettare re lcome due valori separati? Potremmo invece accettare una matrice a due elementi, ad esempio? Che ne dici dell'ordine di questi, è rigorosamente rseguito da l?
Dal

@Sok È accettabile come interpretazione di "due argomenti"
AJFaraday,

Deve davvero stampare il diagramma o può semplicemente restituirlo?
Ripristina Monica - notmaynard

@iamnotmaynard il ritorno va bene.
AJFaraday,

Risposte:


6

JavaScript (ES6), 131 byte

Emette 0come carattere di tocco .

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)

Provalo online!

Come?

Usiamo la stessa funzione di supporto per due scopi diversi.g()

g()0K=mcm(l,r)

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

S

g()1n3XS0

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

4

Java 11, 226 234 233 219 byte

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

Un po 'lungo; peccato che Java non abbia una lcm()funzione. Provalo online qui (TIO non ha ancora Java 11, quindi utilizza un metodo helper anziché String.repeat()).

La mia versione iniziale ha preso l'intervallo tra i tocchi anziché il numero di tocchi. Riparato ora. Grazie a Kevin Cruijssen per il golf 1 byte.

Ungolfed:

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
}

Non è molto, ma -1 byte cambiando ?".":" "in ?'.':32.
Kevin Cruijssen,

@KevinCruijssen Ogni byte conta :-) Grazie!
OOBalance

4

Python 2 , 187 185 183 174 166 156 148 147 145 byte

Utilizza -come carattere di tocco

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

Provalo online!


Salvato:

  • -2 byte, grazie a Jonathan Frech

[i%(w/y)and i%(w/z)>0]potrebbe essere [i%(w/y)!=0<i%(w/z)].
Jonathan Frech,

@JonathanFrech Thanks :)
TFeld

3

Perl 6 , 85 80 78 byte

-2 byte grazie a Jo King.

'  'R L M»Z~'-'x($!=[lcm] @_),|(@_.=map:{' '~(0~' 'x$!/$_-1)x$_}),[~|] @_}

Provalo online!

Restituisce un elenco di quattro righe.


3

Python 2 , 185 228 223 234 249 byte

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)

Provalo online!


Ho appena copiato e incollato questo in TIO e da lì ho preso il formato generato. Si scopre che è fatto in meno byte di quanto pensassi;)
AJFaraday

@Tfeld r=4, l=8funziona bene per me
sonrad10

La lunghezza dovrebbe essere il minimo comune multiplo. Con r = 4, l = 8, dovrebbe essere 8, ma sembra che l'output sia molto più lungo (8 * 4?).
OOBalance

1
Ciò non dà ancora alla LCM; ad esempio per 15,25, dà 375, ma dovrebbe essere 75.
OOBalance

1
Credo che l'ultimo controllo possa essere sostituito da i%r+i%l+0**i<1. Inoltre, puoi rimuovere le versioni precedenti del codice, poiché verranno conservate nella cronologia delle modifiche di chiunque voglia vederle
Jo King

2

Gelatina , 32 byte

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

Provalo online!

Accetta input come elenco [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 byte

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

Porta della mia risposta Java . Chiama con f(number_of_right_hand_taps, number_of_left_hand_taps). Provalo online qui .



1

Pyth, 53 byte

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

Sicuramente spazio per il golf. Lo farò quando avrò tempo.
Provalo qui

Spiegazione

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 # (compilatore interattivo Visual C #) , 254 byte


Golf Provalo online!

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

Ungolfed

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

Codice completo

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

Uscite

  • v1.0 - 254 bytes- Soluzione iniziale.

Appunti

  • Nessuna

1

Carbone , 52 byte

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

Provalo online! Il collegamento è alla versione dettagliata del codice. Spiegazione:

≔θζW﹪ζη≧⁺θζ

Calcola il LCM degli input prendendo il primo multiplo di Rquello divisibile per L.

ζ↙

Stampa l'LCM, che genera automaticamente la riga necessaria di - s. Quindi spostare per stampare il ritmo da destra a sinistra.

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

Scorri i numeri dall'LCM fino a 0 e crea una serie di elenchi che rappresentano i battiti delle mani destra e sinistra.

Fζ⊞ι⌈ι

Passa sopra i battiti e aggiungi il metaritmo.

↓Eζ⭆ι§ .λ

Stampa le battute inverse verso il basso, ma poiché si tratta di un array, finiscono verso sinistra.

←↓RLM

Stampa l'intestazione.



1

Python 2 , 117 byte

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

Provalo online!


1

Pyth, 49 byte

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

Prevede input nel modulo [r,l]. Utilizza -per visualizzare i tocchi. Provalo online qui o verifica tutti i casi di test contemporaneamente qui .

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 byte

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

Provalo online!

Sicuramente sento che c'è spazio per miglioramenti qui, ma ho provato alcuni approcci diversi e questo è l'unico che si è bloccato. Sbarazzarsi della definizione della funzione interna mi renderebbe abbastanza felice, e ho provato un sacco di ristrutturazioni del gatto () per farlo accadere.Non importa, non appena ho pubblicato ho capito cosa avrei potuto fare. Ancora sicuramente alcuni risparmi di efficienza da trovare.

Ci sono altre funzioni LCM nelle biblioteche con nomi più brevi, ma TIO ha dei numeri e ho ritenuto che siano più utili a questo punto.


1

C ++ (gcc) , 197 byte

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

Provalo online!


suggerire ++p%a+p%b invece di++p%a||p%b
ceilingcat il
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.