Переведите пары чисел в гитарные ноты


18

Гриф гитары выглядит так:

  0  1  2  3  4  5  6  7  8  9 10 11 12   <- Fret number (0 means it's open)
|-E--F--F#-G--G#-A--A#-B--C--C#-D--D#-E
|-B--C--C#-D--D#-E--F--F#-G--G#-A--A#-B 
|-G--G#-A--A#-B--C--C#-D--D#-E--F--F#-G
|-D--D#-E--F--F#-G--G#-A--A#-B--C--C#-D
|-A--A#-B--C--C#-D--D#-E--F--F#-G--G#-A
|-E--F--F#-G--G#-A--A#-B--C--C#-D--D#-E

Как видите, первая открытая строка (сверху) - это E. Первый лад на первой струне - это F. Четвертый лад на третьей струне - это B. Обратите внимание, что первая нота - это ноль, а не первая.

Это можно записать цифрами в формате string, fret. Строки пронумерованы от 1 до 6 сверху вниз. Лады нумеруются от 0 до 12 слева направо. Первый Eпоэтому 1, 0. Некоторые другие примеры:

1, 0 --> E
1, 1 --> F
3, 5 --> C
5, 1 --> A# 
6, 6 --> A#

Вызов:

Возьмите Nпары чисел ( sи f) и выведите последовательность примечаний с разделителями.

  • Ввод может быть в любом подходящем формате. кортежи, 2D-матрица, два отдельных списка, переплетенный список (строка, раздражение, строка, раздражение ...) и т. д.
  • Выходной тон должен быть разделен, но разделитель необязателен (запятая, пробел, тире ...). Вывод может быть в верхнем или нижнем регистре.
  • s(для строки) будет в диапазоне [1, 6](вы можете выбрать i 0-indexed)
  • f (для раздражения) будет в диапазоне [0, 12]

Тестовые случаи и примеры:

1 4 5 2 1 3   <- String
4 2 6 3 5 1   <- Fret
G# E D# D A G#

6 2 3 1 4 2 3 2 2 2 6 5 2
0 1 2 3 4 5 6 7 8 9 10 11 12
E C A G F# E C# F# G G# D G# B  

3 3 3 3 3 3 3 3 3 3 3 3 3   <- String
0 3 5 0 3 6 5 0 3 5 3 0 0   <- Fret
G A# C G A# C# C G A# C A# G G     

// The same test case, but different input and output format:
(3,0)(3,3)(3,5)(3,3)(3,6)(3,5)(3,0)(3,3)(3,5)(3,3)(3,0)(3,0)    
G,A#,C,G,A#,C#,C,G,A#,C,A#,G,G     

Удачи и счастливого гольфа!


Не гитарист (и даже не приличный музыкант, на самом деле), но разве здесь нет существенного упущения, если вы ожидаете выхода в виде узнаваемых мелодий? То есть длительность ноты - целая, половина, четверть, и т. Д.
jamesqf

1
@jamesqf Нет, это прекрасно, если ты знаешь песню. В настоящее время это самая популярная песня на ultimate-guitar.com . Посмотрите на вступление.
Стьюи Гриффин

Ответы:


4

05AB1E , 48 47 43 40 байт

Использует кодировку CP-1252 .

И струны, и лады начинаются с 0.

v7YT5¾7)y`Šè+•™ÎÚ,Ülu•žh'#A«‡•7V3•3BS£è,

объяснение

v                                # for each pair in input
 7YT5¾7)                         # the list [7,2,10,5,0,7]
 y`                              # flatten the pair [string, fret] and places on stack
 Šè                              # index into the list above using the string
 +                               # add the fret
 •™ÎÚ,Ülu•žh'#A«‡•7V3•3BS£       # list of accords
 è                               # index into the string using the number calculated above
 ,                               # print

Попробуйте онлайн!

Сохранено 7 байтов благодаря Аднану


1
Эксплуатация жуков очень важна для гольфа! .-)
Луис Мендо

"AA#BCC#DD#EFF#GG#"•7V3•3BS£а "A A# B C C# D D# E F F# G G#"#не на несколько байт короче :).
Аднан

@Adnan: Ооо, хорошая смена базы :)
Emigna

