Consonância ou dissonância?

36

Dados dois nomes de notas, você deve escrever um programa que determine se o intervalo formado por essas duas notas é consoante ou dissonante.

Introdução

Na música ocidental, existem apenas 12 tons "diferentes". Seus nomes, ordenados menor para o maior, são estas: C, C#, D, D#, E, F, F#, G, G#, A, A#, B. A sequência é cíclica, ou seja, continua com outra Capós o Binfinitamente.

A distância entre dois tons é chamada de intervalo . O intervalo entre duas notas adjacentes na série acima (por exemplo, C — C#ou E — F) é chamado de semitom . O intervalo entre as notas mais distantes é definido como o número de etapas de semitons necessárias para ir do primeiro ao segundo (enquanto possivelmente envolve a sequência). Alguns exemplos: D to E= 2 semitons, C to G= 7 semitons, B to D#= 4 semitons (isso envolve a sequência). 1 1

Agora, esses intervalos são divididos em duas categorias: consoante (soando agradavelmente se você tocar as duas notas ao mesmo tempo) e dissonante (nem tanto).

Vamos definir os intervalos consoantes como: 0, 3, 4, 5, 7, 8 e 9 semitons.

O restante deles é dissonante, a saber: 1, 2, 6, 10 e 11 semitons.

O desafio

Escreva um "programa" (no sentido amplo da palavra: uma função está perfeitamente bem) para fazer o seguinte:

  • Pegue dois nomes de notas (sequências da sequência acima) como entrada. Você pode tomá-los como quiser (do stdin, como argumentos, separados pelo que você quiser, até sinta-se à vontade para tomá-los como uma lista de caracteres (por exemplo ["C","#"]).) No entanto, você não pode atribuir nenhum outro nome às notas (especialmente você não pode numerá-los de 0 a 11 e usar os números).

  • Para os fãs de música por aí, as notas serão especificadas sem a oitava. Nesse caso, também não importa em qual ordem as notas vêm e qual é mais baixa e qual é mais alta. Por fim, você não precisa manipular nenhum nome que não esteja na lista acima. Nenhuma outra enarmônica como E#, sem apartamentos, alterações duplas e assim por diante.

  • Escolha dois valores diferentes. Seu programa deve produzir um deles sempre que o intervalo formado pelas duas notas na entrada for consoante e o outro, se não for. (Pode ser Truee False, mas até π e e se você quiser :))

  • Este é um código de golfe. O programa mais curto em bytes em cada idioma vence. Diverta-se!

Exemplos e casos de teste

Note 1    Note 2    Output    Interval [semitones]
  C          D     Dissonant   2
  A#         A#    Consonant   0
  G          D     Consonant   7 (wraparound)
  D#         A     Dissonant   6
  F          E     Dissonant   11
  A          C     Consonant   3

Não adiciono mais, pois não há casos particularmente traiçoeiros nisso.

Este é o meu primeiro desafio, portanto qualquer crítica construtiva é muito bem-vinda: --). Se você achar a explicação da teoria superficial, sinta-se à vontade para fazer perguntas. Finalmente, por favor, não me diga que este é um joguete de este ou este . Eu tive certeza de que não é. (O último é bem parecido, mas mais complexo. Pensei que colocar um desafio um pouco mais simples tornaria mais fácil a participação de pessoas.)


1 : Tentei simplificar essa explicação o máximo que pude. Há muito mais teoria sobre os intervalos. Por favor, não me bata por deixá-lo de fora.

Ramillies
fonte

Respostas:

12

Gelatina , 21 bytes

Recebe a entrada como uma lista de duas strings. Retorna 0para dissonante ou 1consoante.

OḢ6×%21_Lµ€IA“¬ɠṘ’æ»Ḃ

Experimente online!

OḢ6×%21_Lµ€IA“¬ɠṘ’æ»Ḃ   - main link
         µ€             - for each note             e.g. ["A#", "C"]
O                       -   convert to ASCII codes  -->  [[65, 35], 67]
 Ḣ                      -   keep the first element  -->  [65, 67]
  6×                    -   multiply by 6           -->  [390, 402]
    %21                 -   modulo 21               -->  [12, 3]
       _L               -   subtract the length     -->  [12, 3] - [2, 1] = [10, 2]
           IA           - absolute difference       -->  8
             “¬ɠṘ’      - the integer 540205
                  æ»    - right-shift               -->  540205 >> 8 = 2110
                    Ḃ   - isolate the LSB           -->  2110 & 1 = 0

