Допоможи мені зіграти на Трубі


14

Труба є клапанним Аерофон інструменту, як правило , станом B♭. Звук видається, коли гравець вібрує губами, щоб витіснити повітря всередині інструменту. Ця вібрація набувається шляхом встановлення рота певним чином, який називається етчур. Різні фасони, з більш щільними або пухкими губами, створюють різні смоли.

Крім того, кожен клапан у трубі також змінює крок інструменту. При натисканні клапан закриває шлях всередині трубки приладу, роблячи потік повітря більш довгим шляхом, тим самим знижуючи крок початкового звуку. Для цілей цього виклику ми розглянемо стандартну B♭трубу, коли перший клапан знижує крок на повний крок, другий знижує крок на півкроку, а третій знижує крок на один і півкроку.

Змагання

Ваше завдання полягає в тому, щоб створити програму або функцію, яка з урахуванням двох входів embouchureі valvesвизначає висоту відтворення ноти.

Для цілей цього виклику примітки дотримуватимуться послідовності:

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

Правила

  • Введення / виведення можна приймати / давати будь-яким розумним методом .
  • Застосовуються стандартні лазівки .
  • Вам дозволяється використовувати bі #замість цього, і якщо ви хочете.
  • Вхідні дані valvesможуть сприйматися як список затиснених клапанів ( 1, 3) або булевий список ( 1, 0, 1).
  • Це , тому найкоротший код на кожній мові виграє.

Випробування:

Valves у цих тестових випадках подається у вигляді булевого списку, де 0 означає депресію та 1 - натиснуту.

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♯

Відмова: Я ще не дуже музикант, тому прошу вибачення за будь-яке вбивство, яке я міг би зробити на тестах. Виправлення цінуються.


2
Перкусіоніст тут. Зачекайте, зачекайте, ось так ви заклинаєте заклинання. Завжди думав, що це почалося з
a--)

1
@vasilescur ви праві. Я виправлю їх і перегляну будь-які інші можливі помилки. Дякую за голову вгору
Дж. Салле

1
Як хтось, хто довго грав на трубі, мене дуже бентежить вимірювання Embouchure ... Наприклад, що таке C # Embouchure?
bendl

1
Чи повинен F# 100бути E не F?
Річка рівня Св.

2
@bendl Немає такого. Ви не можете грати C#на трубі, не натискаючи жодного клапана. Просто конкретні ноти ( B♭-F-B♭-D-F-A♭-B♭...), ряд обертонів B♭. Однак, навіть якщо це не відображає реальний інструмент, виклик ідеально чітко визначений.
Кріс

Відповіді:


4

Пітон 3 2, 125 119 81 байт

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]

Спробуйте в Інтернеті!

Зберегли багато байт завдяки Джонатану Аллану.


Моє оригінальне рішення (в 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)])

Спробуйте в Інтернеті!

Збережено 6 байт завдяки @HyperNeutrino.


Пояснення

По- перше, я роблю масив нот, але в два рази по довжині , так що я не повинен турбуватися про перекручування навколо від Bbдо A.

Потім я приймаю вхід у такому форматі (наприклад):

Bb 1 0 1

