Bantu saya memainkan Trumpet

14

The terompet adalah instrumen telepon udara valved, biasanya berkemah di B♭. Suara itu dibuat ketika pemain menggetarkan bibir mereka untuk memindahkan udara di dalam instrumen. Getaran itu diperoleh dengan mengatur mulut seseorang dengan cara tertentu, yang disebut embouchure. Berbagai kantong yang berbeda, dengan bibir yang lebih kencang atau longgar, menghasilkan nada yang berbeda.

Selain itu, setiap katup dalam terompet juga mengubah nada instrumen. Ketika ditekan, katup menutup jalur di dalam tabung instrumen, membuat aliran udara melalui jalur yang lebih panjang, sehingga menurunkan nada suara asli. Untuk keperluan tantangan ini, kami akan mempertimbangkan standar, B♭terompet, di mana katup pertama menurunkan nada dengan langkah penuh, yang kedua menurunkan nada dengan setengah langkah, dan yang ketiga menurunkan nada dengan satu dan satu setengah langkah.

Tantangan

Tantangan Anda adalah membuat program atau fungsi yang, diberi dua input embouchuredan valves, menentukan nada not yang sedang diputar.

Untuk keperluan tantangan ini, catatan akan mengikuti urutan:

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

Aturan

  • I / O dapat diambil / diberikan dengan metode yang masuk akal .
  • Celah standar berlaku.
  • Anda diizinkan untuk menggunakan bdan #bukannya dan jika Anda mau.
  • Input untuk valvesdapat diambil sebagai daftar katup depresi ( 1, 3) atau daftar boolean ( 1, 0, 1).
  • Ini adalah , sehingga kode terpendek di setiap bahasa menang.

Kasus uji:

Valves dalam kasus uji ini diberikan sebagai daftar boolean, di mana 0 berarti tertekan dan 1 berarti ditekan.

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♯

Penafian: Saya belum banyak menjadi musisi, jadi saya minta maaf atas pemotongan yang mungkin saya lakukan pada kasus uji. Koreksi dihargai.

J. Sallé
sumber
2
Perkusi di sini. Tunggu tunggu, begitulah cara Anda mengejanya. Selalu berpikir itu dimulai dengan ;-)
MayorMonty
1
@ vasilescur kau benar. Saya akan memperbaikinya dan meninjau kemungkinan kesalahan lainnya. Terimakasih atas peringatannya.
J. Sallé
1
Sebagai seseorang yang sudah lama bermain trompet, saya benar-benar bingung dengan pengukuran Embouchure ... Misalnya apa itu C # Embouchure?
bendl
1
Seharusnya F# 100E bukan F?
Level River St
2
@ Belend Tidak ada hal seperti itu. Anda tidak dapat memainkan C#trompet tanpa menekan katup apa pun. Hanya catatan khusus ( B♭-F-B♭-D-F-A♭-B♭...), seri nada B♭. Namun, bahkan jika itu tidak mencerminkan instrumen nyata tantangannya didefinisikan dengan sangat baik.
Chris

Jawaban:

4

Python 3 2, 125 119 81 byte

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]

Cobalah online!

Menyimpan banyak byte berkat Jonathan Allan.


Solusi asli saya (dalam 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)])

Cobalah online!

Disimpan 6 byte berkat @HyperNeutrino.


Penjelasan

Pertama, saya membuat array catatan, tetapi panjangnya dua kali lipat jadi saya tidak perlu khawatir tentang perulangan dari BbkeA .

Lalu, saya mengambil input dalam format berikut (misalnya):

Bb 1 0 1

