Hilf mir, Trompete zu spielen

14

Die Trompete ist ein ventiliertes Aerophoninstrument, das normalerweise eingestimmt ist B♭. Der Ton wird erzeugt, wenn der Player mit den Lippen vibriert, um die Luft im Inneren des Instruments zu verdrängen. Diese Schwingung wird dadurch erreicht, dass man den Mund auf eine bestimmte Art und Weise einstellt, die Embouchure genannt wird. Unterschiedliche Prägungen mit festeren oder lockereren Lippen erzeugen unterschiedliche Tonhöhen.

Darüber hinaus ändert jedes Ventil in der Trompete auch die Tonhöhe des Instruments. Durch Drücken eines Ventils wird ein Pfad im Inneren des Instrumentenschlauchs geschlossen, wodurch die Luft durch einen längeren Pfad strömt und somit die Tonhöhe des Originaltons verringert wird. Für die Zwecke dieser Herausforderung betrachten wir die Standard- B♭Trompete, bei der das erste Ventil die Tonhöhe um eine volle Stufe absenkt, das zweite die Tonhöhe um eine halbe Stufe und das dritte die Tonhöhe um eins und a absenkt halber Schritt.

Die Herausforderung

Ihre Herausforderung besteht darin, ein Programm oder eine Funktion zu erstellen, die bei zwei Eingaben embouchureundvalves der Tonhöhe der gespielten Note bestimmt.

Für die Zwecke dieser Herausforderung folgen die Notizen der Reihenfolge:

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

Regeln

  • I / O kann auf jede vernünftige Weise genommen / gegeben werden .
  • Standard-Schlupflöcher gelten .
  • Sie dürfen bund #anstelle von und verwenden, wenn Sie möchten.
  • Die Eingabe für valveskann als Liste niedergedrückter Ventile ( 1, 3) oder als Boolesche Liste ( 1, 0, 1) erfolgen.
  • Das ist , also gewinnt der kürzeste Code in jeder Sprache.

Testfälle:

Valves In diesen Testfällen wird eine Boolesche Liste angegeben, in der 0 für gedrückt und 1 für gedrückt steht.

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♯

Haftungsausschluss: Ich bin noch kein großer Musiker, daher entschuldige ich mich für die Schlachtung der Testfälle. Korrekturen sind erwünscht.

J. Sallé
quelle
2
Schlagzeuger hier. Warte, warte, so buchstabierst du Embouchure.
Dachte
1
@vasilescur du hast recht. Ich werde diese beheben und alle anderen möglichen Fehler überprüfen. Danke für die Warnung.
J. Sallé
1
Als jemand, der lange Zeit Trompete gespielt hat, bin ich wirklich verwirrt von der Embouchure-Messung ... Was ist beispielsweise eine C # -Embouchure?
Bendl
1
Sollte F# 100E nicht F sein?
Level River St
2
@bendl So etwas gibt es nicht. Sie können nicht C#auf einer Trompete spielen, ohne Ventile zu drücken. Nur bestimmte Noten ( B♭-F-B♭-D-F-A♭-B♭...), die Obertonreihe von B♭. Auch wenn es sich nicht um ein echtes Instrument handelt, ist die Herausforderung perfekt definiert.
Chris

Antworten:

4

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

Probieren Sie es online!

Dank Jonathan Allan konnten viele Bytes gespart werden.


Meine ursprüngliche Lösung (in 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)])

Probieren Sie es online!

6 Bytes gespart dank @HyperNeutrino.


Erläuterung

Zuerst mache ich eine Reihe von Noten, aber in der Länge verdoppelt , so ich zu kümmern, nicht um Umschlingung aus Bbzu A.

Dann nehme ich Eingaben in folgendem Format vor (zum Beispiel):

Bb 1 0 1