Также сжатая версия "AA#BCC#DD#EFF#GG#"строки: •™ÎÚ,Ülu•žh'#A«‡(поскольку строчные буквы разрешены: p).
Аднан

9

JavaScript (ES6), 79 70 байт

a=>a.map(([s,f])=>"AA#BCC#DD#EFF#GG#".match(/.#?/g)[(s*7+(s>2)+f)%12])

Требуются строки на основе 1. Редактировать: Сохранение 9 байтов путем непосредственного вычисления преобразования строки в лад, основываясь на старом ответе @ nimi.


@Arnauld Спасибо, но я вместо этого присвоил ответ @ nimi.
Нил

Гораздо эффективнее;)
Арно

Умная. очень подлый ответ
Рохан Джхунджхунвала

7

Mathematica, 62 байта (не конкурирует)

<<Music`;MusicScale[100(#2+{24,19,15,10,5,0}[[#]])&@@@#,E2,9]&

Символы {24,19,15,10,5,0}the и the E2представляют открытые струны шести гитарных струн (например, верхняя строка на 24 полутона выше ноты E2). Не конкурирует, потому что не печатает названия нот - он воспроизводит последовательность нот! (только если у вас есть Mathematica, к сожалению) Например,

<<Music`;MusicScale[100(#2+{24,19,15,10,5,0}[[#]])&@@@#,E2,9]&@
 {{4,0},{3,2},{2,3},{1,2},{5,0},{4,2},{3,2},{2,2},
  {5,2},{4,4},{2,0},{2,3},{6,2},{4,4},{3,2},{2,2},
  {6,3},{4,0},{3,0},{2,0},{4,0},{4,4},{3,2},{2,3},
  {6,3},{3,0},{2,0},{2,3},{5,0},{4,2},{3,2},{2,2},{4,0}}

играет первые 4 такта или около того из канона Пахельбеля. (это примерно столько же Канона Пахельбеля, сколько я могу вынести)


7

MATL , 48 47 45 байт

Спасибо @Emigna за исправление относительно формата ввода.

Гитара и код гольф ... Я должен был ответить на этот вопрос!

'$)-27<'i)-'F F# G G# A A# B C C# D D#

Формат ввода: массив строки (на основе 1), затем массив ладов (на основе 0).

Попробуйте онлайн!

объяснение

Некоторые языковые функции, используемые в этом ответе:

  • Строка автоматически преобразуется в числовой массив кодовых точек ASCII, когда к ней применяется какая-либо арифметическая операция.
  • Арифметические операции работают поэлементно , то есть векторизованы. Таким образом, вычитание строки и числового массива одинакового размера дает массив с вычитанием соответствующих записей.
  • Индексирование основано на 1 и является модульным .
  • Массив ячеек , как список на других языках. Он может содержать произвольные элементы, возможно, массивы разных типов или размеров. Здесь будет использоваться массив ячеек для хранения строк разной длины (имен заметок).

Код комментария:

'$)-27<'                       % Push this string
i                              % Take first input (array of guitar strings)
)                              % Index into the string. For example, input [1 3] gives
                               % the string '$-' (indexing is 1-based)
-                              % Implicitly take second input (array of guitar frets).
                               % Subtract element-wise. This automatically converts the
                               % previous string into an array of ASCII codes. For
                               % example, second input [1 5] gives a result [-35 -40],
                               % which is [1 5] minus [36 45], where 36 and 45 are the
                               % ASCII codes of '$-' 
'F F# G G# A A# B C C# D D# E' % Push this string
Yb                             % Split at spaces. Gives a cell array of 12 (sub)strings:
                               % {'F', 'F#', 'G', ..., 'E'}
w)                             % Swap and index into the cell array of strings.
                               % Indexing is 1-based and modular. In the example, since
                               % the cell array has 12 elements, the indexing array
                               % [-35 -40] is the same [1 8], and thus it gives a 
                               % (sub-)array formed by the first and eighth cells: 
                               % {'F', 'C'}. This is displayed as the cells' contents,
                               % one per line

1
Я знал, что найду ответ от вас, как только
увижу

1
@ LuisMendo Очень приятно! Мне нравится трюк с индексом ascii-char :)
Emigna

4

Ява, 174

