Actualización musical rápida:
El teclado del piano consta de 88 notas. En cada octava, hay 12 notas, C, C♯/D♭, D, D♯/E♭, E, F, F♯/G♭, G, G♯/A♭, A, A♯/B♭
y B
. Cada vez que golpeas una 'C', el patrón se repite una octava más arriba.
Una nota se identifica de forma exclusiva por 1) la letra, incluidos los objetos punzantes o planos, y 2) la octava, que es un número del 0 al 8. Las primeras tres notas del teclado son A0, A♯/B♭
y B0
. Después de esto viene la escala cromática completa en la octava 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
y B1
. Después de esto viene una escala cromática completa en las octavas 2, 3, 4, 5, 6 y 7. Luego, la última nota es a C8
.
Cada nota corresponde a una frecuencia en el rango de 20-4100 Hz. Con un A0
comienzo exacto de 27.500 hertzios, cada nota correspondiente es la nota anterior multiplicada por la duodécima raíz de dos, o aproximadamente 1.059463. Una fórmula más general es:
donde n es el número de la nota, con A0 siendo 1. (Más información aquí )
El reto
Escriba un programa o función que tome una cadena que represente una nota e imprima o devuelva la frecuencia de esa nota. Usaremos un signo de libra #
para el símbolo agudo (o el hashtag para ustedes, youngins) y una minúscula b
para el símbolo plano. Todas las entradas se verán (uppercase letter) + (optional sharp or flat) + (number)
sin espacios en blanco. Si la entrada está fuera del rango del teclado (menor que A0 o mayor que C8), o si hay caracteres no válidos, faltantes o extra, esta es una entrada no válida y no tiene que manejarla. También puede asumir con seguridad que no obtendrá entradas extrañas como E # o Cb.
Precisión
Como la precisión infinita no es realmente posible, diremos que cualquier cosa dentro de un centavo del valor verdadero es aceptable. Sin entrar en detalles excesivos, un centavo es la raíz número 1200 de dos, o 1.0005777895. Usemos un ejemplo concreto para hacerlo más claro. Digamos que su entrada fue A4. El valor exacto de esta nota es 440 Hz. Una vez que el centavo es plano 440 / 1.0005777895 = 439.7459
. Una vez que el centavo está afilado, por lo 440 * 1.0005777895 = 440.2542
tanto, cualquier número mayor que 439.7459 pero menor que 440.2542 es lo suficientemente preciso como para contar.
Casos de prueba
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.
Tenga en cuenta que no tiene que manejar las entradas no válidas. Si su programa finge que son entradas reales e imprime un valor, eso es aceptable. Si su programa falla, eso también es aceptable. Cualquier cosa puede suceder cuando obtienes uno. Para ver la lista completa de entradas y salidas, consulte esta página
Como de costumbre, este es el código de golf, por lo que se aplican las lagunas estándar y gana la respuesta más corta en bytes.
H
?H
lo que significa B es AFAIK solo utilizado en países de habla alemana. (dondeB
significa Bb por cierto.) Lo que los británicos e irlandeses llaman B se llama Si o Ti en España e Italia, como en Do Re Mi Fa Sol La Si.H
se usa en Alemania, República Checa, Eslovaquia, Polonia, Hungría, Serbia, Dinamarca, Noruega, Finlandia, Estonia y Austria, según Wikipedia . (También puedo confirmarlo para Finlandia.)Respuestas:
Japt,
41373534 bytes¡Finalmente tengo la oportunidad de darle
¾
un buen uso! :-)Pruébalo en línea!
Cómo funciona
Casos de prueba
Todos los casos de prueba válidos vienen bien. Son los inválidos donde se pone raro ...
fuente
Pyth,
464443423935 bytesPruébalo en línea. Banco de pruebas.
El código ahora usa un algoritmo similar a la respuesta Japt de ETHproductions , así que acéptelo por eso.
Explicación
Versión anterior (42 bytes, 39 con cadena empaquetada)
Explicación
Mostrar fragmento de código
fuente
Mathematica, 77 bytes
Explicacion :
La idea principal de esta función es convertir la cadena de nota a su tono relativo y luego calcular su frecuencia.
El método que uso es exportar el sonido a midi e importar los datos en bruto, pero sospecho que hay una forma más elegante.
Casos de prueba :
fuente
MATL ,
56535049 48 bytesUtiliza la versión actual (10.1.0) , que es anterior a este desafío.
Pruébalo en línea !
Explicación
fuente
JavaScript ES7,
737069 bytesUtiliza la misma técnica que mi respuesta Japt .
fuente
Rubí,
6965Sin golf en el programa de prueba
Salida
fuente
ES7, 82 bytes
Devuelve 130.8127826502993 en la entrada de "B # 2" como se esperaba.
Editar: Guardado 3 bytes gracias a @ user81655.
fuente
2*3**3*2
es 108 en la consola del navegador de Firefox, lo cual concuerda2*(3**3)*2
. También tenga en cuenta que esa página también dice que?:
tiene mayor prioridad que,=
pero en realidad tienen la misma prioridad (considerea=b?c=d:e=f
).**
así que nunca he podido probarlo. Creo?:
que tiene una precedencia más alta que=
aunque porque en su ejemploa
se establece el resultado del ternario, en lugar deb
ejecutar el ternario. Las otras dos tareas están encerradas en el ternario, por lo que son un caso especial.e=f
dentro del ternario?a=b?c=d:e=f?g:h
. Si tuvieran la misma precedencia y el primer ternario terminara=
despuése
, causaría un error de asignación de mano izquierda no válido.?:
tuviera mayor prioridad que de=
todos modos. La expresión necesita agruparse como si lo fueraa=(b?c=d:(e=(f?g:h)))
. No puedes hacer eso si no tienen la misma precedencia.C, 123 bytes
Uso:
El valor calculado siempre es aproximadamente 0,8 centavos menos que el valor exacto, porque corté tantos dígitos como sea posible de los números de coma flotante.
Descripción general del código:
fuente
R,
157150141136 bytesCon sangría y líneas nuevas:
Uso:
fuente
Python,
9795 bytesBasado en el antiguo enfoque de Pietu1998 (y otros) de buscar el índice de la nota en la cadena
'C@D@EF@G@A@B'
para algunos caracteres en blanco u otros. Utilizo el desempaquetado iterable para analizar la cadena de notas sin condicionales. Hice un poco de álgebra al final para simplificar la expresión de conversión. No sé si puedo acortarlo sin cambiar mi enfoque.fuente
b==['#']
podría acortarse a'#'in b
, ynot b
ab>[]
.Wolfram Language (Mathematica), 69 bytes
Usando el paquete de música , con el cual simplemente ingresando una nota como una expresión se evalúa su frecuencia, así:
Para guardar bytes evitando importar el paquete con
<<Music
, estoy usando los nombres completos:Music`Eflat3
. Sin embargo, todavía tengo que reemplazarb
conflat
y#
consharp
para que coincida con el formato de entrada de la pregunta, lo que hago con un simpleStringReplace
.fuente