Aidez-moi à jouer de la trompette

14

La trompette est un instrument d'aérophone à valve, généralement intégré B♭. Le son est émis lorsque le joueur fait vibrer ses lèvres pour déplacer l'air à l'intérieur de l'instrument. Cette vibration s'acquiert en mettant sa bouche d'une manière spécifique, appelée l'embouchure. Différentes embouchures, avec des lèvres plus serrées ou plus lâches, produisent des hauteurs différentes.

De plus, chaque valve de la trompette change également la hauteur de l'instrument. Lorsqu'elle est enfoncée, une valve ferme un chemin à l'intérieur du tube de l'instrument, faisant circuler l'air sur un chemin plus long, abaissant ainsi la hauteur du son d'origine. Pour les besoins de ce défi, nous considérerons la B♭trompette standard, dans laquelle la première valve abaisse le pitch d'un pas complet, la seconde abaisse le pitch d'un demi-pas et la troisième abaisse le pitch d'un et d'un Demi-pas.

Le défi

Votre défi est de créer un programme ou une fonction qui, compte tenu de deux entrées embouchureet valves, détermine la hauteur de la note jouée.

Aux fins de ce défi, les notes suivront la séquence:

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

Règles

  • Les E / S peuvent être prises / données par toute méthode raisonnable .
  • Des échappatoires standard s'appliquent.
  • Vous êtes autorisé à utiliser bet #au lieu de et si vous le souhaitez.
  • L'entrée pour valvespeut être considérée comme une liste de vannes enfoncées ( 1, 3) ou une liste booléenne ( 1, 0, 1).
  • C'est le , donc le code le plus court dans chaque langue l'emporte.

Cas de test:

Valves dans ces cas de test est donné sous forme de liste booléenne, où 0 signifie enfoncé et 1 signifie enfoncé.

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♯

Avertissement: je ne suis pas encore beaucoup un musicien, donc je m'excuse pour toute boucherie que j'ai pu faire sur les cas de test. Les corrections sont appréciées.

J. Sallé
la source
2
Percussionniste ici. Attendez, attendez, c'est ainsi que vous épelez l'embouchure.
J'ai
1
@vasilescur vous avez raison. Je vais les corriger et passer en revue toute autre erreur possible. Merci pour l'information.
J. Sallé
1
En tant que quelqu'un qui joue de la trompette depuis longtemps, je suis vraiment confus par la mesure de l'embouchure ... Par exemple, qu'est-ce qu'une embouchure C #?
bendl
1
Doit F# 100être E pas F?
Level River St
2
@bendl Il n'y a rien de tel. Vous ne pouvez pas jouer C#de la trompette sans appuyer sur aucune valve. Juste des notes spécifiques ( B♭-F-B♭-D-F-A♭-B♭...), la série harmonique de B♭. Pourtant, même s'il ne reflète pas un véritable instrument, le défi est parfaitement bien défini.
Chris

Réponses:

4

Python 3 2, 125 119 81 octets

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]

Essayez-le en ligne!

Beaucoup d'octets enregistrés grâce à Jonathan Allan.


Ma solution originale (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)])

Essayez-le en ligne!

6 octets enregistrés grâce à @HyperNeutrino.


Explication

Tout d'abord, je crée un tableau de notes, mais de longueur double, je n'ai donc pas à me soucier de boucler de Bbà A.

Ensuite, je prends la saisie dans le format suivant (par exemple):

Bb 1 0 1

Je trouve ensuite l'index de la note de départ en utilisant n.index(e,9)(le 9est là pour m'assurer que je commence bien au milieu de la liste (doublée). Je calcule le décalage souhaité avec l'expression:

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

fest la première soupape, sest la deuxième soupape, et test la troisième.

Enfin, il imprime simplement la note trouvée dans la liste en soustrayant le décalage de l'index de départ.

