Solver de intervalo de música


11

insira a descrição da imagem aqui

Na teoria musical, um intervalo é a diferença entre dois arremessos. Cada afinação é definida pelo número de meios-passos (a diferença entre C e C #) ou etapas inteiras (a diferença entre C e D). Um passo inteiro é igual a dois meios-passos. Aqui está uma lista de todos os intervalos padrão e o número de meias etapas que eles representam:

0     Perfect Unison
2     Major Second
4     Major Third
5     Perfect Fourth
7     Perfect Fifth
9     Major Sixth
11    Major Seventh
12    Perfect Octave

Existem 3 variações nos intervalos padrão, menor , diminuído e aumentado .

  • Um intervalo menor é um meio passo abaixo do intervalo principal, mas não é um intervalo perfeito. Então você tem um segundo menor (1), um terço menor (3), um sexto menor (8) e um sétimo menor (10). Não existe quarto menor, quinto menor, uníssono menor ou oitava menor, pois todos esses intervalos são perfeitos.

  • Um intervalo diminuído é meio passo mais baixo que um intervalo menor ou perfeito. Há segundo diminuído (0), terceiro diminuído (2), quarto diminuído (4), quinto diminuído (6), sexto diminuído (7), diminuto sétimo (9) e oitava diminuída (11).

  • Um intervalo aumentado é um meio passo mais alto que um intervalo maior ou perfeito. Aumentamos o uníssono (1), aumentamos o segundo (3), aumentamos o terceiro (5), aumentamos o quarto (6), aumentamos o quinto, (8), aumentamos o sexto (10) e aumentamos o sétimo (12).

O desafio:

Você deve escrever um programa ou função que execute várias etapas ou etapas inteiras e, em seguida, imprima uma das descrições válidas em inglês desse intervalo. Não importa qual descrição você escolher, desde que corresponda exatamente à tabela de E / S. Você pode considerar isso como uma sequência

"5w" == 5 whole steps
"3h" == 3 half steps

ou como um número e uma string / caractere.

5, "w" == 5 whole steps
3, "h" == 3 half steps.

Você pode assumir que todas as entradas estarão entre 0 e 12 meias-etapas.

Tabela IO

Aqui está uma lista completa, mapeando o número de meias etapas para todas as saídas aceitáveis.

0       Perfect unison, Diminished second   
1       Minor second, Augmented unison  
2       Major second, Diminished third  
3       Minor third, Augmented second   
4       Major third, Diminished fourth  
5       Perfect fourth, Augmented third     
6       Diminished fifth, Augmented fourth  
7       Perfect fifth, Diminished sixth 
8       Minor sixth, Augmented fifth        
9       Major sixth, Diminished seventh 
10      Minor seventh, Augmented sixth      
11      Major seventh, Diminished octave    
12      Perfect octave, Augmented seventh   

Aqui está uma amostra de E / S:

5w      Minor Seventh
5h      Augmented Third
12h     Perfect Octave
12w     UNDEFINED
1w      Diminished third
2h      Major Second

Dimished ? ....
CalculatorFeline

7
@CatsAreFluffy Minha má ortografia diminuiu minha capacidade de escrever bons desafios. ಠ_ಠ
James

Ainda é um bom desafio, apenas com mais edições! : P
Rɪᴋᴇʀ

Respostas:


1

Ruby, Rev. B 138 bytes

->n,s{i=12-n-n*(s<=>?h)
[a='Augmented','Major','Minor',d='Diminished',a,'Perfect',d][i%7]+' '+%w{seventh fifth third unison}[i%7/4+i/7*2]}

5 bytes salvos por não repetir Augmented/Diminished. 1 byte salvo pelo uso de ?h.

Ruby, Rev A 144 bytes

->n,s{i=12-n-n*(s<=>'h')
%w{Augmented Major Minor Diminished Augmented Perfect Diminished}[i%7]+' '+%w{seventh fifth third unison}[i%7/4+i/7*2]}

A idéia é minimizar o número de intervalos básicos (sétimo quinto terço e uníssono) e aproveitar o fato de que sétimos e quintos têm uma relação análoga à que existe entre terços e uniões.

Existem quatro tipos de sétimo / terceiro e três tipos de quinto / uníssono, portanto a variável de índice ié definida como 12 menos o número de meias etapas, para que o primeiro termo da expressão i%7/4 + i/7*2selecione corretamente o tipo de intervalo básico.

ungolfed no programa de teste

f=->n,s{                 #n = number of steps. s= step size, w or h
  i=12-n-n*(s<=>'h')     # i=12-n. If s is later in the alphabet than 'h' subtract again for whole steps
  %w{Augmented Major Minor Diminished Augmented Perfect Diminished}[i%7]+
  ' '+%w{seventh fifth third unison}[i%7/4+i/7*2]
}

-1.upto(12){|j|
puts f[j,'h']
}  

0.upto(6){|j|
puts f[j,'w']
}

resultado

Diminished unison
Perfect unison
Augmented unison
Diminished third
Minor third
Major third
Augmented third
Diminished fifth
Perfect fifth
Augmented fifth
Diminished seventh
Minor seventh
Major seventh
Augmented seventh

Perfect unison
Diminished third
Major third
Diminished fifth
Augmented fifth
Minor seventh
Augmented seventh

Entradas de comportamento indefinidas: A função fornece a resposta correta diminished unionpara -1 halfsteps, mas falha para entradas acima de 12. Por exemplo, ela produz perfect unison14 half steps, pois o algoritmo é baseado em um ciclo de 14 em vez de 12.


2

Python 2, 149 bytes

def f(n,c):n*=1+(c>'h');print(n-6)%13%2*"Diminished"or"Augmented",'octave seventh sixth fifth fourth third second unison'.split()[71056674174>>3*n&7]

Primeiro, etapas inteiras são convertidas em meias etapas.

Então, Diminishedvs Augmentedé impresso. Eles alternam para adjacentes, nexceto isso, n=5e n=6dão o mesmo, o que é obtido primeiro colocando-os em um módulo de limite um número ímpar.

Finalmente, a distância é impressa, calculada através de uma tabela de pesquisa de três bits. Isso é mais curto do que fazer int('6746543230210'[n]).


2

Python 2.7, 155 bytes

s='second unison third fourth sixth fifth seventh octave Diminished Augmented'.split()
def f(n,c):x=0xDE9CB87561430>>[4,8][c>'h']*n;print s[x%2+8],s[x/2%8]

1

Retina, 153 bytes

\ d +
$ *
(. *) w | h
$ 1 $ 1
^ 1 * $
$ .0
^ 11
$ 0 diminuído
^ \ d
$ 0 aumentada
10 | 7
sexto
11
oitava
12 | 9
sétimo
8
quinto
4 | 6
quarto
5 | 2
terceiro
1
uníssono
\ d
segundo

O número da entrada é primeiro convertido em unário, depois dobrado se seguido por we todas as letras são removidas, deixando apenas o número unário. Esse número é convertido novamente em decimal. Finalmente, algumas pesquisas e substituições são aplicadas para construir a saída final.

Exemplo é executado:

6w => 111111w => 111111111111 => 12 => 12 aumentado => sétimo aumentado
7h => 1111111h => 1111111 => 7 => Diminuído 7 => Diminuído sexto
3w => 111w => 111111 => 6 => Aumentado 6 => Aumentado quarto
0h => h => => 0 => Diminuído 0 => Diminuído segundo

Experimente online!


0

Vitsy , 166 bytes

Bem, isso definitivamente pode ser ainda mais jogado.

WW2M1+*a+mZ
'dehsinimiD'
'roniM'
'rojaM'
'tcefreP'
'detnemguA'
'dnoces '
'htruof '
'htxis '
'evatco '
6m1m
6m2m
6m3m
6m5m
7m1m
7m4m
7m5m
8m1m
8m2m
8m3m
8m5m
9m1m
9m4m

Isso funciona definindo a quantidade mínima de itens possível e, em seguida, chamando esses itens através da sintaxe do método.

Experimente Online!


0

Javascript 189 bytes

a=>(n='sutsftfxFvxov'[N=parseInt(a)*(a.slice(-1)>'v'?2:1)])&&((N>5?N+1:N)%2?'Augmented ':'Dimished ')+'unison,second,third,fourth,fifth,sixth,seventh,octave'.split`,`['ustfFxvo'.indexOf(n)]



 F=
  a=>
    (n='sutsftfxFvxov' //using the right side of the possible answers
                       //set n = the letter representing
                       //unison, first, second ...

       //set N to 12 for 12h, but 24 for 12w
       [N=parseInt(a)*(a.slice(-1)>'v'?2:1)])

  &&   //if we were out of range (12w) we'll return undefined


    (
      (N>5?N+1:N)%2?  //get Aug or Dim (right side goes)
                      //DADADAADADADA
                      //     ^^ makes this a pain
       'Augmented ':'Dimished '
     )
     +
            //turn n (which is u for unison, x for sixth, etc
            //into it's full name
       'unison,second,third,fourth,fifth,sixth,seventh,octave'
         .split`,`
     ['ustfFxvo'.indexOf(a)]

0

Java, 225 224 bytes

Tem que haver uma maneira melhor de empacotar essas strings, mas eu não tenho nenhuma idéia.

(i,s)->{String A="Augmented",M="Major",m="Minor",P="Perfect",D="Diminished",d=" Second",f=" Fourth",a=" Sixth",C=" Octave";String[]o=new String[]{D+d,m+d,M+d,A+d,P+f,A+f,D+a,m+a,M+a,A+a,D+C,P+C};i*=s=='w'?2:1;return o[i-1];}

Recuado:

static BiFunction<Integer, Character, String> interval = (i,s) -> {
    String A="Augmented",M="Major",m="Minor",P="Perfect",D="Diminished",
            d=" Second",f=" Fourth",a=" Sixth",C=" Octave";
    String[] o = new String[] {D+d,m+d,M+d,A+d,P+f,A+f,D+a,m+a,M+a,A+a,D+C,P+C};
    i *= s=='w' ? 2 : 1;
    return o[i-1];
};

Acredito que você pode reduzi-lo, substituindo-o if(s=='w')i*=2;pori*=s=='w'?2:1;
Mr Public

@MrPublic Você está correto.
284
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.