Przetłumacz pary liczb na nuty gitarowe

18

Schemat podstrunnicy gitarowej wygląda następująco:

  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

Jak widać pierwszy otwarty ciąg (od góry) to E. Pierwszy prog na pierwszym sznurku to F. Czwarty próg na trzecim sznurku to B. Zauważ, że pierwsza nuta jest progiem zerowym, a nie pierwszą.

Można to zapisać cyframi w formacie string, fret. Ciągi są ponumerowane od 1 do 6 od góry do dołu. Progi są ponumerowane od 0 do 12 od lewej do prawej. Pierwszy Ejest zatem 1, 0. Kilka innych przykładów:

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

Wyzwanie:

Weź Npary liczb ( si f) i wyślij ograniczoną sekwencję nut.

  • Dane wejściowe mogą mieć dowolny odpowiedni format. krotki, macierz 2D, dwie osobne listy, lista przeplatanych (ciąg, próg, ciąg, próg ...) itp.
  • Ton wyjściowy powinien być oddzielony, ale separator jest opcjonalny (przecinek, spacja, myślnik ...). Dane wyjściowe mogą być pisane wielkimi lub małymi literami.
  • s(dla ciągu) będzie w zakresie [1, 6](możesz zdecydować się na indeksowanie i 0)
  • f (dla progu) będzie w zakresie [0, 12]

Przypadki testowe i przykłady:

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     

Powodzenia i udanej gry w golfa!

Stewie Griffin
źródło
Nie jest gitarzystą (a nawet przyzwoitym muzykiem), ale czy nie ma tu istotnego pominięcia, jeśli oczekujesz, że produkcja będzie rozpoznawalna? To znaczy czas trwania nuty - całe, pół, ćwierćnuty i c.
jamesqf
1
@jamesqf Nie, jest idealnie w porządku, o ile znasz piosenkę. Jest to obecnie najpopularniejsza piosenka na ultimate-guitar.com . Zobacz wprowadzenie.
Stewie Griffin

Odpowiedzi:

4

05AB1E , 48 47 43 40 bajtów

Wykorzystuje kodowanie CP-1252 .

Zarówno ciągi, jak i progi są oparte na 0.

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

Wyjaśnienie

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

Wypróbuj online!

Zaoszczędzono 7 bajtów dzięki Adnan

Emigna
źródło
1
Wykorzystywanie błędów jest bardzo golfowe! .-)
Luis Mendo
"AA#BCC#DD#EFF#GG#"•7V3•3BS£zamiast "A A# B C C# D D# E F F# G G#"#jest o kilka bajtów krótszy :).
Adnan
@Adnan: Ooh, niezła zmiana bazy :)
Emigna
Również skompresowana wersja "AA#BCC#DD#EFF#GG#"łańcucha: •™ÎÚ,Ülu•žh'#A«‡(ponieważ dozwolone są małe litery: p).
Adnan
9

JavaScript (ES6), 79 70 bajtów

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

Wymaga ciągów opartych na 1. Edycja: Zapisano 9 bajtów, bezpośrednio obliczając konwersję ciągu na próg, na podstawie starej odpowiedzi @ nich.

Neil
źródło
@Arnauld Dziękuję, ale zamiast tego zawłaszczyłem odpowiedź @ nimi.
Neil
Rzeczywiście o wiele bardziej wydajny;)
Arnauld
Sprytny. bardzo podstępna odpowiedź
Rohan Jhunjhunwala,
7

Mathematica, 62 bajty (niekonkurujące)

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

Symbole {24,19,15,10,5,0}i E2reprezentują tony otwartych strun sześciu strun gitarowych (na przykład struna górna znajduje się 24 półtonów nad nutą E2). Nie konkuruje, ponieważ nie drukuje nazw nut - odtwarza sekwencję nut! (tylko jeśli masz Mathematica, niestety) Na przykład

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

gra początkowe 4 takty z Kanonu Pachelbela. (co stanowi tyle samo Kanonu Pachelbela, ile mogę znieść)

Greg Martin
źródło
7

MATL , 48 47 45 bajtów

Dzięki @Emigna za korektę formatu wejściowego.

Gitara i golf golf ... Musiałem odpowiedzieć na to!

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

Format wejściowy to: tablica ciągów (opartych na 1), a następnie tablica progów (opartych na 0).

Wypróbuj online!

Wyjaśnienie

Niektóre funkcje językowe użyte w tej odpowiedzi:

  • Ciąg jest automatycznie konwertowany na tablicę numeryczną punktów kodowych ASCII, gdy zostanie do niego zastosowana jakaś operacja arytmetyczna.
  • Operacje arytmetyczne działają elementarnie , tj. Wektoryzują. Odejmowanie ciągu znaków i tablicy numerycznej o tym samym rozmiarze daje tablicę z odejmowaniem odpowiednich wpisów.
  • Indeksowanie jest oparte na 1 i modułowe .
  • Tablica komórek jest jak lista w innych językach. Może zawierać dowolne elementy, być może tablice różnych typów lub rozmiarów. Tutaj tablica komórek będzie używana do przechowywania ciągów o różnych długościach (nazwy nut).

Skomentowany kod:

'$)-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
Luis Mendo
źródło
1
Wiedziałem, że znajdę odpowiedź od ciebie, jak tylko zobaczyłem słowo „Gitara”
Suever
1
@LuisMendo Bardzo miło! Podoba mi się sztuczka z indeksem ascii-char :)
Emigna,
4

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

Nie golfowany:

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

źródło
3

C 104 104 bajtów

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

Pobiera liczby jako string fretpary na standardowe wejście i wysyła notatkę po każdej parze. Na przykład:

1 4
G#
4 2
E 
5 6
D#
2 3
D 
orlp
źródło
3

