Diretrizes
Tarefa
Dadas duas notas, inseridas como seqüências de caracteres ou listas / matrizes, calcule quantos semitons estão separados (inclusive as próprias notas), produzindo como um número.
Explicação de um semitom:
Um semitom é um passo para cima ou para baixo do teclado. Um exemplo é C para C #. Como você pode ver abaixo, a nota C está em uma nota branca e C # é a nota preta apenas uma acima dela. Semitons são os saltos de uma nota preta para a próxima nota branca, para cima ou para baixo, exceto:
- B a C
- C para B
- E a F
- F para E
Exemplos
'A, C' -> 4
'G, G#' -> 2
'F#, B' -> 6
'Bb, Bb' -> 13
Regras
- A maior distância entre duas notas é de 13 semitons.
- A segunda nota inserida estará sempre acima da primeira nota inserida.
- Você pode receber a entrada como uma sequência ou uma matriz / lista. Se você a usar como uma corda, as notas serão separadas por vírgula (por exemplo
String -> 'A, F'
,Array -> ['A', 'F']
). - Você pode assumir que sempre receberá duas notas válidas.
- Os objectos cortantes serão designados como
#
e os apartamentos serão designados comob
- Seu código deve suportar equivalentes enarmônicos (por exemplo, ele deve suportar F # e Gb)
- Seu código não precisa oferecer suporte a anotações nomeadas com, mas pode ser nomeado sem um ponto nítido ou plano (ou seja, você não precisa oferecer suporte a E # ou Cb). Pontos de bônus se o seu código o suportar.
- Seu código não precisa oferecer suporte a objetos cortantes ou planos duplos.
- Você pode supor que, se obtiver as mesmas notas ou o mesmo tom (por exemplo, 'Gb, Gb' ou 'A #, Bb'), o segundo não será exatamente uma oitava acima do primeiro.
- Isso é código de golfe, então a resposta com a menor quantidade de bytes ganha.
G -> G#
porque são ambos incluídos.Cb
ouE#
? E os perfurocortantes duplos?(X, Y]
maneira: C a C # é 1 semitom e C a C é 12 semitom.Respostas:
Python 2 , 66 bytes
Experimente online!
Python 2 , 68 bytes
Experimente online!
fonte
JavaScript (ES6), 78 bytes
Guardado 1 byte graças a @Neil
Faz as anotações na sintaxe de currying
(a)(b)
.Casos de teste
Mostrar snippet de código
Função hash
O objetivo da função hash é converter uma anotação em um ponteiro em uma tabela de pesquisa que contém os desvios de semitons (C = 0, C # = 1, ..., B = 11), armazenados em hexadecimal.
Em primeiro lugar temos um acréscimo '3' para a nota e analisar a cadeia resultante em base-36, levando a um número inteiro N . Como '#' é um caractere inválido, ele é simplesmente ignorado, juntamente com qualquer caractere que o segue.
Então calculamos:
Abaixo está um resumo dos resultados.
Sobre apartamentos e objectos cortantes
Abaixo está a prova de que essa função hash garante que uma nota seguida de um '#' produz o mesmo resultado que a próxima nota seguida de um 'b' . Neste parágrafo, usamos o prefixo @ para quantidades base-36.
Por exemplo, Db será convertido em @ db3 e C # será convertido em @c (consulte o parágrafo anterior). Queremos provar que:
Ou no caso geral, com Y = X + 1 :
@ b3 é 399 em decimal. Assim sendo:
1296 é congruente a 1 módulo 37 , portanto, isso pode ser simplificado como:
Um caso especial é a transição de G # para Ab , como esperamos que Hb atenda às fórmulas acima. No entanto, este também funciona porque:
fonte
Perl,
3932 bytesInclui
+1
parap
Dê as notas de início e fim como duas linhas em STDIN
Apenas o código:
fonte
Japonês , 27 bytes
Teste online! Recebe a entrada como uma matriz de duas seqüências.
Também funciona para qualquer quantidade de objectos cortantes ou planos em qualquer nota de base!
Explicação
fonte
Perl 5 +
-p
, 66 bytesExperimente online!
Toma valores separados por vírgula. Também funciona para Cb, B #, E #, Fb e vários # / b.
Explicação:
Explicação para eval:
fonte
Ruby , 56 bytes
Experimente online!
As letras são analisadas de acordo com seus tempos de código ASCII da
5/3
seguinte maneira (isso fornece o número necessário de semitons mais um deslocamento de 108)O último caractere (
#
,b
ou a letra de novo) é analisado como seu código ASCII dividido por 32, como segueIsso é subtraído do código da letra.
Em seguida, o resultado final é retornado como
13-(difference in semitones)%12
fonte
Stax ,
2524 bytesExecute e depure on-line
A representação ascii correspondente do mesmo programa é essa.
Efetivamente, calcula o índice do teclado de cada nota usando uma fórmula e calcula o intervalo resultante.
2 - code / 32
ondecode
está o código ascii do último caractere.fonte
["F#","B"]
deve ser 6. #Lote,
136135 bytesExplicação: As substituições na
c
sub - rotina substituem#
no nome da nota por+1
eb
com-1
. Como isso não faz distinção entre maiúsculas e minúsculas,Bb
torna-se-1-1
. As variáveis paraC
...A
(também não diferenciam maiúsculas de minúsculas) são, portanto, escolhidas para serem o número apropriado de semitons de distânciaB=-1
. A string resultante é então avaliada, e o truque de @ xnor de subtrair o resultado do valor fornece o efeito desejado de subtrair os valores das notas uns dos outros. Edit: Finalmente eu uso o truque de @ Arnauld de subtrair o módulo de 13 para obter a resposta desejada, economizando 1 byte.fonte
Python 3 , 95 bytes
Experimente online!
-14 bytes graças a user71546
fonte
ord(q[0])-65
substituição"ABCDEFG".find(q[0])
;)(g(b)+~g(a))%12+2
substituição1+((g(b)-g(a))%12or 12)
Gelatina , 28 bytes
Um link monádico que aceita uma lista de duas listas de caracteres e retorna um número inteiro.
Experimente online! ou veja todos os casos possíveis .
Quão?
Executa uma aritmética bizarra nos ordinais dos caracteres de entrada para mapear as notas nos números inteiros de zero a doze e, em seguida, executa uma descompressão de base como proxy para o módulo de doze em que zero é então substituído por 12 e adiciona um.
Também em 28 bytes ...
Uma porta (não tão direta) da resposta Python 2 do xnor ...
Experimente todos os casos possíveis
fonte
CJam , 67 bytes
Intérprete online: http://cjam.aditsu.net/
fonte