Desdobrar saltos musicais

11

A Segno e Da Capo são dois termos musicais muito comumente usados. Eles significam " do sinal " (𝄋) e " do começo ", respectivamente.

Há também a idéia da coda (𝄌), que é o fim de uma peça musical. É o que é tocado após a "seção principal" da peça.

Um DS al coda ( Dal Segno al coda ), por exemplo, significa "vá para o segno , toque até você receber instruções para ir ao coda e depois pule para lá".

Descrição

Seu trabalho neste desafio é receber contribuições compostas por qualquer número de notas que possam ou não conter Dal Segno e Da Capo e produzir a mesma música com os saltos mencionados "desdobrados" para que as repetições sejam expandidas literalmente.

Entrada

Seu código deve ter como entrada uma sequência de notas ou sinais (aqui definidos como qualquer coisa, exceto uma nota), separados por espaços em uma sequência.

  • As notas são qualquer um a, b, c, d, e, f, ou g, com um opcional #ou banexado (para os fins deste desafio, não há ritmo).

  • A C(capital c) representa uma marcação de coda . Sempre haverá zero ou duas marcações de coda ; a primeira coda marcação de representa de onde pular e a segunda representa para onde pular.

  • Um S(maiúsculo) representa uma marcação de sinal . Haverá sempre zero ou um signo marcação (s).

  • Um F(capital f) representa uma boa marcação. Isso "substitui" o final da peça - mais sobre isso abaixo. Sempre haverá zero ou uma marcação fina .

  • Qualquer uma das seguintes seqüências de texto exatas representa:

    • D.S. al fine: vá para o signo e toque até o final da peça ou a marcação fina (se existir).

    • D.S. al coda: Ir ao signo , jogo até a coda , e depois saltar para a segunda coda marcação e jogar até o final da peça.

    • D.C. al fine: vá para o início, toque até o fim ou a marcação fina .

    • D.C. al coda: Ir para o início, o jogo até o coda , e depois saltar para a segunda coda marcação e jogar até o final da peça.

    Sempre haverá um mínimo de zero e um máximo de cada corda por peça. Nunca haverá vários al fines ou múltiplos al codas em uma peça.

Resultado

Seu código deve gerar um formato de sequência semelhante: uma lista de notas, separadas por espaços.

Você sempre pode assumir que a saída acabará tendo um ou mais caracteres.

Casos de teste

Em: a# bb c b a
Fora:a# bb c b a

Em: a S b D.S. al fine c
Fora:a b b c

Em: a S b C c D.S. al coda d C e
Fora:a b c b e

Em: a b F c d D.C. al fine e f
Fora:a b c d a b

Em: a b D.C. al fine c d F e f
Fora:a b a b c d

Em: a b C c d D.C. al coda e f C g g#
Fora:a b c d a b g g#

Em: a b D.C. al coda c d C e f C g g#
Fora:a b a b c d g g#

Em: a b S c d C D.C. al coda C D.S. al fine e f F g
Fora:a b c d a b c d c d e f

Em: a S b C c D.S. al coda C d D.S. al fine e F f
Fora:a b c b d b c d e

Em: a b C c d D.C. al coda e f F g g# C gb a# D.C. al fine
Fora:a b c d a b gb a# a b c d e f

Em: a F b C D.C. al coda C D.C. al fine
Fora:a b a b a

Em: C a S b D.C. al coda C c D.S. al fine d
Fora:a b c b c d

Em: a S b D.S. al coda C C c D.C. al fine
Fora:a b b c a b c

Em: a F C b C D.C. al coda D.C. al fine
Fora:a b a a

Regras

  • As marcações sempre aparecerão em uma ordem lógica. Ou seja, nunca haverá um Sdepois de um D.S.e sempre haverá um antes, etc.

  • Isso é , então o código mais curto em bytes vencerá.

Maçaneta da porta
fonte

Respostas:

1

JavaScript (ES6), 253 bytes

x=>eval('n=(" "+x).replace(/D.{11}|[CSF]/g,d=>({C:4,S:5,F:6}[d]|(d[2]<"S")*2+(d[8]<"f"))).split` `;for(i=c=f=o="";v=n[++i];v<9?v<4?(n[i]=7,i=0,s=n.indexOf`5`,v==0?f=i=s:v==1?c=i=s:v==2?f=1:c=1):v==4&c?c=!(i=n.indexOf("4",i+1)):v==6&f?i=n:0:o+=v+" ");o')

Explicação

Poderia ser jogado melhor, mas estou pronto por enquanto.

x=>
  eval(`                                  // use eval to enable for loop without return
    n=(" "+x)                             // n = array of [ "", ...notes/commands ]
                                          // empty first element means f and c can be set
                                          //     to i (always true) in the cases below
      // DS fine => 0, DS coda => 1, DC fine => 2, DC coda => 3, C => 4, S => 5, F => 6
      .replace(/D.{11}|[CSF]/g,d=>({C:4,S:5,F:6}[d]|(d[2]<"S")*2+(d[8]<"f")))
      .split\` \`;
    for(
      i=                                  // i = position in note array
      c=                                  // c = look out for coda if true
      f=                                  // f = look out for fine if true
      o="";                               // o = output string
      v=n[++i];                           // v = note/command
      v<9?                                // if not a note
        v<4?(                             // if DS/DC
          n[i]=7,                         // change it to NOP
          i=0,                            // reset i here to save doing it in DC cases
          s=n.indexOf\`5\`,
          v==0?f=i=s:                     // case: D.S. al fine
          v==1?c=i=s:                     // case: D.S. al coda
          v==2?f=1:                       // case: D.C. al fine
          c=1                             // case: D.C. al coda
        ):
        v==4&c?c=!(i=n.indexOf("4",i+1)): // case: C
        v==6&f?i=n:                       // case: F
        0                                 // case: S
      :o+=v+" "                           // add the note
    );o                                   // return the output
  `)

Teste

user81655
fonte