Realização de

Primeiro, devemos observar que a função F que estamos procurando é comutativa: para qualquer par de notas (A, B) , temos F (A, B) = F (B, A) .

Como não há muitas entradas possíveis e apenas duas saídas possíveis para lidar, deve ser possível encontrar uma função hash bastante simples H , de modo que | H (A) - H (B) | produz um intervalo limitado de valores e é livre de colisões para todos os pares possíveis de notas (A, B) em relação à produção esperada.

Vamos testar o conjunto de funções H (mul, mod) , que são definidas como:

H(mul, mod)(s) = ((ORD(s[0]) * mul) MOD mod) - LEN(s)

Onde ORD(s[0])está o código ASCII do primeiro caractere da nota e LEN(s)o comprimento da nota ( 2 se houver um '#'e 1 se não).

Abaixo está uma versão comentada do código JS que foi usada para encontrar alguns pares válidos (mul, mod) e as máscaras de bits resultantes. Existem muitas soluções possíveis, mas * 6 % 21é a mais curta com esse método.

Arnauld
fonte
3
Como você consegue essas coisas? .. Você está recebendo esse tipo de 'algoritmo' manualmente ou com força bruta? E, independentemente da resposta da segunda pergunta: como?! ..: S " número inteiro literal 540205; deslocado para a direita com (código ASCII; multiplique por 6; módulo 21; mantenha primeiro; subtraia o comprimento ...); bit a bit-AND 1 " Suas respostas continuam me impressionando todas as vezes ..
Kevin Cruijssen 19/09/17
@KevinCruijssen Adicionei o código JS original que foi usado para encontrar esses valores.
Arnauld
Obrigado pela explicação adicionada. Ainda estou tão impressionado quanto primeiro, mas você deu uma explicação clara de como surgiu. Pena que só posso votar uma vez.
Kevin Cruijssen 19/09/17
9

APL (Dyalog) , 62 39 bytes

Usos ⎕IO←0; 0 é consoante, 1 é dissonante. Leva a lista de caracteres de nota de base como argumento à esquerda e a lista de objetos cortantes como argumento à direita.

