Pomóż mi grać na trąbce

14

Trąbka jest zaworem instrumentem aerofony, zwykle obozem B♭. Dźwięk jest emitowany, gdy odtwarzacz wibruje wargami, aby wyprzeć powietrze z wnętrza instrumentu. Wibrację tę uzyskuje się przez ustawienie ust w określony sposób, zwany tłoczeniem. Różne tłoczenia, z węższymi lub luźniejszymi ustami, wytwarzają różne wysokości.

Co więcej, każdy zawór w trąbce również zmienia wysokość instrumentu. Po wciśnięciu zawór zamyka ścieżkę wewnątrz rurki instrumentu, dzięki czemu powietrze przepływa dłuższą ścieżką, obniżając w ten sposób wysokość dźwięku oryginalnego. Na potrzeby tego wyzwania rozważymy standardową B♭trąbkę, w której pierwszy zawór obniża skok o pełny stopień, drugi obniża skok o pół stopnia, a trzeci obniża skok o jeden i jeden pół kroku.

Wyzwanie

Wyzwanie polega na utworzeniu programu lub funkcji, która przy dwóch wejściach embouchurei valvesokreśla wysokość odtwarzanej nuty.

Na potrzeby tego wyzwania notatki będą przebiegać w następującej kolejności:

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

Zasady

  • We / Wy można przyjmować / podawać dowolną rozsądną metodą .
  • Obowiązują standardowe luki .
  • Możesz używać bi #zamiast i jeśli chcesz.
  • Dane wejściowe dla valvesmożna przyjmować jako listę zaworów o obniżonym ciśnieniu ( 1, 3) lub listę wartości boolowskich ( 1, 0, 1).
  • To jest , więc wygrywa najkrótszy kod w każdym języku.

Przypadki testowe:

Valves w tych przypadkach testowych podano jako listę logiczną, gdzie 0 oznacza wciśnięty, a 1 wciśnięty.

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♯

Oświadczenie: Nie jestem jeszcze muzykiem, więc przepraszam za rzeź, jaką mogłem zrobić na testach. Poprawki są mile widziane.

J. Sallé
źródło
2
Perkusista tutaj. Czekaj, czekaj, tak piszesz zadrapanie. Zawsze myślałem, że zaczęło się od ;-)
MayorMonty
1
@vasilescur masz rację. Naprawię je i przejrzę inne możliwe błędy. Dzięki za heads-upy.
J. Sallé
1
Jako ktoś, kto grał na trąbce od dłuższego czasu, jestem naprawdę zdezorientowany pomiarem Embouchure ... Na przykład, co to jest Embouchure C #?
bendl
1
Czy F# 100E powinno być F?
Level River St
2
@bendl Nie ma czegoś takiego. Nie możesz grać C#na trąbce bez naciskania jakichkolwiek zaworów. Tylko konkretne uwagi ( B♭-F-B♭-D-F-A♭-B♭...), seria tonów B♭. Mimo to, nawet jeśli nie odzwierciedla prawdziwego instrumentu, wyzwanie jest doskonale dobrze zdefiniowane.
Chris

Odpowiedzi:

4

Pyton 3) 2, 125 119 81 bajtów

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]

Wypróbuj online!

Zaoszczędź dużo bajtów dzięki Jonathanowi Allanowi.


Moje oryginalne rozwiązanie (w 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)])

Wypróbuj online!

Zaoszczędź 6 bajtów dzięki @HyperNeutrino.


Wyjaśnienie

Najpierw robię szereg notatek, ale o podwójnej długości, więc nie muszę się martwić, że będę przechodził od Bbdo A.

Następnie biorę dane wejściowe w następującym formacie (na przykład):

Bb 1 0 1

