기타 탭을 생성합니까?


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 2016 년

멋진 생각. 내가 놀 시간이 있었으면 좋겠다!
Igby Largeman 2016 년

답변:


9

자바 스크립트, 297 개 277 262 235 223 문자

골프 버전의 캐리지 리턴은 중요하지 않습니다. 그들은 대답을 읽기 쉽게 만들기 위해 존재합니다. 세미콜론은 중요합니다.

편집 : 외부 map를 while 루프 및 기타 편집으로 대체했습니다 . 마지막으로 Golfscript 버전의 2 배 크기 (현재)!

편집 :indexOf 수학으로 대체하고 룩업 테이블과 기타 작은 개선 사항을 세분화했습니다.

편집 : 또 다른 mapfor와 마지막에 넣어 \n내가 불필요하게 식사를하고 있었다. 마지막으로 Jules의 Python 버전 내부.

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

젠장, 내가 생각하는 자바 스크립트 en 부러워. 잘 했어요
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---

나는 이것에 약 1 시간을 보냈으므로 적어도 5 ~ 10 자 줄일 수 있습니다. 개념적으로 DocMax의 솔루션과 매우 유사합니다. 4 가지 경우에 대한 룩업 테이블, 오프셋만큼 증가하고 문자열을 올바른 순서로 조인합니다.


+1 : 저는 골프 스크립트를 좋아합니다! 오늘 여러 번 코드를 다듬을 곳을 찾았지만 50 %는 아닙니다! 나는 통역사가 편리하지 않습니다 : Eb에 대해 D #을 반환합니까?
DocMax

BTW, 명령 줄에 D # m이 표시되지만 샘플의 마지막 메모는 C # m과 일치합니다. 오타 또는 버그?
DocMax

@DocMax, 버그. 왜 그것이 D #이 아닌 D # m에만 영향을 미치는지 이해하지 못합니다. 디버그하는 것이 흥미로울 것입니다. 나는 먼저 7의 블록을 갖는 것이 편리하기 때문에 물건을 재정렬합니다. 따라서 Eb는 실제로 가장자리가 아닙니다.
피터 테일러

마지막 테이블에는 \ n이 포함되어 있는데, 이것은 룩업 테이블에없는 것은 문자와 동등한 값으로 값을 낮추는 것입니다.
피터 테일러

4

이것을 코딩 한 후에, 나는 이것을 훨씬 더 똑똑하게 할 수 있다는 것을 깨달았습니다 ... 아마도 다른 항목을 만들 것입니다. 잘만되면 나는 단지 가장 빠른 것에 대한 포인트를 얻을 것이다!

어쨌든 펄의 문자는 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';}}

첫 번째 파라미터로 기타 튜닝이 필요합니다. 대부분의 비표준 튜닝은 우스꽝스러운 결과를 제공하지만 표준 튜닝에 만족한다고 생각합니다.

호텔 캘리포니아의 경우 할 수 있습니다 $./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---

상단 4 현을 마이너 3 분의 1로 조율하면 열린 현이 없어도 손가락을 건드리지 않고 현을 "오버"하지 않고도 여러 번의 반전으로 3 현 및 4 현 화음을 연주하기가 매우 쉽습니다. 문자열 DFG # B를 사용하면 "Bbm F Bbm Gb Db Ebm Db F Bbm F F7 Bbm"(Mermaid Song)과 같은 코드 시퀀스가 ​​매우 쉽게 작동합니다. 프렛 하나만 위아래로 이동하면됩니다. 반 단계 키 체인지가 있지만 그것은 단지 프렛을 위로 움직이는 것을 의미합니다. 그래도 다른 두 줄로 무엇을 가장 잘하는지 알지 못했습니다.
supercat

@supercat : 흥미 롭습니다. 내일 기타에 이것을 시도 할 것입니다 ...
반 시계 회전을 중지

당신의 생각을 듣고 싶습니다. 몇 번, 몇 년 간격으로 기타를 집어 들었고, 핑거링이 임의적이고 어색한 것처럼 보였기 때문에 계속 포기했습니다. 그런 다음 간단한 핑거링을 허용하는 튜닝에 대해 생각했습니다. 폐쇄 형 코드는 마이너스 1/3에서 퍼펙트 한 네 번째까지의 간격을 갖기 때문에, 현을 마이너스 1/3로 튜닝하면 각 현이 아래 현보다 낮은 지점에서 감쇠됩니다. 왼손잡이 기타를 시험해 볼 수 있다면, 문자열 순서가 반대 인 완벽한 4 분의 1을 시도 할 수 있습니다.
supercat

즉, 마이너스 1/3로 튜닝한다는 것은 가장 낮은 현에서 첫 번째 손가락의 각 위치에 대해 3 개의 주요 코드 반전과 3 개의 작은 코드 반전이 있음을 의미합니다. 두 번째 손가락을 맨 위 세 줄에 놓으면 일곱 번째 코드를 연주 할 수도 있습니다. 머메이드 송의 경우, 세 번째 프렛에서 시작하여 F-Bb-DF (손가락 1-3-3-4)를 재생하십시오. 그런 다음 F는 FACF (1-2-2-4)입니다. Gb는 프렛이고 1-2-2-4 (F처럼)입니다. Db는 프렛 1-3-4-4로 돌아갑니다. Ebm이 1-2-4-4로 백업됩니다.
supercat 2019

건반을 사용하여 적절한 화음 음이 무엇인지 알아 낸 후 몇 곡 (앞서 언급 한 머메이드 곡 포함)을 부드럽게 연주 할 수있는 지점에 도달하는 데 몇 시간 밖에 걸리지 않았습니다. 이 스타일을 시험해 본 후에는 놀라 울 정도로 자연스러운 느낌이 들었고, 각 주요 코드와 작은 코드의 세 가지 반전을 모두 사용할 수있는 방법이 정말 마음에 듭니다. F-Ab-B-Eb-Gb-D와 같은 튜닝으로 이론적으로 쉬운 핑거링으로 6 손가락 메이저 코드와 마이너 코드를 허용 할 수 있습니다 (1-2-2-3-4-4 또는 1). -1-2-3-3-4)이지만 반전이 없습니다.
supercat 2019

2

390 345 340 포스트 스크립트

기타 실용적 접근 방식으로 단순화되었습니다 (E 모양은 A 모양의 변형 일 뿐이며 한 손가락 만 바꾸면 줄이 아래로 이동합니다). 다른 답변에서 인코딩 된 문자열 아이디어를 빌 렸습니다.

[/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\#(껍데기에서 날카로운 부분을 숨기십시오).

않은 golfed 버전은 거의 더 어려워 golfed보다이었다. 그러나 나는 철저하게 노력했다. 편집 : 트릭시 비트에 대한 몇 가지 추가 의견.

%!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---

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.