{⎕A[|-/('C D EF G A '⍳⍺)+⍵=⍕#]∊'BCGKL'}

Experimente online!

{} Função anônima onde está o argumento da esquerda e é o argumento da direita

⎕A[... ]∊'BCGKL' é o A lphabet, indexado pelo seguinte, um membro da corda?

  ⍕# formate o espaço para nome raiz (gera o caractere nítido)

  ⍵= os caracteres de argumento corretos (os cortantes) são iguais a isso?

  ()+ Adicione o seguinte:

   'C D EF G A '⍳⍺ índices do caractere esquerdo caracteres na string

  -/ diferença entre aqueles

  | valor absoluto

Uriel
fonte
Você se importaria de adicionar uma explicação para aqueles que não estão familiarizados com a APL?
Draconis
@Draconis Explanation added.
Adám 18/09/17
9

MATL , 30 27 26 bytes

,j'DJEFPGIALBC'&mQs]ZP7Mdm

Introduz as duas notas em linhas diferentes. Saídas 0para consoante, 1para dissonante.

Experimente online! Ou verifique todos os casos de teste .

Explicação

A cadeia de 11 caracteres

DJEFPGIALBC

codifica as notas e os intervalos dissonantes, como a seguir.

O programa encontra primeiro os índices baseados em 1 dos caracteres de entrada na sequência acima. Uma entrada não nítida como Ddará 1, Edará 3, ..., Cdará 11. Esses números também podem ser considerados matrizes numéricas 1 × 1. Uma entrada nítida como C#dará a matriz 1 × 2 [11 0], o que significa que Cfoi encontrado na posição 11e #não foi encontrado.

Observe que as letras JPILnunca estarão presentes na entrada. Por enquanto, eles são usados ​​apenas como espaços reservados, de modo que, por exemplo, note Eestão dois semitons acima D. Mas eles também serão úteis para definir intervalos dissonantes.

Os números na primeira entrada da matriz 1 × 1 ou 1 × 2 correspondem ao tom das notas em semitons, sem contar os símbolos nítidos (ainda). Observe que a escala definida por esses números não começa em C; mas isso não importa, porque queremos apenas intervalos, ou seja, diferenças entre as notas. Subtrair os números obtidos daria o intervalo ou 12 menos o intervalo. Mas primeiro precisamos considerar o símbolo afiado.

Para considerar notas nítidas, uma maneira de jogar golfe (em MATL) é adicionar 1a cada entrada da matriz 1 × 1 ou 1 × 2 obtida anteriormente e somar a matriz (2 bytes). Assim, as notas não nítidas são aumentadas 1e as notas nítidas em 2. Isso torna as notas nítidas 1 semitom mais altas que as notas não nítidas, conforme necessário. Também estamos adicionando um semitom extra a todas as notas, mas isso não altera os intervalos entre elas. Então agora a nota Ddará o número do arremesso 2, D#dará 3, ..., Cdará 12, C#dará 13.

Intervalos dissonantes são 1, 2, 6, 10, ou 11. Eles têm simetria no módulo 12 : um intervalo entre duas notas é dissonante se e somente se o intervalo com as notas na ordem inversa, módulo 12, for dissonante.

Se calcularmos as diferenças consecutivas da string 'DJEFPGIALBC', obtemos o vetor numérico

6 -5 1 10 -9 2 -8 11 -10 1

que contém precisamente os intervalos dissonantes, além de alguns valores negativos, que não serão úteis nem prejudiciais. Observe que é a escolha de letras adicionais JPILna string 'DJEFPGIALBC'que define (através de diferenças consecutivas) os intervalos dissonantes.

Para ver se as duas notas de entrada são dissonantes, tomamos a diferença absoluta de seus números de afinação. Por exemplo, Ce D#dará números 12e 3, respectivamente, e a diferença absoluta é 9. A diferença real seria -9e o intervalo real seria 3(obtido como -9módulo 12). Mas, graças à simetria mencionada acima, podemos considerar em 9vez de 3. Como 9não está presente no vetor de diferenças consecutivas, as notas são consoantes.

Luis Mendo
fonte
2
Gosto da maneira como você codificou as notas e os intervalos dissonantes na mesma sequência.
Celtschk # 19/17
8

JavaScript (ES6), 68 64 bytes

Faz as anotações como duas strings na sintaxe de currying (a)(b). Retorna 0para dissonante ou 1consoante.

a=>b=>488055>>(g=s=>'C D EF G A'.search(s[0])-!s[1])(a)-g(b)+9&1

Casos de teste

Formatado e comentado

a => b =>                       // given the two notes 'a' and 'b'
  488055 >>                     // 19-bit lookup bitmask: 1110111001001110111
    (g = s =>                   // we use g() to convert a note 's' into a semitone index
      'C D EF G A'.search(s[0]) // position of the note: -1 for 'B' (not found) to 9 for 'A'
      - !s[1]                   // subtract 1 semitone if the '#' is not there
    )(a)                        // compute the result for 'a'  --> [ -2 ...  9]
    - g(b)                      // subtract the result for 'b' --> [-11 ... 11]
    + 9                         // add 9                       --> [ -2 ... 20]
  & 1                           // test the bitmask at this position (0 if negative or > 18)
Arnauld
fonte
7

Geléia , 26 bytes

i@€ØAo.SḤ’d5ḅ4µ€ạ/“¢£©½¿‘ċ

Um link monádico que obtém uma lista das duas notas (como listas de caracteres) e retorna 0para consoante e 1dissonante.

Experimente online! ou veja todas as entradas no conjunto de testes .

Quão?

i@€ØAo.SḤ’d5ḅ4µ€ạ/“¢£©½¿‘ċ - Link: list of lists of characters, notes
              µ€           - for €ach note in notes: (call the resulting list x)
   ØA                      -   yield the uppercase alphabet
i@€                        -   first index of c in ^ for €ach character, c
                           -     ...note '#' is not there so yields 0 (A->1, B->2,...)
      .                    -   literal one half
     o                     -   or (vectorised)  - e.g. "C#" -> [3, 0] -> [3, 0.5]
       S                   -   sum
        Ḥ                  -   double - that is ...  C C#  D D#  E  F F#  G G#  A A#  B
                                                 ->  6  7  8  9 10 12 13 14 15  2  3  4
         ’                 -   decrement         ->  5  6  7  8  9 11 12 13 14  1  2  3
           5               -   literal five
          d                -   divmod                (e.g. 9 -> [1,4] or 11 -> [2,1])
             4             -   literal four
            ḅ              -   convert from base     (e.g. [1,4] -> 8 or [2,1] -> 9)
                                                 ->  4  5  6  7  8  9 10 11 12  1  2  3
                 /         - reduce x with:
                ạ          -   absolute difference   (e.g. ["G#", "A"] -> [12, 1] -> 11)
                  “¢£©½¿‘  - code-page indices = [1, 2, 6, 10, 11]
                         ċ - count occurrences (1 if in the list, 0 if not)
Jonathan Allan
fonte
5

Gelatina , 31 bytes

O_65ị“¢[ḋṃ’b⁴¤+L$€Ḣ€ạ/e“cṾ’b12¤

Experimente online!

wheeeeee 32 bytes a mais

Explicação

O_65ị“¢[ḋṃ’b⁴¤+L$€Ḣ€ạ/e“cṾ’b12¤  Main link
O                                Cast each character to an int using Python `ord`
 _65                             Subtract 65 (A is 0, G is 7)
     “¢[ḋṃ’b⁴¤                   [2, 3, 5, 7, 9, 10, 0]
     “¢[ḋṃ’                      37058720
           b                     Digits in base
            ⁴                    16
    ị                            Index into this list; this creates the gaps for sharps
                 €               For each sublist
              +L$                Add the length to each element (Sharpens sharp notes)
              +                  Add
               L                 Length
                   €             For each sublist
                  Ḣ              Take the first element
                    ạ/           Absolute difference between the two (unoctaved) pitches # It's convenient that every interval's inverse (?) has the same consonance/dissonance
                      e          Is the semitone difference in
                       “cṾ’b12¤  [1, 2, 6, 10, 11]?
                       “cṾ’      25178
                           b     base
                            12   12
HyperNeutrino
fonte
Ei, essa é uma ótima resposta! Eu queria saber se alguém faz uso da simetria, e você fez. E também gosto do seu método para combinar os nomes das notas com os números! +1.
Ramillies
A diferença de semitons pode ser simétrica, mas você ainda obtém resultados duff - por exemplo "G#", "A"(dissonante) produz uma diferença da 11qual não está[1,2,6] .
Jonathan Allan
@ JonathanAllan oh, bem, isso é embaraçoso; Eu pensei que aquela diferença absoluta corrigisse isso ... ._. vai corrigir lol
HyperNeutrino
1
@JonathanAllan corrigido por alguns bytes extras (3
IIRC
4

Mathematica, 55 bytes

function                                                  arguments        bytes

FreeQ[1|2|6|10|11]@Abs[#-#2&@@Sound`PitchToNumber/@#]&    [{"C","F#"}]     55

Mapeie o interno interno Sound`PitchToNumberna entrada (lista de duas seqüências), faça a diferença absoluta e faça a correspondência de padrões para números de intervalo dissonantes.


Apenas por diversão (não concorrente)

Aqui estão algumas funções mais curtas que violam a restrição "você não pode atribuir nenhum outro nome às notas". O rudimentarMusic` pacote possui constantes de notas predefinidas (como A4 = 440.) e a função HertzToCents(que pode ser jogada no golfe). Em vez de strings, usaremos as constantes da nota como argumentos, mas fornecidas em um formato diferente para cada função.

FreeQ[1|2|6|10|11]@Abs@@Round[.01HertzToCents@#]&         [{C3,Fsharp3}]   50+9=59
FreeQ[1|2|6|10|11]@Abs@Round[17Log[#2/#]]&                [C3,Fsharp3]     43+9=52
FreeQ[1|2|6|10|11]@Abs@Round[17Log@#]&                    [C3/Fsharp3]     39+9=48

A importação do pacote <<Music`;leva 9 bytes.

Essa função converte uma string (como "F#" ) em uma constante de nota (como Fsharp3):

Symbol[StringReplace[#,"#"->"sharp"]<>"3"]&                                44

Para aceitar intervalos maiores que uma oitava, substitua Abs[…] por Mod[…,12].


Por que alguns intervalos são considerados dissonantes? Um intervalo é uma razão de duas frequências. Se a relação tiver um numerador e denominador "simples", ela tende a ser mais consoante. Em ajuste de 5 limites , as proporções podem ser fatoradas em potências inteiras de apenas números primos menores ou iguais a 5. Nenhum intervalo de temperamento igual, além da oitava, é apenas um intervalo ; são apenas aproximações aproximadas usando potências da 12a raiz de 2.

Em vez de codificar quais números de intervalo são dissonantes, podemos encontrar uma aproximação racional do intervalo e determinar se o numerador e o denominador são "simples" (o que significa que o denominador é menor que 5 e a razão não divide 7).

Esta tabela mostra cada uma das etapas desse processo.

Table[
  Module[{compoundInterval,simpleInterval,rationalApprox,denomLeq5,div7,consonant},
    compoundInterval = Power[2, i/12];
    simpleInterval   = 2^Mod[Log2[compoundInterval], 1];
    rationalApprox   = Rationalize[N@simpleInterval, 1/17];
    denomLeq5        = Denominator[rationalApprox]<=5;
    div7             = Denominator[rationalApprox]>1 && rationalApprox\[Divides]7;
    consonant        = FreeQ[1|2|6|10|11][Mod[i,12]];

    InputForm/@{
      i, simpleInterval, rationalApprox, 
      denomLeq5, div7, denomLeq5 && !div7,
      consonant
    }
  ], {i, 0, 12}
]

i   sInterval  ratio   denomLeq5  div7       den&&!div  | consonant?

0   1          1       True       False      True       | True
1   2^(1/12)   17/16   False      False      False      | False
2   2^(1/6)    9/8     False      False      False      | False
3   2^(1/4)    6/5     True       False      True       | True
4   2^(1/3)    5/4     True       False      True       | True
5   2^(5/12)   4/3     True       False      True       | True
6   Sqrt[2]    7/5     True       True       False      | False
7   2^(7/12)   3/2     True       False      True       | True
8   2^(2/3)    8/5     True       False      True       | True
9   2^(3/4)    5/3     True       False      True       | True
10  2^(5/6)    7/4     True       True       False      | False
11  2^(11/12)  11/6    False      False      False      | False
12  1          1       True       False      True       | True

A aproximação racional está dentro 1/17do intervalo, porque esse é o maior limite que distingue entre os 12 intervalos temperados iguais. Combinamos números racionais com o padrão Rational[a_,b_](ou apenasa_~_~b_ ) primeiro e depois os inteiros com apenas _.

Isso culmina na seguinte função bastante curta que determina se uma taxa de frequência arbitrária (maior que 1) é consoante ou dissonante.

Rationalize[#,1/17]/.{a_~_~b_:>b<=5&&!a∣7,_->True}&       [Fsharp3/C3]     51+9=60
hftf
fonte
1
Puxa, não me diga Mathematica tem um builtin mesmo para este ...: D
Ramillies
3

Mathematica, 118 bytes

FreeQ[{1,2,6,10,11},Min@Mod[Differences[Min@Position["C|C#|D|D#|E|F|F#|G|G#|A|A#|B"~StringSplit~"|",#]&/@{#,#2}],12]]&


Formulário de entrada

["DE ANÚNCIOS"]

Saídas

True->Consonant  
False->Dissonant   

obrigado @JonathanFrech -16 bytes

J42161217
fonte
Apenas uma observação: você não precisa produzir strings Consonante Dissonant. Você pode gerar dois valores em vez deles (0/1, ... qualquer que seja). Isso pode economizar alguns bytes.
Ramillies
1
Você não pode omitir If[...,0,1]e definir True->Consonant; False->Dissonant?
Jonathan Frech
1
StringCases["CC#DD#EFF#GG#AA#B",_~~"#"...]# 42 Bytes
celtschk
1
Além disso, 2 bytes podem ser salvos substituindo {1,2,6,10,11}por1|2|6|10|11
celtschk
1
@ Skyler Veja a resposta abaixo.
Hftf #
3

Carvão , 30 bytes

≔B#A#G#FE#D#C槔o∧⌈ς”⁻⌕ζ⮌θ⌕ζ⮌η

Experimente online! Link é a versão detalhada do código. Saídas 1 para consoante, 0 para dissonante. Explicação:

≔B#A#G#FE#D#Cζ                  Store reversed note names in z
                        θ       First input
                       ⮌        Reversed
                     ⌕ζ         Find index in z
                            η   Second input
                           ⮌    Reversed
                         ⌕ζ     Find index in z
                     ⁻          Subtract
               ”o∧⌈ς”           Compressed string 100111011100
              §                 Circularly index
                                Implicitly print
Neil
fonte
por curiosidade, existe um motivo mnemônico pelo qual o glifo ⌕ζé usado para "encontrar índice"?
Jonah
@Jonah ζé a variável atribuída anteriormente.
Neil
2

J, 68 bytes

[:e.&1 2 6 10 11[:(12| -~/)(<;._1',C,C#,D,D#,E,F,F#,G,G#,A,A#,B')i.]

explicação

Uma implementação direta e não super-golfe em J:

  • A entrada é fornecida como notas detalhadas em caixas (produzidas usando corte), em ordem.

  • Encontre seus índices no intervalo de notas: (<;._1',C,C#,D,D#,E,F,F#,G,G#,A,A#,B')i.]

  • Subtraia o primeiro do segundo: -~/

  • Pegue o restante quando dividido por 12: 12|

  • Verifique se é uma das notas dissonantes: e.&1 2 6 10 11

Experimente online!

Jonah
fonte
2

/// , 90 88 bytes

/^/"\///^\/\///C^D/##"E/DD"F/E#"G/FD"A/GD"B/AD"#,#/,"B#^B/#"A#/#"A^G#^G^F#/#"F^E^D#^D/#/

Experimente online! (todos os casos de teste de uma vez)

  • Coloque a entrada após o código.
  • Separe os nomes das notas com ,B# em cada caso de teste.
  • A saída é ,para consoante,,# para dissonante.
  • Suporte para alterações duplas ( ##) ou E#em alguns casos particulares. Caso contrário, a saída é ,para consoante, #,para dissonante (graças à simetria do módulo 12)
  • Pode lidar com vários casos de teste de uma só vez (se separados razoavelmente)
  • Caracteres minúsculos são impressos exatamente.
user202729
fonte
2

C (gcc) , 91 bytes

g(char*s){return (s[1]&1|2**s&15)*4/5;}f(char*x,char*y){return (1952220<<g(x)>>g(y))&2048;}

ligar: f("A#", "D")

Valor de retorno:

  • Consoante: 2048
  • Dissonant: 0

Bônus: A função não diferencia maiúsculas de minúsculas.

Experimente online!

celtschk
fonte
Não existem dois espaços desnecessários em ambos os return (s?
Jonathan Frech
Você pode tentar uma g(char*s){s=(s[1]&1|2**s&15)*4/5;}f(char*x,char*y){x=1952220<<g(x)>>g(y)&2048;}boa solução!
Keyu Gan
1

Python 2, 125 117 83 78 77 bytes

a,b=map("C C#D D#E F F#G G#A A#B".index,input())
print chr(abs(a-b))in""

Onde ""no final, na verdade, contém os caracteres"\x02\x04\x0c\x14\x16"

Experimente Online!

(+3 porque esqueci 11 ou 22 na lista, para começar)

-8 bytes de Jonathan Frech e alternando para Python 2 .

-34 bytes com sugestões de Jonathan Frech e usando stro índice em vez delist .

-4 bytes de inlining ie Neil invertendo a sugestão de string (apenas -2 realmente, como esqueci em ()torno de um gerador)

-5 bytes de inline i e alterando o formato de entrada

-1 bytes de Jonathan Frech com map() e não imprimíveis.

Recebe entrada em uma linha de stdin no formato:

'C','C#'

True é dissonante, False é consoante.

Explicação antiga:

i='C C#D D#E F F#G G#A A#B'.index
a,b=input()
print abs(i(a)-i(b))in[2,4,12,20]

Python str.indexretorna o menor índice inicial (positivo) de uma substring correspondente, so "ABACABA".index("A") == 0e "ABACABA".index("BA") == 1. Por esse motivo, podemos colocar os nomes das notas espaçados igualmente em uma sequência e, desde que (por exemplo) Avenha antes A#, o compartilhamento Anão será um problema.

i='C C#D D#E F F#G G#A A#B'.index

iagora é uma função que retorna o índice em 'C C#D D#E F F#G G#A A#B'seu argumento (um nome de nota), que é 2 * (o número de semitons dessa nota C)

a,b=input()

O Python 2 input()é (na maior parte) equivalente ao eval(input())Python3, portanto, com uma entrada válida do formato 'C#','F'(por exemplo) a='C#'eb='F'

print abs(i(a)-i(b))in[2,4,12,20]

Se a distância entre a primeira nota e a segunda nota na sequência não for 2, 4, 12 ou 20 (como os nomes das notas estão representados em 2 caracteres), o intervalo é dissonante, imprima True, caso contrário, é consoante, imprimir Falso.

pizzapants184
fonte
Como o formato de entrada não é estrito, você pode usar eval(input())(13 bytes) em vez de input().split()(15 bytes).
Jonathan Frech
101 bytes
Jonathan Frech
98 bytes
Jonathan Frech
79 bytes
Jonathan Frech
1
Você pode usar caracteres Unicode ( ) em vez de uma sequência vazia.
Jonathan Frech
1

C (gcc) , 115117 120 bytes

g(char*a){a=*a-65+!!a[1]*(7-*a/70-*a/67);}f(x,y)char*x,*y;{x="(pP$HL<lt<X"[g(x)]*32+"=ZukW-^h1F6"[g(x)]>>g(y)&1;}

Experimente online!

Retorne 1/0 para consonat e dissonat. É sempre interessante fazer a manipulação de strings com C. puro.f("A#", "C")

Keyu Gan
fonte
0

PowerShell , 107 bytes

param($a,$b)[math]::abs(($x=-split'C C# D D# E F F# G G# A A# B').indexof($b)-$x.indexof($a))-in1,2,6,10,11

Experimente online!

Saídas Truepara dissonante e Falseconsoante.

Recebe entrada $ae $b, as duas notas, como seqüências de caracteres. Executa uma -splitoperação na balança, que se divide em espaço em branco, para criar uma matriz de notas e as armazena $x. Localiza o .indexof $bnessa matriz, subtrai o índice de $ae, em seguida, obtém o absvalor olute. Verifica se esse número é -ino intervalo dissonante.

AdmBorkBork
fonte
0

Python 2 , 68 bytes

lambda a,b,f='C C#D D#E F F#G G#A A#B'.find:3142>>(f(a)-f(b))/2%12&1

Experimente online!

Saídas: 1é dissonante, 0é consoante.

Lynn
fonte
0

SQL, 582 bytes

SQL Fiddle

Eu ainda tenho algum golfe para fazer, mas eu queria pegá-lo aqui antes que acabasse quebrando completamente.

Se a entrada estiver em um formato de letra, colocar essas letras em uma tabela com valores é aceitável, certo?

CREATE TABLE N(N char(2),v int)
Insert Into N values('A',1),('A#',2),('B',3),('C',4),('C#',5),('D',6),('D#',7),('E',8),('F',9),('F#',10),('G',11),('G#',12);
CREATE TABLE D(D char(9),v int) 
Insert Into D values('C',0),('D',1),('D',2),('C',3),('C',4),('C',5),('D',6);
CREATE FUNCTION I(@A char(2),@B char(2))
RETURNS char(9) as
BEGIN
DECLARE @E int=(SELECT v from N where n=@A),@F int=(SELECT v from N where n=@B)
DECLARE @C char(9) = (SELECT case D when 'D' then 'Dissonant' when 'C' then 'Consonant' END from D where v in(abs(@e-@f),12-abs(@e-@f)))
RETURN isnull(@C,'NotANote')
END
phroureo
fonte
0

Perl 5 , 106 bytes

("C,C#,D,D#,E,F,F#,G,G#,A,A#,B,"x2)=~/$F[0],(.*?)$F[1],/;$r=(1+($1=~y/,//))%12;say(grep/$r/,(0,3..5,7..9))

Experimente online!

Retorna false para dissonante, true para consoante.

Xcali
fonte