Створення вкладок гітари?


24

Напишіть найкоротшу програму, яка генерує гітарні вкладки для акордів, поданих як введення.

Щоб гітаристи серед вас не мали переваги, і щоб зробити це детермінованим (і, мабуть, простіше кодувати), ось єдині форми акордів, дозволені:

Major chords:

  E   F   F#  G   G#  A   A#  B   C   C#  D   D#
e 0---1---2---3---4---0---1---2---3---4---5---6---
B 0---1---2---3---4---2---3---4---5---6---7---8---
G 1---2---3---4---5---2---3---4---5---6---7---8---
D 2---3---4---5---6---2---3---4---5---6---7---8---
A 2---3---4---5---6---0---1---2---3---4---5---6---
E 0---1---2---3---4---0---1---2---3---4---5---6---

Minor chords:

  Em  Fm  F#m Gm  G#m Am  A#m Bm  Cm  C#m Dm  D#m
e 0---1---2---3---4---0---1---2---3---4---5---6---
B 0---1---2---3---4---1---2---3---4---5---6---7---
G 0---1---2---3---4---2---3---4---5---6---7---8---
D 2---3---4---5---6---2---3---4---5---6---7---8---
A 2---3---4---5---6---0---1---2---3---4---5---6---
E 0---1---2---3---4---0---1---2---3---4---5---6---

Зауважте, що 5 перших акордів та 7 останніх акордів кожної серії мають різні форми.

Усі акорди - прості основні чи мінорні акорди (без 7-ї чи інших варіацій).

Ви також повинні подбати про квартири. Нагадування:

A# = Bb
C# = Db
D# = Eb
F# = Gb
G# = Ab

B#, Cb, E# and Fb are not used

Вихідні дані повинні містити перший стовпець із назвами шнура, як показано вище. Тут не обов’язково вказувати назву акорда зверху. Акорди повинні бути розділені на 3, -як показано вище. Остаточні 3 не -є обов'язковими.

Введення - це рядок, що складається з імен акордів, розділених пробілами.

Приклад введення:

Bm Gb A E G D Em F#

і відповідний вихід:

e 2---2---0---0---3---5---0---2---
B 3---2---2---0---3---7---0---2---
G 4---3---2---1---4---7---0---3---
D 4---4---2---2---5---7---2---4---
A 2---4---0---2---5---5---2---4---
E 2---2---0---0---3---5---0---2---

... і бічне запитання: яка приклад пісні? :)
Jules Olléon

5
Готель Каліфорнія: P
Метью читайте

Так, ви виграєте! :)
Jules Olléon

Класна ідея. Бажаю, я встиг пограти!
Ігбі Ларгеман

Відповіді:


9

JavaScript, 297 277 262 235 223 символів

Жодна віддача вагона у версії для гольфу не є значною; вони є лише для того, щоб зробити відповідь читабельною. Точки з комою значні.

Редагувати: Замінено зовнішню mapпетлю на час та інші зміни. Нарешті всередині 2 × розмір версії Golfscript (поки що)!

Редагувати: замінив indexOfматематику, розбив таблицю пошуку, інші невеликі вдосконалення.

Edit: Ще mapдо forі покласти в остаточному \nя був надмірно їжі. Нарешті всередині версії Python Jules.

i=prompt(o='').split(' ');for(r=6;o+=' EADGBe'[r]+' ',r--;o+='\n')
for(j=0;n=i[j++];o+=(([84,13,52,5][2*/m/.test(n)+x]*8>>2*r&3)+y-7*x)+'---')
y=n.charCodeAt(0),y=(2*y-(y>66)-(y>69)+(n[1]<'$')-(n[1]=='b')+2)%12,x=y>6;alert(o)

Вихідні дані більше не користуються тим, що трейлінг ---є необов'язковим як:

e 2---2---0---0---3---5---0---2---
B 3---2---2---0---3---7---0---2---
G 4---3---2---1---4---7---0---3---
D 4---4---2---2---5---7---2---4---
A 2---4---0---2---5---5---2---4---
E 2---2---0---0---3---5---0---2---

Чорт, я думаю, що у мене JavaScript-заздрість. Чудово зроблено.
kekekela

7

Гольфскрипт, 136 символів

