Ajude-me a tocar trompete

14

A trombeta é um instrumento de aerofone com válvulas, geralmente afinado B♭. O som é emitido quando o jogador vibra seus lábios para deslocar o ar dentro do instrumento. Essa vibração é adquirida ajustando a boca de uma maneira específica, chamada embocadura. Embocaduras diferentes, com lábios mais apertados ou mais frouxos, produzem arremessos diferentes.

Além disso, cada válvula na trombeta também altera o tom do instrumento. Quando pressionada, uma válvula fecha um caminho dentro da tubulação do instrumento, fazendo o ar fluir por um caminho mais longo, diminuindo assim o tom do som original. Para os propósitos deste desafio, consideraremos o padrão, B♭trompete, no qual a primeira válvula abaixa o passo em um passo completo, a segunda abaixa o passo em um meio passo e a terceira abaixa o passo em um e um meio passo.

O desafio

Seu desafio é criar um programa ou função que, com duas entradas embouchuree valvesdetermine o tom da nota que está sendo tocada.

Para os propósitos deste desafio, as notas seguirão a sequência:

B♭, B, C, C♯, D, E♭, E, F, F♯, G, G♯, A.

Regras

  • A E / S pode ser obtida / fornecida em qualquer método razoável .
  • Aplicam-se brechas padrão .
  • Você tem permissão para usar be, em #vez de e se desejar.
  • A entrada para valvespode ser tomada como uma lista de válvulas pressionadas ( 1, 3) ou uma lista booleana ( 1, 0, 1).
  • Isso é , então o código mais curto em cada idioma vence.

Casos de teste:

Valves nesses casos de teste é fornecida como uma lista booleana, onde 0 significa deprimido e 1 significa pressionado.

Embouchure:    Valves:   Output:
B♭             0 0 0     B♭
B♭             0 1 0     A
B♭             1 0 1     F
C♯             0 0 1     B♭
C♯             1 1 1     G
E♭             1 0 0     C♯
G              0 1 1     E♭
G♯             1 0 0     F♯
G♯             0 0 1     F
G              1 0 0     F
F♯             1 0 0     E
D              1 0 1     A
A              1 1 1     E♭
E              1 1 0     C♯
E              0 0 1     C♯

Disclaimer: Ainda não sou muito músico, então peço desculpas por qualquer massacre que possa ter causado nos casos de teste. As correções são apreciadas.

J. Sallé
fonte
2
Percussionista aqui. Espere, espere, é assim que você soletra a embocadura. Sempre pensei que começou com um ;-) #
MayorMonty 15/0318
1
@vasilescur você está certo. Eu os corrigirei e analisarei quaisquer outros erros possíveis. Obrigado pela atenção.
J. Sallé
1
Como alguém que toca trompete há muito tempo, estou realmente confuso com a medição da Embouchure ... Por exemplo, o que é uma Embouchure C #?
BENDL
1
Deveria F# 100ser E não F?
Level River St
2
@ Bendl Não existe tal coisa. Você não pode tocar um C#trompete sem pressionar nenhuma válvula. Apenas notas específicas ( B♭-F-B♭-D-F-A♭-B♭...), as séries de overtone de B♭. Ainda assim, mesmo que não reflita um instrumento real, o desafio está perfeitamente bem definido.
22418 Chris

Respostas:

4

Pitão 3 2 125 119 81 bytes

lambda e,f,s,t,n=2*'A G# G F# F E Eb D C# C B Bb'.split():n[n.index(e)+2*f+s+3*t]

Experimente online!

Economizou muitos bytes graças a Jonathan Allan.


Minha solução original (em Python 3 ):

n=2*'Bb B C C# D Eb E F F# G G# A'.split()
e,f,s,t=str(input()).split()
print(n[n.index(e,9)-2*int(f)-int(s)-3*int(t)])

Experimente online!

Guardado 6 bytes graças a @HyperNeutrino.


Explicação

Primeiro, faço uma série de anotações, mas o dobro do comprimento, para que eu não precise me preocupar em dar voltas de Bbpara A.

Então, recebo a entrada no seguinte formato (por exemplo):

Bb 1 0 1

