Consonance ou dissonance?

36

Avec deux noms de notes, vous devez écrire un programme qui détermine si l’intervalle formé par ces deux notes est consonant ou dissonant.

introduction

Dans la musique occidentale, il n'y a que 12 tonalités "différentes". Leurs noms, classés du plus bas au plus élevé, sont les suivants C, C#, D, D#, E, F, F#, G, G#, A, A#, B:. La séquence est cyclique, c’est-à-dire qu’elle continue avec une autre Caprès le B, infiniment.

La distance entre deux tons est appelée un intervalle . L’intervalle entre deux notes adjacentes dans la série ci-dessus (par exemple C — C#ou E — F) est appelé un demi - ton . L'intervalle entre les notes les plus distantes est défini comme le nombre de demi-tons nécessaires pour aller du premier au second (tout en encerclant éventuellement la séquence). Quelques exemples: D to E= 2 demi-tons, C to G= 7 demi-tons, B to D#= 4 demi-tons (ceci encapsule la séquence). 1

Maintenant, ces intervalles sont divisés en deux catégories: consonne (qui sonne agréablement si vous jouez les deux notes en même temps) et dissonante (pas tellement).

Définissons les intervalles de consonne comme suit: 0, 3, 4, 5, 7, 8 et 9 demi-tons.

Le reste est dissonant, à savoir: 1, 2, 6, 10 et 11 demi-tons.

Le défi

Ecrivez un "programme" (au sens large du terme: une fonction est parfaitement OK) pour effectuer les opérations suivantes:

  • Prenez deux noms de notes (des chaînes de la séquence ci-dessus) comme entrée. Vous pouvez les prendre à votre guise (depuis stdin, comme arguments, séparés par tout ce que vous voulez, vous pouvez même les prendre comme une liste de caractères (par exemple ["C","#"]). Cependant, vous ne pouvez attribuer aucun autre nom aux notes (en particulier vous. peut ne pas les numéroter de 0 à 11 et utiliser les chiffres).

  • Pour vous les geeks de la musique, les notes seront spécifiées sans l'octave. Dans ce cas également, l’ordre dans lequel les notes arrivent et les notes les plus basses et les plus importantes importe peu. Enfin, vous n'avez pas besoin de gérer des noms qui ne figurent pas dans la liste ci-dessus. Aucune autre harmonie comme E#, pas de bémol, de double altération, etc.

  • Choisissez deux valeurs différentes. Votre programme doit sortir l’une d’entre elles chaque fois que l’intervalle formé par les deux notes de l’entrée est consonne, et l’autre si elles ne le sont pas. (Pourrait être Trueet False, mais même π et e si vous voulez :))

  • Ceci est un code-golf. Le programme le plus court en octets dans chaque langue gagne. S'amuser!

Exemples et cas de test

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

Je n'en ajoute pas davantage car il n'y a pas de cas particulièrement perfides dans ce domaine.

C'est un de mes premiers défis, toute critique constructive est donc la bienvenue :—). Si vous trouvez l'explication théorique bâclée, n'hésitez pas à poser des questions. Enfin, s'il vous plaît, ne me dites pas que c'est dupe de ceci ou de ceci . J'ai fait en sorte que ce ne soit pas. (Ce dernier est assez similaire mais plus complexe. Je pensais que relever un défi un peu plus simple faciliterait l'adhésion des gens.)


1 : J'ai essayé de simplifier cette explication dans la mesure du possible. Il y a beaucoup plus de théorie autour des intervalles. S'il vous plaît ne me reproche pas de l'avoir laissé.

Ramillies
la source

Réponses:

12

Gelée , 21 octets

Prend la saisie sous forme de liste de deux chaînes. Retour 0pour dissonant ou 1pour consonne.

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

Essayez-le en ligne!

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

Making-of

Notons d’abord que la fonction F recherchée est commutative: pour toute paire de notes (A, B) , nous avons F (A, B) = F (B, A) .

Puisqu'il n'y a pas trop d'entrées possibles et seulement 2 sorties possibles à gérer, il doit être possible de trouver une fonction de hachage plutôt simple H , telle que | H (A) - H (B) | produit une plage de valeurs limitée et est sans collision pour toutes les paires de notes possibles (A, B) par rapport à la sortie attendue.

Nous allons tester l'ensemble des fonctions H (mul, mod) , définies comme suit:

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

ORD(s[0])est le code ASCII du premier caractère de la note et LEN(s)sa longueur ( 2 s'il y a un '#'et 1 sinon).

Vous trouverez ci-dessous une version commentée du code JS qui a été utilisée pour trouver quelques paires valides (mul, mod) et les masques de bits résultants. Il existe de nombreuses solutions possibles, mais * 6 % 21c'est la plus courte avec cette méthode.

Arnauld
la source
3
Comment trouvez-vous même ces choses? ... Obtenez-vous ce genre de "algorithmes" à la main ou par force brute? Et quelle que soit la réponse à la deuxième question: comment?! ..: S " littéral entier 540205; décalé à droite de (code ASCII; multiplier par 6; modulo 21; garder le premier; soustraire à la longueur ...); bitwise-AND 1 ". Vos réponses continuent de m'impressionner à chaque fois ..
Kevin Cruijssen le
@KevinCruijssen J'ai ajouté le code JS d'origine utilisé pour rechercher ces valeurs.
Arnauld
Merci pour l'explication ajoutée. Je suis toujours aussi impressionné qu'au début, mais vous avez clairement expliqué comment vous en êtes arrivé à ce résultat. Dommage que je ne puisse voter qu'une fois.
Kevin Cruijssen le
9

APL (Dyalog) , 62 39 octets

Les utilisations ⎕IO←0; 0 est une consonne, 1 est dissonant. Prend la liste des caractères de la note de base comme argument de gauche et la liste des objets tranchants comme argument de droite.

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

Essayez-le en ligne!

{} Fonction anonyme où est l'argument de gauche et l'argument de droite

⎕A[... ]∊'BCGKL' est le A lphabet, indexé par la suite, un membre de la chaîne?

  ⍕# formate l'espace de noms racine (donne le caractère pointu)

  ⍵= les bons arguments (les dièses) sont-ils égaux à cela?

  ()+ Ajouter ce qui suit:

   'C D EF G A '⍳⍺ indices des caractères d'argument de gauche dans la chaîne

  -/ différence entre ceux

  | valeur absolue

Uriel
la source
Souhaitez-vous ajouter une explication à ceux d’entre nous qui ne connaissons pas APL?
Draconis
@Draconis Explication ajoutée.
Adám
9

MATL , 30 27 26 octets

,j'DJEFPGIALBC'&mQs]ZP7Mdm

Entre les deux notes sur des lignes différentes. Sorties 0pour consonne, 1pour dissonant.

Essayez-le en ligne! Ou vérifiez tous les cas de test .

Explication

La chaîne de 11 caractères

DJEFPGIALBC

code à la fois les notes et les intervalles dissonants, comme suit.

Le programme trouve d’ abord les indices 1 des caractères saisis dans la chaîne ci-dessus. Une entrée non-nette telle Dque donnerons 1, Edonnerons 3, ... Cdonnerons 11. Ces nombres peuvent également être considérés comme des tableaux numériques 1 × 1. Une entrée nette comme C#va donner le tableau 1 × 2 [11 0], ce qui signifie que l’ Con a trouvé à la position 11et #n’a pas été trouvé.

Observez que les lettres JPILne seront jamais présentes dans l'entrée. Pour l'instant, ils ne sont utilisés que comme espaces réservés, de sorte que, par exemple, note Eest deux demi-tons ci-dessus D. Mais ils seront également utiles pour définir des intervalles dissonants.

Les nombres de la première entrée du tableau 1 × 1 ou 1 × 2 correspondent à la hauteur de la note par demi-tons, sans compter les symboles nets (pour le moment). Observez que l’échelle définie par ces nombres ne commence pas par C; mais cela n'a pas d'importance parce que nous ne voulons que des intervalles, c'est-à-dire des différences entre les notes. Soustraire les nombres obtenus donnerait soit l'intervalle, soit 12 moins l'intervalle. Mais nous devons d’abord considérer le symbole aigu.

Pour prendre en compte les notes pointues, une méthode amusante (en MATL) consiste à ajouter 1à chaque entrée du tableau 1 × 1 ou 1 × 2 obtenu précédemment, puis à additionner le tableau (2 octets). Ainsi, les notes non-aiguës sont augmentées 1et les notes aiguës par 2. Cela rend les notes aiguës 1 demi-ton plus élevés que les notes non aiguës, selon les besoins. Nous ajoutons également un demi-ton supplémentaire à toutes les notes, mais cela ne modifie pas les intervalles entre elles. Alors maintenant, la note Dva donner le numéro de hauteur 2, D#donner 3, ..., Cdonner 12, donner , C#donner 13.

Intervalles dissonants sont 1, 2, 6, 10ou 11. Celles-ci ont une symétrie modulo-12 : un intervalle entre deux notes est dissonant si et seulement si l'intervalle avec les notes dans l'ordre inverse, modulo 12, est dissonant.

Si nous calculons les différences consécutives de la chaîne, 'DJEFPGIALBC'nous obtenons le vecteur numérique

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

qui contient précisément les intervalles dissonants, en plus de quelques valeurs négatives, qui ne seront ni utiles ni nuisibles. Remarquez que c'est le choix de lettres supplémentaires JPILdans la chaîne 'DJEFPGIALBC'qui définit (via des différences consécutives) les intervalles dissonants.

Pour voir si les deux notes d'entrée sont dissonantes, prenons la différence absolue entre leurs nombres de hauteur. Par exemple, Cet D#donnera des chiffres 12et 3respectivement, et la différence absolue est 9. La différence réelle serait -9, et l'intervalle réel serait 3(obtenu comme -9modulo 12). Mais grâce à la symétrie évoquée ci-dessus, on peut envisager 9au lieu de 3. Comme 9n'est pas présent dans le vecteur de différences consécutives, les notes sont en consonne.

Luis Mendo
la source
2
J'aime la façon dont vous avez encodé les notes et les intervalles dissonants dans la même chaîne.
celtschk
8

JavaScript (ES6), 68 64 octets

Prend les notes comme deux chaînes dans la syntaxe de currying (a)(b). Retour 0pour dissonant ou 1pour consonne.

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

Cas de test

Formaté et commenté

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
la source
7

Gelée , 26 octets

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

Un lien monadique prenant une liste des deux notes (sous forme de listes de caractères) et renvoyant 0pour consonne et 1pour dissonant.

Essayez-le en ligne! ou voir toutes les entrées dans la suite de tests .

Comment?

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
la source
5

Gelée , 31 octets

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

Essayez-le en ligne!

wheeeeee 32 octets trop long

Explication

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
la source
Hé, c'est une excellente réponse! Je me demandais si quelqu'un utilisait la symétrie, et vous l'avez fait. Et j'aime bien votre méthode pour faire correspondre les noms de notes avec des nombres! +1
Ramillies
La différence de demi-ton peut être symétrique, mais vous obtenez toujours des résultats erronés - par exemple "G#", "A"(dissonant),11[1,2,6] vous obtenez une différence qui n’est pas présente .
Jonathan Allan
@ JonathanAllan oh euh bien c'est embarrassant; Je pensais que la différence absolue corrigeait cela ... ._. va réparer lol
HyperNeutrino
1
@JonathanAllan fixé pour quelques octets supplémentaires (3 IIRC)
HyperNeutrino
4

Mathematica, 55 octets

function                                                  arguments        bytes

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

Mappez les éléments internes intégrés Sound`PitchToNumbersur l'entrée (liste de deux chaînes), prenez la différence absolue, puis réglez le modèle pour les nombres d'intervalles dissonants.


Juste pour le plaisir (non compétitif)

Voici quelques fonctions plus courtes qui violent la restriction «vous ne pouvez attribuer aucun autre nom aux notes». Le paquetage rudimentaireMusic` a des constantes de note prédéfinies (comme A4 = 440.) et la fonction HertzToCents(pouvant être jouée au golf). Au lieu de chaînes, nous utiliserons les constantes de note comme arguments, mais dans un format différent pour chaque fonction.

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

L'importation de package <<Music`;prend 9 octets.

Cette fonction convertit une chaîne (comme "F#") en une constante de note (comme Fsharp3):

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

Pour accepter des intervalles supérieurs à une octave, remplacez Abs[…]par Mod[…,12].


Pourquoi certains intervalles sont-ils considérés comme dissonants? Un intervalle est un rapport de deux fréquences. Si le rapport a un numérateur et un dénominateur «simples», il a tendance à être plus consonne. Dans le réglage à 5 limites , les rapports peuvent être décomposés en puissances entières composées uniquement de nombres premiers inférieurs ou égaux à 5. Aucun intervalle de tempérament égal, à part l'octave, n'est un intervalle juste ; ils ne sont que des approximations proches utilisant les puissances de la 12ème racine de 2.

Au lieu de coder en dur les nombres d'intervalles dissonants, nous pouvons trouver une approximation rationnelle de l'intervalle et déterminer ensuite si son numérateur et son dénominateur sont «simples» (ce qui signifie que le dénominateur est inférieur à 5 et que le rapport ne divise pas 7).

Ce tableau montre chacune des étapes de ce processus.

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

L’approximation rationnelle se situe à l’intérieur 1/17de l’intervalle, car c’est le seuil le plus grand qui distingue les 12 intervalles tempérés égaux. Nous faisons d'abord correspondre les nombres rationnels avec le modèle Rational[a_,b_](ou juste a_~_~b_), puis les nombres entiers avec seulement _.

Cela aboutit à la fonction assez courte suivante qui détermine si un rapport de fréquence arbitraire (supérieur à 1) est consonne ou dissonant.

Rationalize[#,1/17]/.{a_~_~b_:>b<=5&&!a∣7,_->True}&       [Fsharp3/C3]     51+9=60
hftf
la source
1
Gosh, ne me dites pas que Mathematica a une méthode intégrée, même pour cela ...: D
Ramillies
3

Mathematica, 118 octets

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]]&


Formulaire de saisie

["UN D"]

Les sorties

True->Consonant  
False->Dissonant   

merci @JonathanFrech -16 octets

J42161217
la source
Juste une remarque: vous n'avez pas besoin de sortir des chaînes Consonantet Dissonant. Vous pouvez sortir deux valeurs quelconques à la place (0/1, ... peu importe). Cela pourrait économiser des octets.
Ramillies
1
Ne pouvez-vous pas omettre le If[...,0,1]et définir True->Consonant; False->Dissonant?
Jonathan Frech
1
StringCases["CC#DD#EFF#GG#AA#B",_~~"#"...]- 42 octets
celtschk le
1
Vous pouvez également enregistrer 2 octets en les remplaçant {1,2,6,10,11}par1|2|6|10|11
celtschk le
1
@Skyler Voir la réponse ci-dessous.
hftf
3

Charbon de bois , 30 octets

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

Essayez-le en ligne! Le lien est vers la version verbeuse du code. Sorties 1 pour consonne, 0 pour dissonant. Explication:

≔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
la source
par curiosité, y a-t-il une raison mnémonique pour laquelle le glyphe ⌕ζest utilisé pour "trouver l'index"?
Jonah
@Jonah ζest la variable affectée à plus tôt.
Neil
2

J, 68 octets

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

explication

Une implémentation simple, pas super golfée en J:

  • Les entrées sont données sous forme de notes détaillées encadrées (produites à l'aide de cut), dans l'ordre.

  • Retrouvez leurs index dans la gamme de notes: (<;._1',C,C#,D,D#,E,F,F#,G,G#,A,A#,B')i.]

  • Soustrayez le premier du deuxième: -~/

  • Prenez le reste divisé par 12: 12|

  • Vérifiez si c'est l'une des notes dissonantes: e.&1 2 6 10 11

Essayez-le en ligne!

Jonas
la source
2

/// , 90 88 octets

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

Essayez-le en ligne!(tous les cas de test à la fois)

  • Mettez l'entrée après le code.
  • Séparez les noms de notes avec ,B# dans chaque cas de test.
  • La sortie est ,pour consonne,,# pour dissonant.
  • Prise en charge des doubles modifications ( ##) ou E#dans certains cas particuliers. Sinon, la sortie est ,pour consonne, #,pour dissonante (grâce à la symétrie modulo 12)
  • Peut gérer plusieurs cas de test à la fois (si raisonnablement séparés)
  • Les caractères minuscules sont imprimés exactement.
utilisateur202729
la source
2

C (gcc) , 91 octets

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

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

Valeur de retour:

  • Consonant: 2048
  • Dissonant: 0

Bonus: La fonction est insensible à la casse.

Essayez-le en ligne!

celtschk
la source
N'y a-t-il pas deux espaces inutiles dans les deux return (?
Jonathan Frech
Vous pouvez essayer une g(char*s){s=(s[1]&1|2**s&15)*4/5;}f(char*x,char*y){x=1952220<<g(x)>>g(y)&2048;}belle solution!
Keyu Gan
1

Python 2, 125 117 83 78 77 octets

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

Où le ""à la fin contient réellement les caractères"\x02\x04\x0c\x14\x16"

Essayez-le en ligne!

(+3 parce que j'ai oublié 11 ou 22 dans la liste pour commencer)

-8 octets de Jonathan Frech et passage à Python 2 .

-34 octets avec des suggestions de Jonathan Frech et utilisation strde l’index au lieu delist 's.

-4 octets d'inline iet de Neil inversant la suggestion de chaîne (seulement -2 vraiment, comme j'ai oublié() un générateur)

-5 octets de non-inlining i et modification du format d'entrée

-1 octets de Jonathan Frech avec map() et non imprimables.

Prend une entrée dans une ligne de stdin dans le format:

'C','C#'

True est dissonant, False est consonne.

Ancienne Explication:

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.indexrenvoie l'indice de départ le plus bas (positif) d'une sous-chaîne correspondante, ainsi "ABACABA".index("A") == 0et "ABACABA".index("BA") == 1. De ce fait, nous pouvons placer les noms de notes à intervalles réguliers dans une chaîne, et tant que (par exemple) Avient avant A#, le partage Ane posera pas de problème.

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

iest maintenant une fonction qui retourne l'index dans 'C C#D D#E F F#G G#A A#B'son argument (un nom de note), qui est 2 * (le nombre de demi-tons à partir duquel la note est active C)

a,b=input()

Python 2 input()équivaut (généralement) à eval(input())Python3, donc avec une entrée valide du format 'C#','F'(par exemple), a='C#'etb='F'

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

Si la distance entre la première note et la seconde note de la chaîne n'est pas 2, 4, 12 ou 20 (puisque les noms des notes sont représentés par 2 caractères), l'intervalle est dissonant, affiche True, sinon il est consonne, print False.

pizzapants184
la source
Le format d'entrée n'étant pas strict, vous pouvez utiliser eval(input())(13 octets) au lieu de input().split()(15 octets).
Jonathan Frech
101 octets
Jonathan Frech
98 octets
Jonathan Frech
79 octets
Jonathan Frech
1
Vous pouvez utiliser des caractères Unicode ( ) au lieu d'une chaîne vide.
Jonathan Frech
1

C (gcc) , 115117 120 octets

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

Essayez-le en ligne!

Retourne 1/0 pour consonat et dissonat. Il est toujours intéressant de manipuler des chaînes avec du C. pur.f("A#", "C")

Keyu Gan
la source
0

PowerShell , 107 octets

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

Essayez-le en ligne!

Sorties Truepour dissonant et Falsepour consonne.

Prend l'entrée $aet $b, les deux notes, sous forme de chaînes. Effectue une -splitopération sur la balance, qui se divise en espaces, pour créer un tableau des notes, les stocke dans $x. Trouve le .indexof $bdans ce tableau, soustrait l'index $a, puis en prend la absvaleur olute. Vérifie si ce nombre correspond -inaux plages dissonantes.

AdmBorkBork
la source
0

Python 2 , 68 octets

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

Essayez-le en ligne!

Sorties: 1est dissonant, 0est consonne.

Lynn
la source
0

SQL, 582 octets

Violon SQL

Il me reste encore du golf à faire, mais je voulais le faire ici avant de finir par le casser complètement.

Si l'entrée est au format lettre, il est correct de placer ces lettres dans un tableau avec des valeurs, n'est-ce pas?

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
la source
0

Perl 5 , 106 octets

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

Essayez-le en ligne!

Retourne false pour dissonant, true pour consonne.

Xcali
la source