O ano é 930 e a Igreja Gregoriana está tendo um problema. Eles têm milhares de páginas de música cantada, mas o problema é que toda a partitura foi simplesmente jogada em uma pilha em vez de ter um sistema de organização real:
Imagem do usuário gamerprinter no Cartographers 'Guild .
A Igreja precisa organizar todas as partituras, para que eles contrataram um engenheiro de software medieval para escrever um programa para organizá-lo para eles. Você é o engenheiro de software que foi contratado. No entanto, o processo de compilação nos tempos medievais envolve a escrita do programa no papel por uma equipe de escribas bíblicos lentos. Para diminuir o tempo que a equipe de escribas leva para compilar seu código, você deve tornar o programa o menor possível.
A Igreja quer que a música cantada seja organizada com base na escala musical em que está escrita. Toda a música cantada da Igreja é escrita em escalas dóricas . Dadas as notas de uma certa peça de música, seu programa produzirá a escala dórica em que está. Aqui, explicarei exatamente o que é uma escala dórica. Se você já sabe, pode pular esta seção.
Existem 12 notas possíveis em qualquer melodia. Aqui estão eles em ordem:
C C# D D# E F F# G G# A A# B
Um semitom (representado usando a S
) está incrementando um passo para a direita, envolvendo (para que um semitom acima de B retorne a C). Um tom (representado usando a T
) é de dois semitons. Por exemplo, um semitom acima de F # seria G. Um tom acima de F # seria G #.
Para criar uma escala dórica, partimos de qualquer anotação da lista e, em seguida, avançamos no seguinte padrão, listando as anotações que encontramos:
T, S, T, T, T, S
Um exemplo. Começo com A. As notas da minha escala Doriana se tornam:
A
B (up a tone)
C (up a semitone)
D (up a tone)
E (up a tone)
F# (up a tone)
G (up a semitone)
A escala tem as notas A, B, C, D, E, F #, e G. Por ter começado a partir de A, vamos chamar isso de escala Dorian em A . Existem, portanto, 12 escalas dóricas diferentes, sendo que cada uma delas recebe o nome da nota da qual elas começaram. Cada um deles usa o mesmo padrão de tons e semitons, apenas começando de uma posição diferente. Se minha explicação não for coerente, você também pode consultar a Wikipedia .
A entrada do programa pode ser fornecida a partir do que for apropriado para o seu programa (por exemplo, STDIN, argumento da linha de comando raw_input()
). Pode não ser pré-inicializado em uma variável. A entrada será uma lista de notas separadas por vírgula, representando a melodia da peça. Pode haver notas repetidas. Sempre haverá notas diferentes suficientes na entrada para poder deduzir decisivamente a escala da peça. Um exemplo de entrada:
B,B,D,E,D,B,A,G#,A,G#,E,D,F#,E,F#,E,F#,G#,A
A saída do programa deve ser a sequência Dorian scale in X
, em que X é a nota inicial da escala. A saída da entrada de exemplo:
Dorian scale in B
Comparando isso com a escala Doriana em B ( B C# D E F# G# A
), vemos que todas as notas da melodia estão dentro dessa escala. A nota C # não é usada neste caso. No entanto, existem notas suficientes para identificar inequivocamente B Dorian como a chave correta. Nenhuma outra escala dórica se encaixa, porque qualquer que seja a outra escala que tentemos, sempre há pelo menos uma nota da melodia que não pertence à escala.
Isso é código de golfe, portanto a entrada com o menor número de caracteres vence. Pergunte nos comentários se você tiver dúvidas.
Respostas:
CJam - 61
Experimente em http://cjam.aditsu.net/
fonte
C,
171146A análise de cadeias de caracteres em C não é tão fácil, então fui para uma abordagem mais matemática.
Aproveito o Círculo dos Quintos. Se organizarmos as notas na seguinte ordem com base na contagem de 7 semitons por vez (conhecido como "quinto"), descobriremos que todas as notas permitidas em uma determinada escala formam um bloco consecutivo de 7 notas e todas as notas proibidas formar um bloco consecutivo de 5 notas.
(é um círculo, volta ao
F
final.)A posição de uma nota natural na sequência acima pode ser calculada como
(ASCII code) * 2 % 7
. Então, se o próximo caractere for ímpar (aplica-se a#
vírgula, espaço ou zero byte), adicionamos 7 para torná-lo nítido. Armazenamos um bitmap das notas que foram usadas.O número
243
(binário11111000
) corresponde às notas proibidas na escala de A # Dorian. Eu multipliquei isso(1<<12)+1=4097
para dar o número mágico1016056
. É ativado o direito de verificar (por AND) se a melodia contém notas proibidas para cada uma das 12 escalas por vez. Se a melodia não contiver notas proibidas, a escala será impressa.Para a saída, precisamos imprimir o nome da balança codificado na ordem inversa para o ciclo de quintos acima, lembre-se de que estamos voltando atrás porque estamos mudando de direitos.) A sequência ASCII
ADGCFBEADGCF
é gerada por65+i*3%7
. Nos cinco primeiros, também deve ser impressa uma nitidez.Código ungolfed
Comportamento de entrada inválido: se notas insuficientes forem fornecidas para determinar sem ambiguidade a escala, ela produzirá todas as escalas possíveis. Se uma combinação impossível de notas for fornecida, ela não produzirá nada. As anotações devem ser delimitadas por vírgula (ou outro caractere que não seja um espaço em branco com um código ASCII par <<64.) Os espaços não podem ser usados, pois tudo após o primeiro espaço seria considerado um argumento diferente. Os códigos ASCII> 64 serão interpretados como notas da maneira descrita.
fonte
Haskell - 152
Ungolfed
fonte
Python 2 - 177 caracteres
Não é tão curto, mas acho que é uma alegria para o Python escrever vários loops aninhados em uma linha, mesmo quando não estiver jogando golfe. Infelizmente, tive que colocar a instrução de entrada em uma linha separada para que não fosse executada mais de uma vez.
Não uso o Python 3, mas acredito que esse seja um caso raro em que a declaração de impressão não precisaria de mais caracteres. Como
print
existe uma função lá, eu seria capaz de compensar a necessidade de parênteses com o uso do*
operador de desempacotamento de lista para substituir o último[0]
.fonte
input
porraw_input
e salvar 4 caracteres em Python 3.Ruby - 132
Entrada da linha de comando args.
por exemplo
ruby dorianscale.rb B,B,D,E,D,B,A,G#,A,G#,E,D,F#,E,F#,E,F#,G#,A
Experimente: ideone
fonte
Haskell - 140
Utilize a propriedade Circle of Fifths introduzida por @steveverrill. Se deixarmos
circle0 = words "C G D A E B F# C# G# D# A# F"
ecircle = circle0 ++ circle0
, podemos construir todas as escalas anotando 7 notas consecutivascircle
.Em cada escala construída dessa maneira
scale !! 3
, o quarto elemento é o nome da escala.Código
Ungolfed
fonte
Scala,
130128127Usando o método do círculo dos quintos. Entrada da linha de comando args
fonte