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 C
aprè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
True
etFalse
, 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é.
APL (Dyalog) ,
6239 octetsLes 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.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 absoluela source
MATL ,
302726 octetsEntre les deux notes sur des lignes différentes. Sorties
0
pour consonne,1
pour dissonant.Essayez-le en ligne! Ou vérifiez tous les cas de test .
Explication
La chaîne de 11 caractères
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
D
que donnerons1
,E
donnerons3
, ...C
donnerons11
. Ces nombres peuvent également être considérés comme des tableaux numériques 1 × 1. Une entrée nette commeC#
va donner le tableau 1 × 2[11 0]
, ce qui signifie que l’C
on a trouvé à la position11
et#
n’a pas été trouvé.Observez que les lettres
JPIL
ne 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, noteE
est deux demi-tons ci-dessusD
. 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ées1
et les notes aiguës par2
. 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 noteD
va donner le numéro de hauteur2
,D#
donner3
, ...,C
donner12
, donner ,C#
donner13
.Intervalles dissonants sont
1
,2
,6
,10
ou11
. 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ériquequi 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
JPIL
dans 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,
C
etD#
donnera des chiffres12
et3
respectivement, et la différence absolue est9
. La différence réelle serait-9
, et l'intervalle réel serait3
(obtenu comme-9
modulo 12). Mais grâce à la symétrie évoquée ci-dessus, on peut envisager9
au lieu de3
. Comme9
n'est pas présent dans le vecteur de différences consécutives, les notes sont en consonne.la source
JavaScript (ES6),
6864 octetsPrend les notes comme deux chaînes dans la syntaxe de currying
(a)(b)
. Retour0
pour dissonant ou1
pour consonne.Cas de test
Afficher l'extrait de code
Formaté et commenté
la source
Gelée , 26 octets
Un lien monadique prenant une liste des deux notes (sous forme de listes de caractères) et renvoyant
0
pour consonne et1
pour dissonant.Essayez-le en ligne! ou voir toutes les entrées dans la suite de tests .
Comment?
la source
Gelée , 31 octets
Essayez-le en ligne!
wheeeeee 32 octets trop long
Explication
la source
"G#", "A"
(dissonant),11
[1,2,6]
vous obtenez une différence qui n’est pas présente .Mathematica, 55 octets
Mappez les éléments internes intégrés
Sound`PitchToNumber
sur 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 rudimentaire
Music`
a des constantes de note prédéfinies (commeA4 = 440.
) et la fonctionHertzToCents
(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.L'importation de package
<<Music`;
prend 9 octets.Cette fonction convertit une chaîne (comme
"F#"
) en une constante de note (commeFsharp3
):Pour accepter des intervalles supérieurs à une octave, remplacez
Abs[…]
parMod[…,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.
L’approximation rationnelle se situe à l’intérieur
1/17
de 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èleRational[a_,b_]
(ou justea_~_~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.
la source
Mathematica, 118 octets
Formulaire de saisie
Les sorties
merci @JonathanFrech -16 octets
la source
Consonant
etDissonant
. Vous pouvez sortir deux valeurs quelconques à la place (0/1, ... peu importe). Cela pourrait économiser des octets.If[...,0,1]
et définirTrue->Consonant; False->Dissonant
?StringCases["CC#DD#EFF#GG#AA#B",_~~"#"...]
- 42 octets{1,2,6,10,11}
par1|2|6|10|11
Charbon de bois , 30 octets
Essayez-le en ligne! Le lien est vers la version verbeuse du code. Sorties 1 pour consonne, 0 pour dissonant. Explication:
la source
⌕ζ
est utilisé pour "trouver l'index"?ζ
est la variable affectée à plus tôt.J, 68 octets
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!
la source
/// ,
9088 octetsEssayez-le en ligne!(tous les cas de test à la fois)
,B#
dans chaque cas de test.,
pour consonne,,#
pour dissonant.##
) ouE#
dans certains cas particuliers. Sinon, la sortie est,
pour consonne,#,
pour dissonante (grâce à la symétrie modulo 12)la source
C (gcc) , 91 octets
appel:
f("A#", "D")
Valeur de retour:
Bonus: La fonction est insensible à la casse.
Essayez-le en ligne!
la source
return (
?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!Python 2,
125 117 83 7877 octetsOù 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
str
de l’index au lieu delist
's.-4 octets d'inline
i
et 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:
True
est dissonant,False
est consonne.Ancienne Explication:
Python
str.index
renvoie l'indice de départ le plus bas (positif) d'une sous-chaîne correspondante, ainsi"ABACABA".index("A") == 0
et"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)A
vient avantA#
, le partageA
ne posera pas de problème.i
est 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 activeC
)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'
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.
la source
eval(input())
(13 octets) au lieu deinput().split()
(15 octets).
) au lieu d'une chaîne vide.C (gcc) , 115
117120octetsEssayez-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")
la source
PowerShell , 107 octets
Essayez-le en ligne!
Sorties
True
pour dissonant etFalse
pour consonne.Prend l'entrée
$a
et$b
, les deux notes, sous forme de chaînes. Effectue une-split
opération sur la balance, qui se divise en espaces, pour créer un tableau des notes, les stocke dans$x
. Trouve le.indexof
$b
dans ce tableau, soustrait l'index$a
, puis en prend laabs
valeur olute. Vérifie si ce nombre correspond-in
aux plages dissonantes.la source
Python 2 , 68 octets
Essayez-le en ligne!
Sorties:
1
est dissonant,0
est consonne.la source
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?
la source
Perl 5 , 106 octets
Essayez-le en ligne!
Retourne false pour dissonant, true pour consonne.
la source