Перекладіть число пар на ноти гітари


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

Як бачите, перша відкрита рядок (зверху) - це an E. Перша лада на першій струні - це F. Четверта лада на третій струні - a 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](ви можете вибрати, щоб я 0-індексував)
  • 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     

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


Не гітарист (навіть навіть порядний музикант, насправді), але хіба тут немає істотного упущення, якщо ви очікуєте виходу як пізнаваних мелодій? Тобто тривалість ноти - ціла, половина, чверть нот та & c.
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.
Ніл

Набагато ефективніше насправді;)
Арнальд,

Розумний. дуже підступна відповідь
Rohan Jhunjhunwala

7

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

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

The {24,19,15,10,5,0}і 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 барах, що відкриваються, від Pachelbel's Canon (що становить приблизно стільки ж канону Пачельбеля, скільки я витримую)


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
Я знав, що збираюся знайти відповідь у вас, як тільки побачив слово "Гітара"
Suever

1
@LuisMendo Дуже приємно! Мені подобається
трюковий

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

Безумовно:

  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пари на stdin та видає нотатку після кожної пари. Наприклад:

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

3

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

приймає масив двоелементних масивів у порядку [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 октави), що краще для гри акордів.

Це незручно для програми, тому ми почнемо зі зміни інтонаційної гітарної інтонації на 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

Як видно, всі гострики згруповані разом. Ця закономірність може бути повторена ad infinitum. Він відомий як "коло п'ятих" і є основоположним для західної музичної шкали (за допомогою трохи настроювального регулювання коло можна закрити через те, що (3/2)**12і 2**7дуже схожі числа.

Тепер ми розбираємося з параметром fret. На відміну від багатьох інших відповідей тут, які переводять параметр рядка в ряд ладів, я перекладаю параметр fret в ряд рядків. У таблиці вище видно, що додавання 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 масив [Input]

+N Додати N (Наступне вхідне значення) до поточного вводу

%12 Modulo 12 поточне вхідне значення

@ Позначити цифровий режим вимкнено

T[,A,A#,B,C#,D,D#,E,F,F#,G,G#] Перекладіть вхід у масив

! Використовувати введення як вихідне значення


1

Java 7 197, 163 байт

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

Безумовно

  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.