Rubinowy, 63 bajty

pobiera tablicę tablic 2-elementowych w kolejności [string,fret].

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

Wyjaśnienie

W standardowym strojeniu gitara jest jednym z niewielu instrumentów strunowych (pochylonych lub progowych), który ma niespójne odstępy między strunami. Większość ma albo stały 5-półtonowy odstęp między wszystkimi parami sąsiednich strun („czwarty”) lub spójny 7-półtonowy odstęp między wszystkimi parami sąsiednich strun („piąty”). Odpowiadają one stosunkom częstotliwości 3: 4 i 2: 3, i zajmują drugie miejsce tylko względem „oktawy” ze stosunkiem częstotliwości 1: 2.

Gitara ma przeważnie 5-półtonowe interwały. Gdyby miał 5 z nich, miałby różnicę 25 półtonów między 1. a 6. struną. Zamiast tego odstęp między drugim i trzecim ciągiem jest zredukowany do 4 półtonów, co daje różnicę 24 półtonów (2 oktawy), co jest lepsze do grania akordów.

Jest to niewygodne dla programu, więc zaczynamy od zmiany intonacji gitary 1-indeksowanej na 5-strunową indeksowaną intonację 0, która ma wszystkie interwały 5 półtonów:

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

Następnie dodajemy 2 i strojenie fikcyjnego 12-strunowego basu z intonacją otwartych strun w następujący sposób, a wszystkie interwały mają 5 półtonów (12 basowych „basów” istnieje, ale nie jestem pewien, że jest ich wiele z tym dokładnie strojenie.)

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

Jak widać, wszystkie ostre narzędzia są zgrupowane razem. Ten wzór można powtarzać w nieskończoność. Jest znany jako „koło piątych” i ma fundamentalne znaczenie dla zachodniej skali muzycznej (z drobnymi korektami strojenia koło można zamknąć ze względu na to, że (3/2)**12i 2**7są bardzo podobnymi liczbami.

Teraz mamy do czynienia z parametrem progu. W przeciwieństwie do wielu innych odpowiedzi tutaj, które tłumaczą parametr ciągu na liczbę progów, tłumaczę parametr progu na liczbę ciągów. W powyższej tabeli widać, że dodanie 7 do numeru struny stawia nas na stringu, którego nazwa nuty jest o jeden półton wyższa. (Jest w zupełnie innej oktawie, ale to nie ma znaczenia.) Więc dodajemy i[1]*7do numeru ciągu i przyjmujemy to modulo 12:

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

Odejmujemy to od 6, aby uzyskać liczbę z zakresu od 6 do -5 i sprawdzamy literę w BEADGCF(Ruby pozwala indeksom ujemnym zawinąć się do końca tablicy.) Jeśli n>=7musimy dodać #symbol, aby zakończyć wynik .

Program testowy

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]

Wynik

E
C
A
G
F#
E
C#
F#
G
G#
D
G#
B
Level River St
źródło
3

C #, 131 bajtów

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

Wprowadź dwie osobne listy, ciągi są oparte na 1.

Taco
źródło
1
Witamy na stronie! Dobra pierwsza odpowiedź.
DJMcMayhem
@DJMcMayhem: Dziękuję :-)
Taco
1

Clora , 55 bajtów

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

Wyjaśnienie

@ tryb numeryczny (odczytaj wprowadzane liczby)

T[0,7,2,10,5,0,7] Przekształć dane wejściowe za pomocą tablicy, ex tablica [Input]

+N Dodaj N (następną wartość wejściową) do bieżącego wejścia

%12 Modulo 12 aktualna wartość wejściowa

@ Wyłącz tryb numeryczny flagi

T[,A,A#,B,C#,D,D#,E,F,F#,G,G#] Przetłumacz dane wejściowe na tablicę

! Użyj wartości wejściowej jako wartości wyjściowej

OPSXCQ
źródło
1

Java 7 197, 163 bajty

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

Bez golfa

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



}
Numberknot
źródło
0

Python 2, 94, 91 , 88 bajtów

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]

Prawdopodobnie trzeba wprowadzić pewne oczywiste ulepszenia. Dane wejściowe to lista par, a ciągi są indeksowane 0, np .:

[0, 4], [3, 2], [4, 6]...
DJMcMayhem
źródło
0

Haskell, 83 82 bajtów

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

Pobiera listę ciągów znaków i listę progów, oba indeksowane 0. Przykład użycia:

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

Z nieskończonej listy notatek zaczynających się od A#, upuść liczbę nut podanych przez listę [6,1,9,4,11,6]w indeksie ciągu i wybierz notatkę o indeksie progu z pozostałej listy.

nimi
źródło
Niestety odstępy między łańcuchami nie są równe.
Neil
@ Neil: ... naprawiono.
nimi
Okazało się to prostą poprawką w JavaScript - (s*7)+(s>2)- więc teraz używam tego w mojej odpowiedzi.
Neil
@ Neil: ... też nad tym pracuje.
nimi
0

JavaScript (ES6), 82 81 bajtów

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

Chciałem wypróbować odpowiedź matematyczną, ale okazała się trochę długa. Może istnieje sposób na golfa ...

Testowy fragment kodu

ETHprodukcje
źródło
Chciałem użyć, toString(17)ale walczyłem, aby uzyskać to w rozsądnej liczbie bajtów.
Neil
0

PHP, 102 bajtów

<?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]._;

Wprowadź jako tablicę wielokrotną zarówno 0, na przykład „[[2,0], [5,3], [2,12], [3,8], [0,3]]”

Fajna alternatywa 106 bajtów, aby ustawić # na podstawie przystawki mod 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]._;
Jörg Hülsermann
źródło