Em seguida, encontro o índice da nota inicial usando n.index(e,9)(o 9existe para garantir que eu comece bem no meio da lista (duplicada). Calculo o deslocamento desejado com a expressão:

2*int(f) - int(s) - 3*int(t)

Onde festá a primeira válvula, sé a segunda válvula e té a terceira.

Finalmente, ele simplesmente imprime a nota encontrada na lista subtraindo o deslocamento do índice inicial.

vasilescur
fonte
3
salve alguns bytes separando por espaços. "<some string>".split()divide por espaço em branco por padrão
HyperNeutrino 15/03
Guardar 30 bytes por se mudar para Python 2 (evitando stre intmoldes e permitindo a entrada avaliado) e reverter as notas e compensação para a frente (evitando o ,9no index. Chamada Try It Online!
Jonathan Allan
... e outros 8 mudando para a função (que funciona em Python 2 ou 3) Experimente Online!
Jonathan Allan
@ JonathanAllan Aprendi vários truques de golfe em Python com suas melhorias. Muito obrigado!
vasilescur
... na verdade, você pode usar a lista em sua ordem original sem repetir e subtrair valores, pois o índice negativo nunca sai dos limites (o mais negativo seria 'Bb', 1, 1, 1levá-lo ao índice -6que seria E, conforme necessário) - é o que TFeld tem desde feito .
Jonathan Allan
3

Wolfram Language (Mathematica) , 100 bytes (e 134 para uma trombeta em funcionamento)

l="Bb,B,C,C#,D,Eb,E,F,F#,G,G#,A"~StringSplit~",";f=l[[Mod[#&@@#&@@l~Position~#-2#2-#3-3#4-1,12]+1]]&

Experimente online!

Bem direto.

l="Bb,B,C,C#,D,Eb,E,F,F#,G,G#,A"~StringSplit~",";f=EmitSound@SoundNote[l[[Mod[#&@@#&@@l~Position~#-2#2-#3-3#4-1,12]+1]],1,"Trumpet"]&

Uma saída melhor pelo custo de 34 bytes.

Keyu Gan
fonte
Espere ... Mathematica tem saída de áudio ??? Malvado!
Titus
@ Titus sim. Para notas de som, que é fornecido pelo midi
Keyu Gan
Claro que o Mathematica possui um built-in para saída de áudio. Isto é ouro.
J. Sallé
2

Geléia ,  37  36 bytes

ØAḣ7;⁾#b“®JXrẊỤȥ’ṃnŒl$œṗ$Ḋ©i_⁸æ.J¤ị®

Um link diádico que aceita as válvulas como uma lista de 1s ou 0s como uma lista que representa [second, first, third]à esquerda e a embocadura como uma lista de caracteres à direita que retorna uma lista de caracteres.

Experimente online!

Quão?

ØAḣ7;⁾#b“®JXrẊỤȥ’ṃnŒl$œṗ$Ḋ©i_⁸æ.J¤ị® - Link: list of integers, V; list of characters, E
ØA                                   - yield uppercase alphabet
  ḣ7                                 - head to index 7 = "ABCDEFG"
     ⁾#b                             - literal list of characters = "#b"
    ;                                - concatenate = "ABCDEFG#b"
        “®JXrẊỤȥ’                    - literal integer = 2270857278734171
                 ṃ                   - base decompress (i.e. convert to base 9 using the 'digits' "bABCDEFG#")
                                     -                 = "ABbBCC#DEbEFF#GG#"
                        $            - last two links as a monad:
                     $               -   last two links as a monad:
                   Œl                -     to lower case = "abbbcc#debeff#gg#"
                  n                  -     not equal? (vectorises) = [1,1,0,1,1,1,0,1,1,0,1,1,1,0,1,1,0]
                      œṗ             -   partition at truthy indices = [[],"A","Bb","B","C","C#","D","Eb","E","F","F#","G","G#"]
                         Ḋ           - dequeue = ["A","Bb","B","C","C#","D","Eb","E","F","F#","G","G#"]
                          ©          - copy to register and yield
                           i         - first index of E in there
                                 ¤   - nilad followed by links as a nilad:
                             ⁸       -   chain's left argument, V
                                J    -   range of length [1,2,3]
                              æ.     -   dot product (i.e. 1*second + 2*first + 3*third)
                            _        - subtract
                                   ® - recall from register
                                  ị  - index into (1-based and modular)
Jonathan Allan
fonte
2

Ruby , 71 bytes

->e,(b,c,d){a=%w{Bb B C C# D Eb E F F# G G# A};a[a.index(e)-b*2-c-d*3]}

Experimente online!

70 caracteres, mas 80 bytes

->e,(b,c,d){a="B♭BCC♯DE♭EFF♯GG♯A".scan /.\W?/;a[a.index(e)-b*2-c-d*3]}

Experimente online!

Asone Tuhid
fonte
1

Javascript 96 bytes

Seguindo a ideia @vasilescur, esta é a implementação em js

(a,b,c,d,_="B♭,B,C,C♯,D,E♭,E,F,F♯,G,G♯,A".split`,`)=>(l=_.concat(_))[l.indexOf(a,9)-(2*b+c+3*d)]

a=(a,b,c,d,_="B♭,B,C,C♯,D,E♭,E,F,F♯,G,G♯,A".split`,`)=>(l=_.concat(_))[l.indexOf(a,9)-(2*b+c+3*d)]
console.log(a('B♭',0,0,0))
console.log(a('B♭',0,1,0))
console.log(a('B♭',1,0,1))
console.log(a('C♯',0,0,1))
console.log(a('C♯',1,1,1))
console.log(a('E♭',1,0,0))
console.log(a('G',0,1,1))
console.log(a('G♯',1,0,0))
console.log(a('G♯',0,0,1))
console.log(a('G',1,0,0))
console.log(a('F♯',1,0,0))
console.log(a('D',1,0,1))
console.log(a('A',1,1,1))
console.log(a('E',1,1,0))
console.log(a('E',0,0,1))

Luis felipe De jesus Munoz
fonte
3 bytes a menos;) Aliás, os apartamentos e objetos cortantes devem ser contados como 3 bytes, não são?
Shieru Asakoto 16/03/19
Oh nvm (eu não vi isso be #é permitido), mas você precisa usar be em #vez de apartamentos e objetos cortantes.
Shieru Asakoto 16/03/19
1

Lote, 188 bytes

@set n=%1
@set/aC=0,D=2,Eb=3,E=4,F=5,G=7,A=9,Bb=10,B=11,n=(%n:#=+1%+12-%2*2-%3-%4*3)%%12
@for %%n in (C.0 C#.1 D.2 Eb.3 E.4 F.5 F#.6 G.7 G#.8 A.9 Bb.10 B.11)do @if %%~xn==.%n% echo %%~nn

Usa #e b: isso significa que Ebe Bbsão nomes de variáveis ​​legais; #é tratado fazendo uma substituição de cadeia de caracteres para +1. O resultado da substituição da coluna é avaliado automaticamente e as válvulas são levadas em consideração antes de o resultado ser pesquisado em uma lista.

Neil
fonte
1

Stax , 32 bytes

τ┤=Yº○!AÄΔâß₧←╥╟ö'ÄD├æñßf╧å▬tó÷╖

Execute e depure on-line

Leva um nome de nota e uma lista de válvulas pressionadas. Ele cria uma matriz de nomes de notas, calcula o intervalo total da válvula e obtém a nota nesse deslocamento na matriz.

"AbABbBCC#DEbEFF#G" just a literal
{VA#}(Y             partition at capital letters and store in y
,]I                 get the index of the input note
,2R:t               swap 1s and 2s in valve list
{-F                 subtract valve list from note index
y@                  look up result from note array

Execute este

recursivo
fonte
1

Python 2 , 84 79 bytes

lambda e,a,b,c,s='Bb B C C# D Eb E F F# G G# A'.split():s[s.index(e)-2*a-b-3*c]

Experimente online!

TFeld
fonte
0

Perl6 / Rakudo 73 caracteres

Tecnicamente, são 83 bytes porque eu coloquei os caracteres Unicode, mas trocá-los pelos equivalentes ASCII daria 73 bytes.

Como {code block}com parâmetros como $^aeste, é um lambda, com uma assinatura ($a, $b, $c, $d).

{$_=2*$^b+$^c+3*$^d;'AG♯GF♯FEE♭DC♯CBB♭'x 2~~/$^a(\w\W?)**{$_}/~~/\w\W?$/}

Chame-o:

say { ... }("D", 1, 0, 1)
>> A

Menos golfe:

sub f($a, $b, $c, $d) {
   my $totalShift = 2*$b + $c + 3*$d;
   my $doubledScale = 'AG♯GF♯FEE♭DC♯CBB♭' x 2;
   my $matchEmbOnward = $doubledScale ~~ / $^a (\w\W?)**{$totalShift} /;
   my $matchFinalNote = $marchEmbOnward ~~ / \w \W? $ /;
   return $matchFinalNote;
}

Aqui dobramos uma string '...' x 2usando o xoperador infix e, em seguida, pesquisamos a embocadura seguida por n notas usando o operador smartmatch '...' ~~ /.../- a regex depende\w\W? que é um caractere de palavra e talvez um caractere que não seja da palavra.

Procuramos n instâncias dessa via (\w\W?)**{$_}, nas quais já calculamos n = $_dos parâmetros $bpara $d. Isso produz uma correspondência entre a nota de embocadura e a nota resultante, da qual queremos apenas a última, então a igualamos com outra~~ /\w\W?$/ .

O cálculo do $_primeiro é necessário para permitir$^b criação implícita de parâmetros no bloco.

76 caracteres

Uma alternativa usando uma matriz em vez de correspondências de cadeia de caracteres é mais 3 caracteres:

{$_=<B♭ B C C♯ D E♭ E F F♯ G G♯ A>;.[((.first: $^a,:k)-2*$^b-$^c-3*$^d)%12]}

A localização da embocadura na lista é obtida com @arr.first: $^a, :k, que retorna o índice (chave) do elemento encontrado com:k .

Definir a matriz para $_(como um objeto) nos permite usar .firste .[ ]sobre ele sem gastar muitos caracteres.

Phil H
fonte
0

C (gcc) , 155 bytes

char r[][12]={"bb","b","c","c#","d","eb","e","f","f#","g","g#","a"};u;v(z,y,x,w)char*z;{for(;u<12;u++)if(!strcmp(z,r[u]))break;u=u-2*y-x-3*w;u=u<0?12+u:u;}

Experimente online!

Abordagem simples.

A entrada da válvula é 0,1.

A entrada da embocadura deve estar em minúscula. Curiosamente, o TiO não é encontrado strcmpi()sem incluir string.h, enquanto o mingw-gcc permite o -Wimplicit-function-declarationaviso padrão .

vazt
fonte