Ayúdame a tocar la trompeta

14

La trompeta es un instrumento de aerófono con válvula, generalmente colocado B♭. El sonido se hace cuando el jugador hace vibrar sus labios para desplazar el aire dentro del instrumento. Esa vibración se adquiere al ajustar la boca de una manera específica, llamada embocadura. Diferentes embocaduras, con labios más apretados o más flojos, producen diferentes tonos.

Además, cada válvula en la trompeta también cambia el tono del instrumento. Cuando se presiona, una válvula cierra un camino dentro del tubo del instrumento, haciendo que el aire fluya a través de un camino más largo, bajando así el tono del sonido original. Para los propósitos de este desafío, consideraremos la B♭trompeta estándar, en la cual la primera válvula baja el paso en un paso completo, la segunda baja el paso en medio paso, y el tercero baja el paso en uno y un medio paso.

El reto

Su desafío es crear un programa o función que, con dos entradas embouchurey valves, determina el tono de la nota que se está reproduciendo.

Para los propósitos de este desafío, las notas seguirán la secuencia:

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

Reglas

  • Las E / S pueden tomarse / administrarse de cualquier manera razonable .
  • Se aplican lagunas estándar .
  • Se le permite usar by en #lugar de y si lo desea.
  • La entrada para valvesse puede tomar como una lista de válvulas deprimidas ( 1, 3) o una lista booleana ( 1, 0, 1).
  • Este es el , por lo que gana el código más corto en cada idioma.

Casos de prueba:

Valves en estos casos de prueba se da como una lista booleana, donde 0 significa deprimido y 1 significa presionado.

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♯

Descargo de responsabilidad: todavía no soy un gran músico, así que me disculpo por cualquier carnicería que haya hecho en los casos de prueba. Se aprecian las correcciones.

J. Sallé
fuente
2
Percusionista aquí. Espera espera, así es como deletreas embocadura. Siempre pensé que comenzó con un a ;-)
MayorMonty
1
@vasilescur tienes razón. Los arreglaré y revisaré cualquier otro posible error. Gracias por el aviso.
J. Sallé
1
Como alguien que ha tocado la trompeta durante mucho tiempo, estoy realmente confundido por la medición de Embouchure ... Por ejemplo, ¿qué es una Embouchure C #?
Bendl
1
¿Debería F# 100ser E no F?
Level River St
2
@bendl No hay tal cosa. No puedes tocar una C#trompeta sin presionar ninguna válvula. Solo notas específicas ( B♭-F-B♭-D-F-A♭-B♭...), la serie de armónicos de B♭. Aún así, incluso si no refleja un instrumento real, el desafío está perfectamente bien definido.
Chris

Respuestas:

4

Pitón 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]

Pruébalo en línea!

Ahorré muchos bytes gracias a Jonathan Allan.


Mi solución original (en 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)])

Pruébalo en línea!

Guardado 6 bytes gracias a @HyperNeutrino.


Explicación

Primero, hago una serie de notas, pero doblé su longitud para no tener que preocuparme por pasar de un lado Bba otro A.

Luego, tomo la entrada en el siguiente formato (por ejemplo):

Bb 1 0 1

Luego encuentro el índice de la nota inicial usando n.index(e,9)( 9está ahí para asegurarme de que empiezo bien en el medio de la lista (duplicada). Calculo el desplazamiento deseado con la expresión:

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

Dónde festá la primera válvula, ses la segunda válvula y tes la tercera.

Finalmente, simplemente imprime la nota encontrada en la lista restando el desplazamiento del índice inicial.

vasilescur
fuente
3
ahorre algunos bytes separándolos por espacios. "<some string>".split()se divide por espacios en blanco por defecto
HyperNeutrino
Ahorre 30 bytes moviéndose a Python 2 (evitando stry intlanzando y permitiendo la entrada evaluada) e invirtiendo las notas y compensando hacia adelante (evitando ,9la indexllamada. ¡ Pruébelo en línea!
Jonathan Allan
... y otros 8 movimientos para funcionar (que funciona en Python 2 o 3) ¡ Pruébelo en línea!
Jonathan Allan
@ JonathanAllan Aprendí varios trucos de golf de Python de tus mejoras. Muchas gracias!
vasilescur
... de hecho, puede usar la lista en su orden original sin repetición y restar valores ya que el índice negativo nunca se sale de los límites (lo más negativo sería 'Bb', 1, 1, 1llevarlo al índice -6que sería E, según sea necesario): es lo que TFeld tiene Ya hecho .
Jonathan Allan
3

Wolfram Language (Mathematica) , 100 bytes (y 134 para una trompeta de trabajo)

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]]&