String f(int[]s,int[]f){String o="";for(int i=0;i<s.length;++i){int n =(7*s[i]-7+f[i]+(s[i]>2?1:0))%12*2;o+="E F F#G G#A A#B C C#D D#".substring(n,n+2).trim()+" ";}return o;}

Ungolfed:

  String f(int[] s, int[] f) {
    String o = "";
    for (int i = 0; i < s.length; ++i) {
      int n = (7 * s[i] - 7 + f[i] + (s[i] > 2 ? 1 : 0)) % 12 * 2;
      o += "E F F#G G#A A#B C C#D D#".substring(n, n + 2).trim() + " ";
    }
    return o;
  }

3

C 104 103 байт

main(s,f){for(;~scanf("%d%d",&s,&f);printf("%.2s\n",
"E F F#G G#A A#B C C#D D#"+(f+7*~-s+(s>2))%12*2));}

Принимает числа в виде string fretпар на стандартном вводе и выводит примечание после каждой пары. Например:

1 4
G#
4 2
E 
5 6
D#
2 3
D 

3

Рубин, 63 байта

принимает массив из 2-х элементов в порядке [string,fret].

->x{x.map{|i|"BEADGCF"[6-n=((i[0]-3)%5+2+i[1]*7)%12]+?#*(n/7)}}

объяснение

В стандартной настройке гитара является одним из немногих струнных инструментов (изогнутых или резных), у которых есть непостоянные интервалы между струнами. Большинство из них имеют либо согласованный 5-полутоновый интервал между всеми парами соседних строк («четвертая»), либо согласованный 7-полутоновый интервал между всеми парами соседних строк («пятая»). Они соответствуют частотным отношениям 3: 4. и 2: 3 соответственно, и уступают по значению только «октаве» с частотным соотношением 1: 2.

Гитара имеет в основном 5-полутоновые интервалы. Если бы он имел 5 из них, он имел бы разницу в 25 полутонов между 1-й и 6-й строками. Вместо этого интервал между 2-й и 3-й струнами уменьшается до 4 полутонов, что дает разницу в 24 полутона (2 октавы), что лучше для игры аккордов.

Это неудобно для программы, поэтому мы начнем с изменения 1-индексированной интонации гитары на 0-индексированную 5-струнную басовую интонацию, которая имеет все интервалы по 5 полутонов:

formula (i[0]-3)%5
Before                            After
String      6 5 4 3 2 1           String 4 3 2 1 0
Note        E A D G B E           Note   B E A D G

Затем мы добавляем 2 и задаем настройку фиктивного 12-струнного баса с интонацией открытых струн следующим образом, и все интервалы составляют 5 полутонов (12 басовых «басов» существуют, но я не уверен, что есть много именно с этим настройка.)

String       11 10 9  8  7  6  5  4  3  2  1  0 
Note         A# D# G# C# F# B  E  A  D  G  C  F

Как видно, все острые предметы сгруппированы вместе. Этот шаблон может повторяться до бесконечности. Он известен как «круг пятых» и является фундаментальным для западной музыкальной шкалы (с небольшой настройкой настройки круг можно замкнуть из-за того, что (3/2)**12и 2**7очень похожи числа.

Теперь мы имеем дело с параметром ладу. В отличие от многих других ответов здесь, которые переводят строковый параметр в несколько раздражений, я преобразовываю параметр раздражения в ряд строк. В приведенной выше таблице видно, что добавление 7 к номеру строки приводит нас к строке, имя примечания которой на полутона выше. (Он находится в совершенно другой октаве, но это не имеет значения.) Итак, мы добавляем i[1]*7к номеру строки и принимаем его по модулю 12:

n=(i[0]-3)%5+2+i[1]*7)%12

Мы вычитаем это из 6, чтобы получить число в диапазоне от 6 до -5, и ищем букву в BEADGCF(Ruby позволяет оборачивать отрицательные индексы обратно в конец массива.) Если n>=7нам нужно добавить #символ для завершения вывода ,

Тестовая программа

f=->x{x.map{|i|"BEADGCF"[6-n=((i[0]-3)%5+2+i[1]*7)%12]+?#*(n/7)}}

z=[[6, 2, 3, 1, 4, 2, 3, 2, 2, 2, 6,5,2],[0, 1, 2, 3, 4 ,5 ,6 ,7, 8, 9, 10, 11, 12]].transpose

puts f[z]

Выход

E
C
A
G
F#
E
C#
F#
G
G#
D
G#
B

3

C #, 131 байт

string n(int[]s,int[]f){return string.Join(" ",s.Zip(f,(x,y)=>"E,F,F#,G,G#,A,A#,B,C,C#,D,D#".Split(',')[(7*x-7+y+(x<3?0:1))%12]));}

Введите два отдельных списка, строки 1 на основе.


1
Добро пожаловать на сайт! Хороший первый ответ.
DJMcMayhem

@DJMcMayhem: Спасибо :-)
Taco

1

Клора , 55 байт

@T[0,7,2,10,5,0,7]+N%12@T[,A,A#,B,C#,D,D#,E,F,F#,G,G#]!

объяснение

@ числовой режим (чтение ввода в виде чисел)

T[0,7,2,10,5,0,7] Преобразование ввода с использованием массива, ex array [Input]

+N Добавить N (следующее значение ввода) к текущему входу

%12 По модулю 12 текущее входное значение

@ Выключить цифровой режим

T[,A,A#,B,C#,D,D#,E,F,F#,G,G#] Перевести ввод в массив

! Использовать ввод как выходное значение


1

Java 7 197163 байта

void f(int[]s,int[]f){String[]l={"A","A#","B","C","C#","D","D#","E","F","F#","G","G#"};int[]d={0,7,2,10,5,0,7};int j=0;for(int i:s)out.print(l[(d[i]+f[j++])%12]);}

Ungolfed

  void f(int[]s,int[]f){
 String[]l={"A","A#","B","C","C#","D","D#","E","F","F#","G","G#"};
int[]d={0,7,2,10,5,0,7};
    int j=0;
    for(int i:s)
        out.print(l[(d[i]+f[j++])%12]);



}

0

Python 2, 94, 91 , 88 байтов

for s,f in input():print"A A# B C C# D D# E F F# G G#".split()[([7,2,10,5,0,7][s]+f)%12]

Вероятно, есть некоторые очевидные улучшения, которые необходимо сделать. Ввод - это список пар, а строки с индексами 0, например:

[0, 4], [3, 2], [4, 6]...

0

Haskell, 83 82 байта

zipWith$(!!).(`drop`cycle(words"A# B C C# D D# E F F# G G# A")).([6,1,9,4,11,6]!!)

Принимает список строк и список раздражений, оба с 0 индексами. Пример использования:

Prelude >  ( zipWith$(!!).(`drop`cycle$words"A# B C C# D D# E F F# G G# A").([6,1,9,4,11,6]!!) ) [0,1,2,3,4,5] [0,0,0,0,0,0]
["E","B","G","D","A","E"]

Из бесконечного списка примечаний, начинающихся с A#, уберите количество примечаний, данных списком [6,1,9,4,11,6]по индексу строки, и выберите примечание по индексу раздражения из оставшегося списка.


К сожалению, интервалы между строками не все равны.
Нил

@Neil: ... исправлено.
Ними,

Это оказалось простым исправлением в JavaScript (s*7)+(s>2)- так что теперь я использую это в своем ответе.
Нил

@Neil: ... тоже работаем над этим.
Ними,

0

JavaScript (ES6), 82 81 байт

a=>a.map(b=>(q=(b[0]+.3+b[1]*7.3|0)%12/1.7+10.3).toString(17)[0]+(q%1>.5?"#":""))

Я хотел попробовать математический ответ, но он получился немного длинным. Может быть, есть способ сыграть в гольф ...

Тестовый фрагмент


Я хотел использовать, toString(17)но изо всех сил пытался получить его в разумном количестве байтов.
Нил

0

PHP, 102 байта

<?foreach($_GET[i]as$t)echo[E,F,"F#",G,"G#",A,"A#",B,C,"C#",D,"D#"][[0,7,3,10,5][$t[0]%5]+$t[1]%12]._;

Ввод в виде множественного массива с 0, например, '[[2,0], [5,3], [2,12], [3,8], [0,3]]'

Хорошая альтернатива 106 байт для установки # на основе конгруэнта мода 7

<?foreach($_GET[i]as$t)echo EFFGGAABCCDD[$d=[0,7,3,10,5][$t[0]%5]+$t[1]%12].["","#"][$d%7?$d%7%2?0:1:0]._;
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.