Помоги мне сыграть на трубе

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
Перкуссионист здесь. Подождите, подождите, вот как вы пишете амбушюр. Всегда думал, что это началось с ;-)
MayorMonty
1
@vasilescur ты прав. Я исправлю это и рассмотрю любые другие возможные ошибки. Спасибо за внимание.
Ж. Салле
1
Как человек, который долго играл на трубе, меня очень смущает измерение Embouchure ... Например, что такое C # Embouchure?
Бендл
1
Должно F# 100быть E не F?
Уровень Река St
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третий.

Наконец, он просто печатает заметку, найденную в списке, вычитая смещение из начального индекса.

vasilescur
источник
3
сохранить несколько байтов, разделяя их пробелами. "<some string>".split()расщепляется по
пробелам
Сохранить 30 байт путем перехода на Python 2 (избегая strи intслепки и позволяя оцененный ввод) и реверсивных ноты и компенсируя вперед (избегая ,9в index. Вызове попробовать Интернет!
Джонатан Allan
... и еще 8 переходят к функции (которая работает в Python 2 или 3) Попробуйте онлайн!
Джонатан Аллан
@JonathanAllan Я научился нескольким трюкам игры в гольф на Python из ваших улучшений. Спасибо огромное!
vasilescur
... на самом деле вы можете использовать список в его первоначальном порядке без повторений и вычитать значения, так как отрицательный индекс никогда не выходит за пределы (самый отрицательный будет приводить 'Bb', 1, 1, 1вас к индексу, -6который будет E, как требуется) - это то, что имеет TFeld так как сделано .
Джонатан Аллан
3

Wolfram Language (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 имеет аудио выход ??? Злая!
Титус
Конечно, 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 байта, не так ли?
Шиеру Асакото
О нвм (я этого не видел 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

Stax , 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 символа

Технически это 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

Менее 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;
}

Здесь мы удваиваем строку, '...' x 2используя xинфиксный оператор, затем ищем вложение, за которым следуют n заметок, используя оператор smartmatch '...' ~~ /.../- регулярное выражение зависит от \w\W?слова char, а может быть от слова non 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.

Ввод Embouchure должен быть в нижнем регистре. Интересно, что TiO не находит strcmpi()без включения string.h, тогда как mingw-gcc позволяет делать это со стандартным -Wimplicit-function-declarationпредупреждением.

vazt
источник