[["eBGDAE"{[]+" "+}/]]\" "/{.-2\{"bm#A B C D E F G"?.)!!*(+}/14%.3>-.8>-.7/@109?0>2*+[963 780 882 753]{3base(;}%=\7%{+'---'+}+%}%+zip n*

Повністю 23 символи (17,5%) мають справу з цими двома символами на початку кожного рядка виводу.

Вибірка зразка, тестування крайових корпусів:

$ golfscript.rb tabs.gs <<<"E G# Ab A Db D# Em G#m Abm Am D#m"
e 0---4---4---0---4---6---0---4---4---0---5---
B 0---4---4---2---6---8---0---4---4---1---6---
G 1---5---5---2---6---8---0---4---4---2---7---
D 2---6---6---2---6---8---2---6---6---2---7---
A 2---6---6---0---4---6---2---6---6---0---5---
E 0---4---4---0---4---6---0---4---4---0---5---

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


+1: Людина, яку я люблю Гольфскрипт! Сьогодні я декілька разів знаходив місця для обрізки коду, але не на 50%! У мене немає перекладача під рукою: чи повертається D # за Eb?
DocMax

BTW, остання примітка у вашому зразку відповідає C # m, хоча в командному рядку вказано D # m. Друкарська помилка чи помилка?
DocMax

@DocMax, помилка. Я не розумію, чому це впливає лише на D # m, а не на D # - це буде цікаво налагодити. Я переупорядковую речі, тому що зручно спочатку мати блок 7, тому Eb насправді не є кращим випадком.
Пітер Тейлор

Виявляється, що останній включав \ n включеного, який, не перебуваючи в таблиці пошуку, тягнув значення вниз, еквівалент букві.
Пітер Тейлор

4

Програмувавши це, я зрозумів, що міг би зробити це набагато розумніше ... можливо, я зроблю ще один запис. Сподіваюсь, я лише отримаю бали за те, що буду найшвидший!

У будь-якому випадку, на Perl є 962 символи.

%c =(B=>{E=>0,F=>1,Gb=>2,G=>3,Ab=>4,A=>2,Bb=>3,B=>4,C=>5,Db=>6,D=>7,Eb=>8,Em=>0,Fm=>1,Gbm=>2,Gm=>3,Abm=>0,Am=>1,Bbm=>2,Bm=>3,Cm=>4,Dbm=>5,Dm=>6,Ebm=>7},G=>{E=>1,F=>2,Gb=>3,G=>4,Ab=>5,A=>2,Bb=>3,B=>4,C=>5,Db=>6,D=>7,Eb=>8,Em=>0,Fm=>1,Gbm=>2,Gm=>3,Abm=>4,Am=>2,Bbm=>3,Bm=>4,Cm=>5,Dbm=>6,Dm=>7,Ebm=>8},D=>{E=>2,F=>3,Gb=>4,G=>5,Ab=>6,A=>2,Bb=>3,B=>4,C=>5,Db=>6,D=>7,Eb=>8,Em=>2,Fm=>3,Gbm=>4,Gm=>5,Abm=>6,Am=>2,Bbm=>3,Bm=>4,Cm=>5,Dbm=>6,Dm=>7,Ebm=>8},A=>{E=>2,F=>3,Gb=>4,G=>5,Ab=>6,A=>0,Bb=>1,B=>2,C=>3,Db=>4,D=>5,Eb=>6,Em=>2,Fm=>3,Gbm=>4,Gm=>5,Abm=>6,Am=>0,Bbm=>1,Bm=>2,Cm=>3,Dbm=>4,Dm=>5,Ebm=>6},E=>{E=>0,F=>1,Gb=>2,G=>3,Ab=>4,A=>0,Bb=>1,B=>2,C=>3,Db=>4,D=>5,Eb=>6,Em=>0,Fm=>1,Gbm=>2,Gm=>3,Abm=>4,Am=>0,Bbm=>1,Bm=>2,Cm=>3,Dbm=>4,Dm=>5,Ebm=>6});
%b=('A#'=>'Bb','C#'=>'Db','D#'=>'Eb','F#'=>'Gb','G#'=>'Ab');
foreach(qw(e B G D A E)){p($_,@ARGV)}
sub p{$s = shift;print "$s ";$s = uc($s);foreach(@_){while(($h,$f)=each(%b)){s/$h/$f/}print "$c{$s}->{$_}---"}print "\n"}

Ось відповідний вихід.

dhrasmus:Desktop standage$ perl guitar Bm Gb A E G D Em F#
e 2---2---0---0---3---5---0---2---
B 3---2---2---0---3---7---0---2---
G 4---3---2---1---4---7---0---3---
D 4---4---2---2---5---7---2---4---
A 2---4---0---2---5---5---2---4---
E 2---2---0---0---3---5---0---2---

4

Оскільки коротші рішення вже були надані (чорт за вас, GolfScript!), Ось моє:

Пітон, 229 символів

s=[("E EmF FmF#GbG GmG#AbA AmA#BbB BmC CmC#DbD DmD#Eb".find("%-02s"%s[:2])/4,s[-1]!='m')for s in raw_input().split()]
for c in range(6):
 l='eBGDAE'[c]+' '
 for(i,M)in s:x=i>4;l+=`i-5*x+2*(2<c+x<5)+(M+x)*(c==2-x)`+"---"
 print l

Вихід:

> echo "Bm Gb A E G D Em F#" | python guitar.py
e 2---2---0---0---3---5---0---2---
B 3---2---2---0---3---7---0---2---
G 4---3---2---1---4---7---0---3---
D 4---4---2---2---5---7---2---4---
A 2---4---0---2---5---5---2---4---
E 2---2---0---0---3---5---0---2---

3

Пітон, 449 символів

z=int
f=str
r=range
j=''.join
n='E F F# G G# A A# B C C# D D#'.split()
n+=[x+'m'for x in n]
c=[j([f(z(x)+i)for x in'001220'])for i in r(5)]+[j([f(z(x)+i)for x in'022200'])for i in r(7)]
c+=[x[:2]+f(z(x[2])-1)+x[3:]for x in c[:5]]+[x[0]+f(z(x[1])-1)+x[2:]for x in c[5:]]
a=[c[n.index((chr(ord(i[0])-1)+'#'+i[2:]).replace('@','G')if len(i)-1 and i[1]=='b'else i)]for i in raw_input().split()] 
for i in r(6):print'eBGDAE'[i],j([x[i]+'-'*3 for x in a])

3

C99 - 231 символ

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

#include<stdio.h>
int main(int c,char**v){for(char*o="e0)B2)G2*D2+A0+E0)",i,m;*o;o+=3,v-=c,puts(""))for(printf("%c ",*o);*++v;printf("%c---",i-(i>2)-i/9+o[1+i/8]-(*o-66-i/8*5?0:m?m+2[*v]>99:0)))m=1[*v],i=(**v*2-4+m/35-m/98*3)%14;}

Проба зразка:

$ ./a.out Bm Gb A E G D Em F#
e 2---2---0---0---3---5---0---2---
B 3---2---2---0---3---7---0---2---
G 4---3---2---1---4---7---0---3---
D 4---4---2---2---5---7---2---4---
A 2---4---0---2---5---5---2---4---
E 2---2---0---0---3---5---0---2---

Без гольфу

#include<stdio.h>
int main(int c,char**v){
     // o points to three characters per output line:
     //   string name, number for A, adjusted number for E (ASCII code minus 7)
     char* o="e0)B2)G2*D2+A0+E0)",
          i, // chord: A=0, A#=1, ..., G#=13, allowing also 3="E#" and 9="B#"
          m; // second character in chord name
     for (; *o; o+=3) {
          printf("%c ", *o);
          for (; *++v; ) {
               m = 1[*v],
               i = (**v*2-4+m/35-m/98*3)%14; // parse & adjust for sharp, flat
               printf("%c---",
                      i-(i>2)-i/9 // eliminate "E#", "B#"
                      +o[1+i/8] // get the number for a major chord
                      // adjust for minor...
                      -(*o-66-i/8*5
                        ? 0
                        : m ? m+2[*v]>99 : 0));
          }
          v -= c; // rewind argument pointer
          puts("");
     }
}

Нестандартний C - 206 символів

Якщо нас не цікавлять специфікації мови, GCC може скласти наступний однокласник у функціональний бінарний файл, навіть якщо він змішує декларації змінної C99 з декларацією аргументу стилю K&R (і неявною заявою printf).

main(c,v)char**v;{for(char*o="e0)B2)G2*D2+A0+E0)",i,m;*o;o+=3,v-=c,puts(""))for(printf("%c ",*o);*++v;printf("%c---",i-(i>2)-i/9+o[1+i/8]-(*o-66-i/8*5?0:m?m+2[*v]>99:0)))m=1[*v],i=(**v*2-4+m/35-m/98*3)%14;}

2

C ++, 432

#include <cmath>
#include <iostream>
F(int c){c-=65;return c*1.6+sin(c/5.+.3);}
T(int a,int s){if(s)return(a=(T(a,s-1)+2)%3)-=(a==1&s>2);return(a<7)*2;}
#define c(a,b) while(*(++j)==a)b;--j; 
#define O std::cout<<
main(int a,char*p[]){
int P=2;for(int i=-1;++i<6;P=2){O p[1][i];O" ";while(P<a){char*j=p[P++];
int f=F(*j);c('#',++f)c('b',--f)
int t=T(f,i)*3.5;if(*(++j)!='m'){--j;t+=(t==3);}
O(f-F(p[1][i])+t+24)%12;O"---";
}O'\n';}}

Зауважте, що для цього потрібна настройка гітари як перший параметр. (Більшість нестандартних налаштувань дадуть вам смішні результати розбиття пальців, але, мабуть, ви задоволені стандартною настройкою.)

Для готелю California ви можете це зробити $./a.out EBGDAE Cbm Gb Bbb Fb G D Em F# Bm F# G## D## F## C## D##m E##. Результат:

E 2---2---0---0---3---5---0---2---2---2---5---0---3---5---0---2---
B 3---2---2---0---3---7---0---2---3---2---5---0---3---7---0---2---
G 4---3---2---1---4---7---0---3---4---3---6---1---4---7---0---3---
D 4---4---2---2---5---7---2---4---4---4---7---2---5---7---2---4---
A 2---4---0---2---5---5---2---4---2---4---7---2---5---5---2---4---
E 2---2---0---0---3---5---0---2---2---2---5---0---3---5---0---2---

Настроювання верхніх чотирьох струн на незначні третини дозволяє дуже легко відтворювати три- і чотириструнні акорди в багатьох інверсіях, без відкритих струн і без необхідності розміщувати палець «над» струною, не торкаючись її. Використовуючи рядки DFG # B, дуже легко виходить послідовність акордів типу "Bbm F Bbm Gb Db Ebm Db F Bbm F F7 Bbm" (Пісня русалки). Потрібно лише зміщуватися вгору і вниз однією лапою. Існує півкрокова зміна клавіш, але це просто означає, як рухатися вгору. Не зрозумів, що найкраще робити з іншими двома струнами.
supercat

@supercat: Цікаво, я спробую це на своїй гітарі завтра ...
перестав повертати проти годинника,

Я хотів би почути, що ти думаєш. Я брав гітару декілька разів, років один від одного, і продовжував здаватися, тому що пальці здавалися як довільними, так і незграбними. Потім я задумався над тим, які тюнінг дозволить простувати пальцями. Оскільки акорди закритої форми мають інтервали, що варіюються від другої третини до ідеальної четвертої, то налаштування струн до другої третини означає, що кожна струна буде затухана в точці, яка не нижче, ніж рядок нижче. Якщо я можу спробувати гітару з лівою рукою, я можу спробувати ідеальні четвертки зі зворотним порядком струн, оскільки це має бути подібним.
supercat

Налаштування незначної третини означає, що для кожного положення першого пальця на нижній струні буде три основних інверсії акорда та три незначні інверсії акорда. Можна також відіграти сьомий акорд, розмістивши другий палець в трьох верхніх струнах. Для Русалки Пісня, почніть з третьої ладу і грайте в F-Bb-DF (пальцями 1-3-3-4). Тоді F - FACF (1-2-2-4). Gb вгору лада, пальцем 1-2-2-4 (як F). Db повертається до ладу, 1-3-4-4. Ебм резервний, 1-2-4-4.
supercat

Пройшло лише кілька годин, щоб дістатись до того, що я могла плавно відтворити деякі твори (включаючи вищезгадану Пісню Русалки) після того, як опрацювати за допомогою клавіатури, якими мають бути належні акорди. Одного разу я спробував цей стиль, він відчув дивовижний природний характер, і мені дуже подобається те, як можна використовувати всі три інверсії кожного основного та мінорного акорду. Якщо ви хотіли лише мажорних та мінорних акордів, то налаштування на зразок F-Ab-B-Eb-Gb-D теоретично могла б дозволити шість пальців основних та мінорних акордів легкими пальцями (1-2-2-3-4-4 або 1 -1-2-3-3-4), але без інверсій.
supercat

2

390 345 340 Постскрипт

Спрощений до гітарно-прагматичного підходу (форма Е - це лише зміна форми А, зміщеної вниз струною, зміною одним пальцем). Позичив ідею закодованого рядка з інших відповідей.

[/p{print}/x{exch}/e{cvx exec}/d{dup 0
get}/f{forall}(A0#1B2C3D5E7F8G:b;){}forall/m{dup
4 2 copy get 1 sub put}109{m 48}/+{[3 1 roll x{1
index add x}f]}/*{[0 0 2 2 2 0 0]x{load e 48 sub
+}f d 12 gt{-12 +}if d 6 gt{m -7 + 1}{0}ifelse 6
getinterval}>>begin[ARGUMENTS{*}f][(E)(A)(D)(G)(B)(e)]6{[x
e p( )p]x[x{[x e( )cvs p(---)p]}f]x()=}repeat

Раніше:

450 442 418 Постскрипт

Я виправив вихідний формат і з цим. (Попередні версії починалися з "E ---", а не "e".)

<</i{index}/a{add}/p{pop}/x{exch}/g{getinterval}/r{print}/f{forall}/e{exec}>>begin<<65[0
2 3 5 -5 -4 -2]{1 i 1 a}f p 35{1 a}98{1 sub}109{x dup
4 20 put x}>>begin[ARGUMENTS{[x[0 5 12 17 21 24 29
0]x{load e}f x{1 i a x}f]dup 0 get 0 ge{0}{1}ifelse 7
g[0 -5 -10 -15 -19 -24 -29]0 1 6{2 copy get 3 i 2 i
get a 3 copy put p p}for x p 0 6
g}f][(E)(A)(D)(G)(B)(e)]6{[x cvx e r( )r]x[x{[x cvx
e( )cvs r(---)r]}f]x(\n)r}repeat

Як його запустити: gsnd -q -- tab.ps Bm Gb A E G D Em F\#(сховай гострий від оболонки).

Версія без гольфу була майже складніше, ніж версія для гольфу. Але я намагався бути ретельним. Редагувати: ще кілька коментарів до хитрощів.

%!PS
<<    %axioms and operations
/t{2 2 1}    %major tetrachord
/m{t t 2}    %mixolydian mode
/u{2 1 2}    %minor tetrachord
/a{u u}      %aolian mode
/s{m m t}    %2.5-octave mixolydian intervals
/r{3 1 roll}
/${[exch 0 exch{1 index add}forall]}    %running sum: convert (relative)intervals to (abstract)fretstops
/+{[r exch{1 index add exch}forall pop]}    %scale array by scalar
/@{[r{2 copy get r pop}forall pop]}    %select array elements from array of indices
/&{0 1 3 index length 1 sub{    %array2 += array1
    2 copy get 3 index 2 index get add 3 copy put pop pop}for exch pop}
>>begin<<    %map ascii values to scaling functions
65[a]$    %generate fretstops of the A aolian scale to assign scalars to note names
[0 0 0 0 -12 -12 -12]&    %drop E F and G down an octave
{[exch/+ cvx]cvx 1 index 1 add}forall pop    %generate the pairs 'A'->{0 +}, 'B'->{2 +}
35{1 +}     %'#'-> scale up by one
98{-1 +}    %'b'-> scale down by one
109{dup 4 2 copy get 1 sub put}     %'m'-> tweak the 'third' down by one
%generate chord pattern from (string)
/*{[s]$       %generate fretstops of the E mixolydian scale
  [1 4 8 11 13 15 18]    %A-shape figured bass: IV chord of E mixolydian
  -1 +       %convert scale degrees to array indices
  @       %generate chord template by selecting indices from mixolydian scale
  exch{load exec}forall       %execute ascii values, scaling the pattern
  dup 0 get 0 ge{0}{1}ifelse 6 getinterval    %discard first note if it has fallen off the bottom
  [0 -5 -10 -15 -19 -24]&}    %subtract the string offsets
>>begin    %activate definitions
%(A)* pstack()= clear    %[0 0 2 2 2 0]
%(B)* pstack()= clear    %[2 2 4 4 4 2]
%(F#)* pstack()= clear    %[2 4 4 3 2 2]
%(Abm)* pstack()=    %[4 6 6 4 4 4]
[ARGUMENTS{*}forall]    %convert array of strings to array of patterns
[(E)(A)(D)(G)(B)(e)]    %array of string names
6{    %for each "string"
    [exch cvx exec print( )print]    %pop string name and print with space
    exch       %put names behind numbers
    [exch{     %for each "chord"
        [exch cvx exec( )cvs print(---)print]    %pop number, convert, print with trailing hyphens
    }forall]    %zip up chord array for next iteration
    ()=         %print a newline
    exch        %put numbers behind names
}repeat

А як щодо Будинку Східного сонця як випробування?

04:51 PM:~ 0> gsnd -q -- tabb.ps Em G A C Em G B B Em G A C Em B Em B|sed 's/^/    /'
e 0---3---0---3---0---3---2---2---0---3---0---3---0---2---0---2---
B 0---3---2---5---0---3---4---4---0---3---2---5---0---4---0---4---
G 0---4---2---5---0---4---4---4---0---4---2---5---0---4---0---4---
D 2---5---2---5---2---5---4---4---2---5---2---5---2---4---2---4---
A 2---5---0---3---2---5---2---2---2---5---0---3---2---2---2---2---
E 0---3---0---3---0---3---2---2---0---3---0---3---0---2---0---2---

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