Rafraîchissement musical rapide:
Le clavier de piano se compose de 88 notes. Sur chaque octave, il y a 12 notes, C, C♯/D♭, D, D♯/E♭, E, F, F♯/G♭, G, G♯/A♭, A, A♯/B♭
et B
. Chaque fois que vous frappez un «C», le motif se répète une octave plus haut.
Une note est identifiée de manière unique par 1) la lettre, y compris les aigus ou plats, et 2) l'octave, qui est un nombre compris entre 0 et 8. Les trois premières notes du clavier sont A0, A♯/B♭
et B0
. Après cela vient la pleine échelle chromatique sur les octaves 1. C1, C♯1/D♭1, D1, D♯1/E♭1, E1, F1, F♯1/G♭1, G1, G♯1/A♭1, A1, A♯1/B♭1
et B1
. Après cela vient une gamme chromatique complète sur les octaves 2, 3, 4, 5, 6 et 7. Ensuite, la dernière note est a C8
.
Chaque note correspond à une fréquence dans la gamme 20-4100 Hz. Avec un A0
démarrage à exactement 27,500 hertz, chaque note correspondante est la note précédente multipliée par la douzième racine de deux, soit environ 1,059463. Une formule plus générale est la suivante:
où n est le numéro de la note, A0 étant 1. (Plus d'informations ici )
Le défi
Écrivez un programme ou une fonction qui prend une chaîne représentant une note et imprime ou renvoie la fréquence de cette note. Nous utiliserons un signe #
dièse pour le symbole pointu (ou un hashtag pour vous les jeunes) et un minuscule b
pour le symbole plat. Toutes les entrées ressembleront (uppercase letter) + (optional sharp or flat) + (number)
sans espace blanc. Si l'entrée est en dehors de la plage du clavier (inférieure à A0 ou supérieure à C8), ou s'il y a des caractères non valides, manquants ou supplémentaires, il s'agit d'une entrée non valide et vous n'avez pas à la gérer. Vous pouvez également supposer en toute sécurité que vous n'obtiendrez pas d'entrées étranges telles que E # ou Cb.
Précision
Comme une précision infinie n'est pas vraiment possible, nous dirons que tout ce qui se trouve à moins d' un cent de la valeur réelle est acceptable. Sans entrer dans les détails, un cent est la 1200e racine de deux, ou 1.0005777895. Prenons un exemple concret pour le rendre plus clair. Disons que votre entrée était A4. La valeur exacte de cette note est de 440 Hz. Une fois que cent est plat 440 / 1.0005777895 = 439.7459
. Une fois que cent est net 440 * 1.0005777895 = 440.2542
, tout nombre supérieur à 439.7459 mais inférieur à 440.2542 est suffisamment précis pour compter.
Cas de test
A0 --> 27.500
C4 --> 261.626
F#3 --> 184.997
Bb6 --> 1864.66
A#6 --> 1864.66
A4 --> 440
D9 --> Too high, invalid input.
G0 --> Too low, invalid input.
Fb5 --> Invalid input.
E --> Missing octave, invalid input
b2 --> Lowercase, invalid input
H#4 --> H is not a real note, invalid input.
Gardez à l'esprit que vous n'avez pas à gérer les entrées non valides. Si votre programme prétend qu'il s'agit de véritables entrées et affiche une valeur, cela est acceptable. Si votre programme plante, c'est également acceptable. Tout peut arriver quand vous en avez un. Pour la liste complète des entrées et sorties, voir cette page
Comme d'habitude, il s'agit de code-golf, donc les lacunes standard s'appliquent et la réponse la plus courte en octets l'emporte.
H
?H
ce qui signifie que B est AFAIK uniquement utilisé dans les pays germanophones. (oùB
signifie Bb au fait.) Ce que les Britanniques et les Irlandais appellent B est appelé Si ou Ti en Espagne et en Italie, comme dans Do Re Mi Fa Sol La Si.H
est utilisé en Allemagne, en République tchèque, en Slovaquie, en Pologne, en Hongrie, en Serbie, au Danemark, en Norvège, en Finlande, en Estonie et en Autriche, selon Wikipedia . (Je peux également le confirmer pour la Finlande moi-même.)Réponses:
Japt,
41373534 octetsJ'ai enfin une chance d'en faire
¾
bon usage! :-)Essayez-le en ligne!
Comment ça marche
Cas de test
Tous les cas de test valides passent bien. Ce sont les invalides où ça devient bizarre ...
la source
Pyth,
464443423935 octetsEssayez-le en ligne. Suite de tests.
Le code utilise maintenant un algorithme similaire à la réponse Japt d'ETHproductions , alors merci à lui pour cela.
Explication
Ancienne version (42 octets, 39 avec chaîne compressée)
Explication
Afficher l'extrait de code
la source
Mathematica, 77 octets
Explication :
L'idée principale de cette fonction est de convertir la chaîne de notes à sa hauteur relative, puis de calculer sa fréquence.
La méthode que j'utilise est d'exporter le son vers midi et d'importer les données brutes, mais je soupçonne qu'il existe une manière plus élégante.
Cas de test :
la source
MATL ,
56535049 48 octetsUtilise la version actuelle (10.1.0) , antérieure à ce défi.
Essayez-le en ligne !
Explication
la source
JavaScript ES7,
737069 octetsUtilise la même technique que ma réponse Japt .
la source
Rubis,
6965Non testé dans le programme de test
Production
la source
ES7, 82 octets
Renvoie 130.8127826502993 à l'entrée de "B # 2" comme prévu.
Edit: sauvé 3 octets grâce à @ user81655.
la source
2*3**3*2
est 108 dans la console du navigateur de Firefox, ce qui est d'accord2*(3**3)*2
. Notez également que cette page indique également que la?:
priorité est plus élevée que,=
mais qu'ils ont en fait une priorité égale (à considérera=b?c=d:e=f
).**
donc je n'ai jamais pu le tester. Je pense?:
que la priorité est plus élevée que=
dans la mesure où, dans votre exemple,a
le résultat est le ternaire, plutôt que l'b
exécution du ternaire. Les deux autres affectations sont incluses dans le ternaire, elles sont donc un cas spécial.e=f
intérieur du ternaire?a=b?c=d:e=f?g:h
. S'ils avaient la même priorité et que le premier ternaire se terminait à la=
fine
, cela provoquerait une erreur d'affectation gauche non valide.?:
avait une priorité plus élevée que de=
toute façon. L'expression doit se regrouper comme si elle l'étaita=(b?c=d:(e=(f?g:h)))
. Vous ne pouvez pas faire cela s'ils n'ont pas la même priorité.C, 123 octets
Usage:
La valeur calculée est toujours environ 0,8 cents inférieure à la valeur exacte, car j'ai coupé autant de chiffres que possible des nombres à virgule flottante.
Aperçu du code:
la source
R,
157150141136 octetsAvec retrait et nouvelles lignes:
Usage:
la source
Python,
9795 octetsBasé sur l'ancienne approche de Pietu1998 (et d'autres) consistant à rechercher l'index de la note dans la chaîne
'C@D@EF@G@A@B'
pour un caractère vierge ou un autre. J'utilise le déballage itérable pour analyser la chaîne de notes sans condition. J'ai fait un peu d'algèbre à la fin pour simplifier l'expression de conversion. Je ne sais pas si je peux le raccourcir sans changer mon approche.la source
b==['#']
pourrait être raccourci à'#'in b
, etnot b
àb>[]
.Wolfram Language (Mathematica), 69 octets
Utiliser le package musical , avec lequel la simple saisie d'une note en tant qu'expression évalue sa fréquence, comme ceci:
Pour enregistrer les octets en évitant d'importer le paquet avec
<<Music
, j'utilise les noms qualifiés:Music`Eflat3
. Cependant, je dois encore remplacerb
parflat
et#
parsharp
pour correspondre au format d'entrée de la question, ce que je fais avec un simpleStringReplace
.la source