Ich finde dann den Index der Startnote mit n.index(e,9)(das 9ist da, um sicherzustellen, dass ich gut in der Mitte der (doppelten) Liste beginne. Ich berechne den gewünschten Versatz mit dem Ausdruck:

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

Wo fist das erste Ventil, sist das zweite Ventil und tist das dritte.

Zum Schluss wird einfach die in der Liste gefundene Notiz gedruckt, indem der Versatz vom Startindex abgezogen wird.

Vasilescur
quelle
3
Sparen Sie ein paar Bytes, indem Sie sie durch Leerzeichen trennen. "<some string>".split()Standardmäßig wird nach Leerzeichen geteilt
HyperNeutrino
Sparen Sie 30 Bytes, indem Sie zu Python 2 wechseln (Vermeiden strund Umsetzen intund Zulassen ausgewerteter Eingaben) und die Noten umkehren und weiterleiten (Vermeiden ,9des indexAnrufs. Probieren Sie es online aus!
Jonathan Allan
... und weitere 8 Funktionen (funktioniert in Python 2 oder 3) Try It Online!
Jonathan Allan
@ JonathanAllan Ich habe mehrere Python-Golftricks aus Ihren Verbesserungen gelernt. Ich danke dir sehr!
Vasilescur
... in der Tat können Sie die Liste in ihrer ursprünglichen Reihenfolge verwenden , ohne Wiederholung und Werte subtrahieren , da nie der negativer Index der Grenzen erlischt (die negativste würden 'Bb', 1, 1, 1Sie indizieren nehmen , -6die sein würde , je Enach Bedarf) - es ist , was TFeld hat da getan .
Jonathan Allan
3

Wolfram Language (Mathematica) , 100 Bytes (und 134 für eine Arbeitstrompete)

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

Probieren Sie es online!

Recht einfach.

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

Eine bessere Ausgabe für die Kosten von 34 Bytes.

Keyu Gan
quelle
Warten Sie ... Mathematica hat Audio-Ausgang? Böse!
Titus
@Titus ja. Für Tonaufnahmen
sorgt
Natürlich verfügt Mathematica über eine integrierte Audioausgabe. Das ist Gold.
J. Sallé
2

Jelly ,  37  36 Bytes

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

Ein dyadischer Link, der die Ventile als Liste von 1s oder 0s als Liste [second, first, third]auf der linken Seite und die Embouchure als Liste von Zeichen auf der rechten Seite akzeptiert, die eine Liste von Zeichen zurückgibt.

Probieren Sie es online!

Wie?

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

Probieren Sie es online!

70 Zeichen aber 80 Bytes

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

Probieren Sie es online!

Asone Tuhid
quelle
1

Javascript 96 Bytes

Nach der Idee von @vasilescur ist dies die Implementierung in 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
quelle
3 Bytes weniger;) Übrigens sollten die Flats und Sharps als 3 Bytes gezählt werden, nicht wahr?
Shieru Asakoto
Oh nvm (ich habe das nicht gesehen bund bin #erlaubt) aber du musst bund #anstelle von Wohnungen und scharfen Gegenständen benutzen.
Shieru Asakoto
1

Batch, 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

Verwendet #und b: dies bedeutet, dass Ebund Bbzulässige Variablennamen sind; #wird behandelt, indem ein String-Ersatz an vorgenommen wird +1. Das Ergebnis des Stringwechsels wird dann automatisch ausgewertet und die Ventile berücksichtigt, bevor das Ergebnis in einer Liste nachgeschlagen wird.

Neil
quelle
1

Stax , 32 Bytes

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

Führen Sie es online aus und debuggen Sie es

Es enthält einen Notennamen und eine Liste der niedergedrückten Ventile. Es wird ein Array von Notennamen erstellt, dann das gesamte Ventilintervall berechnet und die Note an diesem Offset im Array abgerufen.

"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

Führen Sie dieses aus

rekursiv
quelle
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]

Probieren Sie es online!

TFeld
quelle
0

Perl6 / Rakudo 73 Zeichen

Technisch sind das 83 Bytes, weil ich die Unicode-Zeichen eingebe, aber wenn ich sie gegen die ASCII-Entsprechungen austausche, ergeben sich 73 Bytes.

Als {code block}mit Parametern wie $^adiesem ist ein Lambda mit einer Signatur ($a, $b, $c, $d).

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

Nennen:

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

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

Hier verdoppeln wir eine Zeichenfolge , '...' x 2die mit xInfixoperator, dann die Suche nach der embouchure von n Anmerkungen folgten dem Smartmatch Operator '...' ~~ /.../- die Regex Scharniere auf \w\W?denen ein Wort char dann vielleicht ein nicht-Wort char.

Wir suchen nach n Instanzen davon (\w\W?)**{$_}, bei denen wir bereits n = $_von params $bbis berechnet haben $d. Dies ergibt eine Übereinstimmung von der Embouchure-Note zu der resultierenden Note, von der wir nur die letzte wollen, damit wir diese mit einer anderen abgleichen ~~ /\w\W?$/.

Die Berechnung von $_first ist erforderlich, um die $^bimplizite Erstellung von Parametern auf dem Block zu ermöglichen.

76 Zeichen

Eine Alternative, bei der ein Array anstelle von Zeichenfolgenübereinstimmungen verwendet wird, sind drei weitere Zeichen:

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

Das Auffinden der Embouchure in der Liste erfolgt mit @arr.first: $^a, :k, wobei der Index (Schlüssel) des gefundenen Elements mit zurückgegeben wird :k.

Wenn Sie das Array auf $_(als Objekt) setzen, können Sie .firstund .[ ]darauf verwenden, ohne zu viele Zeichen zu verbrauchen.

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

Probieren Sie es online!

Einfacher Ansatz.

Der Ventileingang beträgt 0,1.

Die Embouchure-Eingabe muss in Kleinbuchstaben erfolgen. Interessanterweise findet TiO nicht strcmpi()ohne Einschluss string.h, wohingegen mingw-gcc es mit der Standardwarnung erlaubt -Wimplicit-function-declaration.

vazt
quelle