Pruébalo en línea!

Bastante sencillo.

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"]&

Una mejor salida por el costo de 34 bytes.

Keyu Gan
fuente
Espera ... ¿Mathematica tiene salida de audio? ¡Malvado!
Titus
Por supuesto, Mathematica tiene una salida de audio incorporada. Esto es oro
J. Sallé
2

Gelatina ,  37  36 bytes

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

Un enlace diádico que acepta las válvulas como una lista de 1s o 0s como una lista que representa [second, first, third]a la izquierda y la embocadura como una lista de caracteres a la derecha que devuelve una lista de caracteres.

Pruébalo en línea!

¿Cómo?

Ø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
fuente
2

Rubí , 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]}

Pruébalo en línea!

70 caracteres pero 80 bytes

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

Pruébalo en línea!

Asone Tuhid
fuente
1

Javascript 96 bytes

Siguiendo la idea de @vasilescur, esta es la implementación en 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
fuente
3 bytes menos;) Por cierto, los pisos y objetos punzantes deben contarse como 3 bytes, ¿no?
Shieru Asakoto
Oh nvm (no vi eso by #están permitidos) pero necesitas usar by en #lugar de pisos y objetos punzantes.
Shieru Asakoto
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

Usos #y b: esto significa que Eby Bbson nombres de variables legales; #se maneja haciendo un reemplazo de cadena a+1 . El resultado del reemplazo de la cadena se evalúa automáticamente y las válvulas se tienen en cuenta antes de buscar el resultado en una lista.

Neil
fuente
1

Stax , 32 bytes

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

Ejecútelo y depúrelo en línea

Toma un nombre de nota y una lista de válvulas deprimidas. Construye una matriz de nombres de notas, luego calcula el intervalo total de la válvula y obtiene la nota en ese desplazamiento en la 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

Ejecute este

recursivo
fuente
0

Perl6 / Rakudo 73 caracteres

Técnicamente, esto es 83 bytes porque puse los caracteres Unicode, pero intercambiarlos por los equivalentes ASCII daría 73 bytes.

Como {code block}con parámetros como $^aeste es un lambda, con una firma ($a, $b, $c, $d).

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

Llámalo:

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

Menos golfizado:

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;
}

Aquí doblamos una cadena '...' x 2usando el xoperador infijo, luego buscamos la embocadura seguida de n notas usando el operador smartmatch '...' ~~ /.../: la expresión regular depende de \w\W?que sea una palabra char y luego tal vez una palabra no char.

Buscamos n instancias de esa vía (\w\W?)**{$_}, donde ya hemos calculado n = $_de params $ba $d. Esto produce una coincidencia de la nota de embocadura con la nota resultante, de la cual solo queremos la última, por lo que la combinamos con otra ~~ /\w\W?$/.

El cálculo de $_primero es necesario para permitir$^b creación implícita de parámetros en el bloque.

76 caracteres

Una alternativa que utiliza una matriz en lugar de coincidencias de cadenas es 3 caracteres más:

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

Encontrar la embocadura en la lista se logra con @arr.first: $^a, :k, que devuelve el índice (clave) del elemento encontrado con :k.

Establecer la matriz en $_(como un objeto) nos permite usarla .firsty usarla .[ ]sin gastar demasiados caracteres.

Phil H
fuente
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;}

Pruébalo en línea!

Enfoque simple

La entrada de la válvula es 0,1.

La entrada de embocadura debe estar en minúscula. Curiosamente, TiO no se encuentra strcmpi()sin incluir string.h, mientras que mingw-gcc lo permite con la -Wimplicit-function-declarationadvertencia estándar .

vazt
fuente