vasilescur
la source
3
économisez quelques octets en les séparant par des espaces. "<some string>".split()se divise par espace par défaut
HyperNeutrino
Enregistrer 30 octets en déplaçant vers Python 2 (évitant stret intmoulages et permettant l' entrée évaluée) et inverser les notes et la compensation en avant ( en évitant le ,9dans le index. Appel Essayez - le en ligne!
Jonathan Allan
... et 8 autres en mouvement (qui fonctionne en Python 2 ou 3) Essayez-le en ligne!
Jonathan Allan
@JonathanAllan J'ai appris plusieurs astuces de golf Python grâce à vos améliorations. Merci beaucoup!
vasilescur
... en fait, vous pouvez utiliser la liste dans son ordre d'origine sans répétition et soustraire des valeurs car l'indice négatif ne sort jamais des limites (le plus négatif serait de vous 'Bb', 1, 1, 1amener à indexer -6ce qui serait E, comme requis) - c'est ce que TFeld a depuis fait .
Jonathan Allan
3

Wolfram Language (Mathematica) , 100 octets (et 134 pour une trompette qui fonctionne)

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

Essayez-le en ligne!

Assez simple.

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

Une meilleure sortie pour le coût de 34 octets.

Keyu Gan
la source
Attendez ... Mathematica a une sortie audio ??? Méchant!
Titus
Bien sûr, Mathematica a une sortie audio intégrée. C'est de l'or.
J.Sallé
2

Gelée ,  37  36 octets

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

Un lien dyadique acceptant les valves comme une liste de 1s ou 0s comme une liste représentant [second, first, third]à gauche et l'embouchure comme une liste de caractères à droite qui renvoie une liste de caractères.

Essayez-le en ligne!

Comment?

Ø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
la source
2

Rubis , 71 octets

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

Essayez-le en ligne!

70 caractères mais 80 octets

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

Essayez-le en ligne!

Asone Tuhid
la source
1

Javascript 96 octets

Suivant l'idée de @vasilescur, voici l'implémentation dans 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
la source
3 octets de moins;) BTW les appartements et les objets tranchants devraient être comptés comme 3 octets, n'est-ce pas?
Shieru Asakoto
Oh nvm (je ne l'ai pas vu bet je suis #autorisé) mais vous devez utiliser bet #au lieu des appartements et des objets tranchants.
Shieru Asakoto
1

Lot, 188 octets

@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

Utilise #et b: cela signifie que Ebet Bbsont des noms de variables légaux; #est gérée en remplaçant la chaîne par +1. Le résultat du remplacement de la chaîne est alors automatiquement évalué et les vannes sont ensuite prises en compte avant de rechercher le résultat dans une liste.

Neil
la source
1

Stax , 32 octets

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

Exécutez-le et déboguez-le en ligne

Il prend un nom de note et une liste de valves enfoncées. Il crée un tableau de noms de notes, puis calcule l'intervalle total des valves et obtient la note à ce décalage dans le tableau.

"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

Exécutez celui-ci

récursif
la source
1

Python 2 , 84 79 octets

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]

Essayez-le en ligne!

TFeld
la source
0

Perl6 / Rakudo 73 caractères

Techniquement, c'est 83 octets parce que j'ai mis les caractères Unicode dedans, mais les échanger contre des équivalents ASCII donnerait 73 octets.

Comme {code block}avec des paramètres comme $^acelui-ci, c'est un lambda, avec une signature ($a, $b, $c, $d).

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

Appeler:

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

Moins golfé:

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

Ici, nous doublons une chaîne '...' x 2à l'aide de l' xopérateur infixe, puis recherchons l'embouchure suivie de n notes à l'aide de l'opérateur smartmatch '...' ~~ /.../- la charte regex sur \w\W?laquelle est un mot char puis peut-être un non-mot char.

Nous recherchons n instances de cette via (\w\W?)**{$_}, où nous avons déjà calculé n = $_des paramètres $bà $d. Cela donne une correspondance de la note d'embouchure à la note résultante, dont nous voulons juste la dernière donc nous faisons correspondre cela avec une autre ~~ /\w\W?$/.

Le calcul de $_first est nécessaire pour permettre $^bla création implicite de paramètres sur le bloc.

76 caractères

Une alternative utilisant un tableau plutôt que des correspondances de chaîne est 3 caractères supplémentaires:

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

La recherche de l'embouchure dans la liste est réalisée avec @arr.first: $^a, :k, qui renvoie l'index (clé) de l'élément trouvé avec :k.

Définir le tableau sur $_(en tant qu'objet) nous permet d'utiliser .firstet .[ ]dessus sans dépenser trop de caractères.

Phil H
la source
0

C (gcc) , 155 octets

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

Essayez-le en ligne!

Une approche simple.

L'entrée de la vanne est 0,1.

L'entrée d'embouchure doit être en minuscules. Fait intéressant, TiO ne trouve pas strcmpi()sans inclure string.h, alors que mingw-gcc le permet avec l' -Wimplicit-function-declarationavertissement standard .

vazt
la source