Потім я знаходжу індекс початкової ноти за допомогою n.index(e,9)( 9є, щоб переконатися, що я починаю добре в середині (подвоєного) списку. Я обчислюю потрібне зміщення за допомогою виразу:

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

Де fперший клапан, sдругий клапан і tтретій.

Нарешті, він просто друкує замітку, знайдену в списку, віднімаючи зміщення від початкового індексу.


3
збережіть кілька байтів, розділивши пробіли. "<some string>".split()розбивається на пробіли за замовчуванням
HyperNeutrino

Зберегти 30 байт шляхом переходу на Python 2 (уникаючи strі intзліпки і дозволяючи оцінений введення) і реверсивних ноти і компенсуючи вперед (уникаючи ,9в index. Виклик спробувати Інтернет!
Джонатан Allan

... і ще 8 переходять до функції (яка працює в Python 2 або 3) Спробуйте в Інтернеті!
Джонатан Аллан

@JonathanAllan Я дізнався кілька трюків з гольфу на Python з ваших удосконалень. Дуже дякую!
vasilescur

... насправді ви можете використовувати список у його початковому порядку без повторення та віднімання значень, оскільки негативний індекс ніколи не виходить за межі ( найнегативнішим вважатиметься'Bb', 1, 1, 1 індекс, -6який би був E, як потрібно) - це те, що має TFeld з тих пір .
Джонатан Аллан

3

Мова Вольфрама (Mathematica) , 100 байт (і 134 для робочої труби)

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

Спробуйте в Інтернеті!

Досить прямо.

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

Кращий вихід за вартістю 34 байти.


Зачекайте ... Математика має аудіо вихід ??? Злий!
Тит

Звичайно, у Mathematica є вбудований аудіо вихід. Це золото.
Дж. Салле

2

Желе ,  37  36 байт

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

Діадичне посилання, що приймає клапани як список 1s або 0s як список, що відображається [second, first, third]зліва, а конвертація як список символів праворуч, який повертає список символів.

Спробуйте в Інтернеті!

Як?

Ø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)


1

Javascript 96 байт

Слідом за ідеєю @vasilescur, це реалізація в 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))


На 3 байти менше;) До речі, квартири та гострики слід вважати 3 байтами, чи не так?
Шиеру Асакото

О, nvm (я цього не бачив bі #дозволено), але вам потрібно використовувати bі #замість квартир і гострих.
Шиеру Асакото

1

Пакетна, 188 байт

@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

Використання #та b: це означає, що Ebі Bbє юридичними назвами змінних; #обробляється шляхом заміни рядка на +1. Результат заміни струни потім автоматично оцінюється, а клапани враховуються до того, як результат знайдеться у списку.


1

Стакс , 32 байти

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

Запустити та налагодити його в Інтернеті

Він займає назву нота та список пригнічених клапанів. Він будує масив імен нот, потім обчислює загальний інтервал клапана і отримує нотатку при цьому зміщенні в масиві.

"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

Виконати цей




0

Perl6 / Rakudo 73 chars

Технічно це 83 байти, тому що я помістив символи Unicode, але заміна їх на еквіваленти ASCII дала б 73 байти.

Оскільки {code block}з такими параметрами $^aє лямбда, з підписом ($a, $b, $c, $d).

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

Назви це:

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

Менш гольф:

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

Тут ми подвоюємо рядок '...' x 2за допомогою xоператора інфіксації, а потім шукаємо контур, а потім n нот за допомогою оператора smartmatch '...' ~~ /.../- шарнірних шрифтів, на \w\W?яких є слово char, а може бути, не слово char.

Ми шукаємо n екземплярів цього через (\w\W?)**{$_}, де ми вже обчислили n = $_від парам $bдо $d. Це дає збіг від нот-контуру до отриманої ноти, з яких ми просто хочемо останнього, щоб ми відповідали цій іншій ~~ /\w\W?$/.

Розрахунок $_спочатку необхідний, щоб дозволити $^bстворення неявного параму на блоці.

76 символів

Альтернативою, що використовує масив, а не рядкові збіги, є ще 3 символи:

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

Знайти в списку ешелону @arr.first: $^a, :k, яка повертає індекс (ключ) знайденого елемента за допомогою :k.

Встановлення масиву $_(як об'єкта) дозволяє нам використовувати його .firstі .[ ]на ньому, не витрачаючи занадто багато символів.


0

C (gcc) , 155 байт

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

Спробуйте в Інтернеті!

Простий підхід.

Вхід клапана 0,1.

Введення для ешелони повинен бути малим. Цікаво, що TiO не знаходить strcmpi()без включення string.h, тоді як mingw-gcc дозволяє це зі стандартним -Wimplicit-function-declarationпопередженням.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.