Atualização musical rápida:
O teclado do piano consiste em 88 notas. Em cada oitava, há 12 notas C, C♯/D♭, D, D♯/E♭, E, F, F♯/G♭, G, G♯/A♭, A, A♯/B♭
e B
. Cada vez que você pressiona um 'C', o padrão repete uma oitava mais alta.
Uma nota é identificada exclusivamente por 1) a letra, incluindo objetos pontiagudos ou planos, e 2) a oitava, que é um número de 0 a 8. As três primeiras notas do teclado são A0, A♯/B♭
e B0
. Depois disso, vem a escala cromática completa na oitava 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
e B1
. Depois disso, aparece uma escala cromática completa nas oitavas 2, 3, 4, 5, 6 e 7. Em seguida, a última nota é a C8
.
Cada nota corresponde a uma frequência na faixa de 20-4100 Hz. Com o A0
início de exatamente 27.500 hertz, cada nota correspondente é a nota anterior multiplicada pela décima segunda raiz de duas, ou aproximadamente 1.059463. Uma fórmula mais geral é:
onde n é o número da nota, com A0 sendo 1. (Mais informações aqui )
O desafio
Escreva um programa ou função que use uma sequência que represente uma nota e imprima ou retorne a frequência dessa nota. Usaremos um sinal de libra #
para o símbolo nítido (ou hashtag para os jovens) e uma minúscula b
para o símbolo plano. Todas as entradas terão aparência (uppercase letter) + (optional sharp or flat) + (number)
sem espaço em branco. Se a entrada estiver fora do alcance do teclado (menor que A0 ou maior que C8) ou se houver caracteres inválidos, ausentes ou extras, esta é uma entrada inválida e você não precisa lidar com isso. Você também pode assumir com segurança que não receberá entradas estranhas, como E # ou Cb.
Precisão
Como a precisão infinita não é realmente possível, diremos que qualquer coisa dentro de um centavo do valor real é aceitável. Sem entrar em detalhes em excesso, um centavo é a 1200a raiz de dois, ou 1.0005777895. Vamos usar um exemplo concreto para torná-lo mais claro. Digamos que sua entrada foi A4. O valor exato desta nota é 440 Hz. Uma vez centavo é 440 / 1.0005777895 = 439.7459
. Uma vez que o centavo é nítido 440 * 1.0005777895 = 440.2542
, portanto, qualquer número maior que 439.7459, mas menor que 440.2542, é preciso o suficiente para contar.
Casos de teste
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.
Lembre-se de que você não precisa lidar com as entradas inválidas. Se o seu programa fingir que são entradas reais e imprimir um valor, isso é aceitável. Se o seu programa falhar, isso também é aceitável. Tudo pode acontecer quando você recebe um. Para a lista completa de entradas e saídas, consulte esta página
Como de costume, esse é um código de golfe, então as brechas padrão se aplicam e a resposta mais curta em bytes vence.
H
?H
o significado de B é AFAIK usado apenas em países de língua alemã. (ondeB
significa Bb, a propósito.) O que os britânicos e irlandeses chamam de B é chamado Si ou Ti na Espanha e na Itália, como em Do Re Mi Fa Sol La Si.H
é usado na Alemanha, República Tcheca, Eslováquia, Polônia, Hungria, Sérvia, Dinamarca, Noruega, Finlândia, Estônia e Áustria, de acordo com a Wikipedia . (Eu também posso confirmá-lo para a Finlândia).Respostas:
Japt,
41373534 bytesFinalmente tenho a chance de fazer
¾
bom uso! :-)Experimente online!
Como funciona
Casos de teste
Todos os casos de teste válidos são excelentes. São os inválidos onde fica estranho ...
fonte
Pitão,
464443423935 bytesExperimente online. Suíte de teste.
O código agora usa um algoritmo semelhante à resposta japonesa da ETHproductions , portanto, agradeça a ele por isso.
Explicação
Versão antiga (42 bytes, 39 com sequência compactada)
Explicação
Mostrar snippet de código
fonte
Mathematica, 77 bytes
Explicação :
A idéia principal dessa função é converter a seqüência de notas em sua afinação relativa e calcular sua frequência.
O método usado é exportar o som para o midi e importar os dados brutos, mas suspeito que exista uma maneira mais elegante.
Casos de teste :
fonte
MATL ,
56535049 48 bytesUsa a versão atual (10.1.0) , anterior a esse desafio.
Experimente online !
Explicação
fonte
JavaScript ES7,
737069 bytesUtiliza a mesma técnica da minha resposta em japonês .
fonte
Ruby,
6965Ungolfed in program program
Saída
fonte
ES7, 82 bytes
Retorna 130.8127826502993 na entrada de "B # 2" conforme o esperado.
Editar: salvou 3 bytes graças a @ user81655.
fonte
2*3**3*2
é 108 no console do navegador Firefox, o que concorda2*(3**3)*2
. Observe também que essa página também diz que?:
tem precedência maior do que,=
mas na verdade eles têm precedência igual (considerea=b?c=d:e=f
).**
portanto nunca fui capaz de testá-lo. Eu acho?:
que tem uma precedência mais alta do=
que no entanto, porque no seu exemploa
é definido o resultado do ternário, em vez deb
executar o ternário. As outras duas tarefas estão incluídas no ternário, portanto são um caso especial.e=f
interior do ternário?a=b?c=d:e=f?g:h
. Se eles tivessem a mesma precedência e o primeiro ternário terminasse=
depoise
, isso causaria um erro de atribuição à esquerda inválido.?:
tivesse maior precedência do que=
qualquer outra forma. A expressão precisa agrupar como se fossea=(b?c=d:(e=(f?g:h)))
. Você não pode fazer isso se eles não tiverem a mesma precedência.C, 123 bytes
Uso:
O valor calculado é sempre cerca de 0,8 centavos a menos do que o valor exato, porque cortei o maior número possível de dígitos nos números de ponto flutuante.
Visão geral do código:
fonte
R,
157150141136 bytesCom recuo e novas linhas:
Uso:
fonte
Python,
9795 bytesCom base na antiga abordagem de Pietu1998 (e de outros), de procurar o índice da nota na string
'C@D@EF@G@A@B'
por algum caractere em branco ou outro. Eu uso a descompactação iterável para analisar a sequência de notas sem condicionais. Fiz um pouco de álgebra no final para simplificar a expressão de conversão. Não sei se posso diminuí-lo sem alterar minha abordagem.fonte
b==['#']
poderia ser reduzido para'#'in b
enot b
parab>[]
.Wolfram Language (Mathematica), 69 bytes
Usando o pacote de músicas , com o qual simplesmente digitar uma nota como expressão avalia sua frequência, desta forma:
Para salvar bytes, evitando importar o pacote com
<<Music
, estou usando os nomes totalmente qualificados:Music`Eflat3
. No entanto, ainda tenho que substituirb
porflat
e#
comsharp
para corresponder ao formato de entrada da pergunta, o que faço com uma simplesStringReplace
.fonte