Następnie znajduję indeks nuty początkowej za pomocą n.index(e,9)( 9jest tam, aby upewnić się, że zaczynam dobrze na środku (podwójnej) listy. Obliczam pożądane przesunięcie za pomocą wyrażenia:

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

Gdzie fjest pierwszy zawór, sjest drugi zawór i tjest trzeci.

Wreszcie, po prostu drukuje notatkę znalezioną na liście, odejmując przesunięcie od indeksu początkowego.

vasilescur
źródło
3
save a few bytes by separating by spaces. "<some string>".split() splits by whitespace by default
HyperNeutrino
Save 30 bytes by moving to Python 2 (avoiding str and int casts and allowing evaluated input) and reversing the notes and offsetting forward (avoiding the ,9 in the index call. Try It Online!
Jonathan Allan
...and another 8 moving to function (which works in Python 2 or 3) Try It Online!
Jonathan Allan
@JonathanAllan I learned several Python golfing tricks from your improvements. Thank you so much!
vasilescur
...in fact you can use the list in its original order without repetition and subtract values since the negative index never goes out of bounds (the most negative would be 'Bb', 1, 1, 1 taking you to index -6 which would be E, as required) - it's what TFeld has since done.
Jonathan Allan
3

Wolfram Language (Mathematica), 100 bytes (and 134 for a working trumpet)

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

Try it online!

Quite straightforward.

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

A better output for the cost of 34 bytes.

Keyu Gan
źródło
Wait ... Mathematica has Audio output??? Wicked!
Titus
Of course Mathematica has a built-in for audio output. This is gold.
J. Sallé
2

Jelly,  37  36 bytes

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

A dyadic link accepting the valves as a list of 1s or 0s as a list representing [second, first, third] on the left and the embouchure as a list of characters on the right which returns a list of characters.

Try it online!

How?

Ø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
źródło
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]}

Try it online!

70 chars but 80 bytes

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

Try it online!

Asone Tuhid
źródło
1

Javascript 96 bytes

Following @vasilescur idea, this is the implementation 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
źródło
3 bytes less ;) BTW the flats and sharps should be counted as 3 bytes aren't they?
Shieru Asakoto
Oh nvm (I didn't see that b and # are allowed) but you need to use b and # instead of flats and sharps.
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

Uses # and b: this means that Eb and Bb are legal variable names; # is handled by doing a string replacement to +1. The result of the string replacement is then automatically evaluated and the valves are then taken into account before the result is looked up in a list.

Neil
źródło
1

Stax, 32 bytes

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

Run and debug it online

It takes a note name and a list of depressed valves. It builds an array of note names, then calculates the total valve interval, and gets the note at that offset in the array.

"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

Run this one

recursive
źródło
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]

Try it online!

TFeld
źródło
0

Perl6/Rakudo 73 chars

Technically this is 83 bytes because I put the Unicode characters in, but swapping them for the ASCII equivalents would give 73 bytes.

As a {code block} with parameters like $^a this is a lambda, with a signature ($a, $b, $c, $d).

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

Call it:

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

Less-golfed:

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

Here we double a string '...' x 2 using the x infix operator, then searching for the embouchure followed by n notes using the smartmatch operator '...' ~~ /.../ - the regex hinges on \w\W? which is a word char then maybe a non-word char.

We look for n instances of that via (\w\W?)**{$_}, where we've already calculated n=$_ from params $b to $d. This yields a match from the embouchure note to the resulting note, of which we just want the last so we match that with another ~~ /\w\W?$/.

The calculation of $_ first is necessary to permit $^b implicit param creation on the block.

76 chars

An alternative using an array rather than string matches is 3 more chars:

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

Finding the embouchure in the list is achieved with @arr.first: $^a, :k, which returns the index (key) of the found element with :k.

Setting the array to $_ (as an object) lets us use .first and .[ ] on it without spending too many characters.

Phil H
źródło
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;}

Try it online!

Simple approach.

Valve input is 0,1.

Embouchure input must be lowercase. Interestingly, TiO is not finding strcmpi() without including string.h, whereas mingw-gcc allows it with the standard -Wimplicit-function-declaration warning.

vazt
źródło