Saya kemudian menemukan indeks catatan awal menggunakan n.index(e,9)( 9ada di sana untuk memastikan bahwa saya mulai dengan baik di tengah daftar (dua kali lipat). Saya menghitung offset yang diinginkan dengan ekspresi:

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

Di mana fkatup pertama,s katup kedua, dan katup tketiga.

Akhirnya, ia hanya mencetak catatan yang ditemukan dalam daftar dengan mengurangi offset dari indeks awal.

vasilescur
sumber
3
simpan beberapa byte dengan memisahkan dengan spasi. "<some string>".split()terbagi secara spasi putih secara default
HyperNeutrino
Simpan 30 byte dengan pindah ke Python 2 (menghindari strdan intgips dan memungkinkan masukan dievaluasi) dan membalikkan catatan dan mengimbangi maju (menghindari ,9di index. Panggilan Cobalah online!
Jonathan Allan
... dan 8 pemindahan fungsi lainnya (yang berfungsi dengan Python 2 atau 3) Cobalah Online!
Jonathan Allan
@ Jonathan Allan Saya belajar beberapa trik golf Python dari peningkatan Anda. Terima kasih banyak!
vasilescur
... pada kenyataannya Anda dapat menggunakan daftar dalam urutan aslinya tanpa pengulangan dan kurangi nilai karena indeks negatif tidak pernah keluar dari batas (yang paling negatif akan 'Bb', 1, 1, 1membawa Anda ke indeks -6yang akan E, sesuai kebutuhan) - itulah yang dimiliki TFeld sejak selesai .
Jonathan Allan
3

Bahasa Wolfram (Mathematica) , 100 byte (dan 134 untuk trompet yang berfungsi)

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

Cobalah online!

Cukup mudah.

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

Output yang lebih baik untuk biaya 34 byte.

Keyu Gan
sumber
Tunggu ... Mathematica memiliki output Audio ??? Jahat!
Titus
@Itus ya. Untuk catatan suara, disediakan oleh midi
Keyu Gan
Tentu saja Mathematica memiliki built-in untuk output audio. Ini emas.
J. Sallé
2

Jelly ,  37  36 byte

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

Sebuah link diad yang menerima katup sebagai daftar 1s atau 0s sebagai daftar yang mewakili [second, first, third]di sebelah kiri dan kotak sebagai daftar karakter di sebelah kanan yang mengembalikan daftar karakter.

Cobalah online!

Bagaimana?

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

Ruby , 71 byte

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

Cobalah online!

70 karakter tetapi 80 byte

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

Cobalah online!

Asone Tuhid
sumber
1

Javascript 96 byte

Mengikuti ide @vasilescur, ini adalah implementasi di 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
sumber
3 byte kurang;) BTW flat dan benda tajam harus dihitung sebagai 3 byte, bukan?
Shieru Asakoto
Oh nvm (saya tidak melihat itu bdan #diizinkan) tetapi Anda harus menggunakan bdan #bukannya flat dan benda tajam.
Shieru Asakoto
1

Batch, 188 byte

@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

Menggunakan #dan b: ini berarti bahwa Ebdan Bbmerupakan nama variabel hukum; #ditangani dengan melakukan penggantian string ke +1. Hasil penggantian string kemudian secara otomatis dievaluasi dan katup kemudian diperhitungkan sebelum hasilnya dicari dalam daftar.

Neil
sumber
1

Stax , 32 byte

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

Jalankan dan debug secara online

Dibutuhkan nama catatan dan daftar katup yang tertekan. Itu membangun array nama catatan, kemudian menghitung interval katup total, dan mendapatkan catatan itu diimbangi dalam 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

Jalankan yang ini

rekursif
sumber
1

Python 2 , 84 79 byte

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]

Cobalah online!

TFeld
sumber
0

Perl6 / Rakudo 73 karakter

Secara teknis ini adalah 83 byte karena saya memasukkan karakter Unicode, tetapi menukarnya dengan ASCII setara akan memberikan 73 byte.

Sebagai {code block}parameter dengan seperti $^aini adalah lambda, dengan tanda tangan ($a, $b, $c, $d).

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

Sebut saja:

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

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

Di sini kita menggandakan string '...' x 2menggunakan xoperator infiks, kemudian mencari embouchure diikuti oleh n catatan menggunakan operator smartmatch '...' ~~ /.../- regex bergantung pada \w\W?yang merupakan kata char kemudian mungkin char non-kata.

Kami mencari n contoh dari itu via (\w\W?)**{$_}, di mana kami telah menghitung n = $_dari params $bke $d. Ini menghasilkan kecocokan dari catatan embouchure ke catatan yang dihasilkan, yang kami hanya ingin yang terakhir jadi kami cocokkan dengan yang lain~~ /\w\W?$/ .

Perhitungan $_pertama diperlukan untuk mengizinkan $^bpembuatan param implisit di blok.

76 karakter

Alternatif menggunakan array daripada pencocokan string adalah 3 karakter lainnya:

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

Menemukan embouchure dalam daftar dicapai dengan @arr.first: $^a, :k, yang mengembalikan indeks (kunci) dari elemen yang ditemukan dengan :k.

Mengatur array ke $_(sebagai objek) memungkinkan kita menggunakan .firstdan menggunakannya .[ ]tanpa menghabiskan terlalu banyak karakter.

Phil H
sumber
0

C (gcc) , 155 byte

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

Cobalah online!

Pendekatan sederhana.

Input katup adalah 0,1.

Input embouchure harus huruf kecil. Menariknya, TiO tidak menemukan strcmpi()tanpa menyertakan string.h, sedangkan mingw-gcc memungkinkannya dengan -Wimplicit-function-declarationperingatan standar .

ay
sumber