数字のペアをギターの音に変換する


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です。3番目の文字列の4番目のフレットは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マトリックス、2つの個別のリスト、織り交ぜられたリスト(string、fret、string、fret ...)など。
  • 出力トーンは分離する必要がありますが、区切り文字はオプションです(コンマ、スペース、ダッシュ...)。出力は大文字でも小文字でもかまいません。
  • s(文字列の場合)は範囲内にあります[1, 6](i 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

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

オンラインでお試しください!

Adnanのおかげで7バイト節約


1
バグを悪用するのは非常に難しいです!.-)
ルイスメンドー

"AA#BCC#DD#EFF#GG#"•7V3•3BS£代わりに"A A# B C C# D D# E F F# G G#"#、数バイト短くなります:)。
アドナン

@アドナン:ああ、すてきな基本変更:)
エミグナ

また、"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ベースの文字列が必要です。編集:@nimiの古い回答に基づいて、フレットからフレットへの変換を直接計算して、9バイトを保存しました。


@Arnauldありがとう。でも、代わりに@ nimiの答えを流用することになりました。
ニール

はるかに効率的に確か;)
アルノー

賢い。非常に卑劣な答え
ローハンジュンジュンワラ

7

Mathematica、62バイト(非競合)

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

{24,19,15,10,5,0}そしてE2(例えば、上部列はノートE2上記24個の半音である)は、6本のギター弦の開放弦トーンを表します。ノートの名前を印刷しないため、競合しません。ノートのシーケンスを再生します。(残念ながら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}}

Pachelbel's Canonのオープニングを4曲ほど演奏します。(これは、PachelbelのCanonとほぼ同じくらいです)


7

MATL48 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とても素敵!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;}

ゴルフをしていない:

  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 fretstdinでペアとして数値を取得し、ペアごとにノートを出力します。例えば:

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

説明

標準的なチューニングでは、ギターは弦の間隔に一貫性がない数少ない弦楽器(弓またはフレット)の1つです。ほとんどの場合、隣接するストリングのすべてのペア間で一貫した5セミトーン間隔(「4番目」)、または隣接するストリングのすべてのペア間で一貫した7セミトーン間隔(「5番目」)があります。それぞれ2:3であり、周波数比1:2の「オクターブ」に次いで2番目に重要です。

ギターの大部分は5半音間隔です。これらが5つある場合、1番目と6番目の文字列の間に25半音の差があります。代わりに、2番目と3番目の文字列の間隔が4半音に短縮され、和音の演奏に適した24半音(2オクターブ)の差が与えられます。

これはプログラムにとって不便です。そのため、1インデックスのギターイントネーションを、5セミトーンのすべての間隔を持つ0インデックスの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)**122**7非常に類似番号です。

ここで、fretパラメーターを扱います。ここでの文字列パラメーターをいくつかのフレットに変換する他の多くの回答とは異なり、フレットパラメーターをいくつかの文字列に変換します。上記の表では、文字列番号に7を追加すると、音名が1半音高い文字列になります。(これは完全に異なるオクターブにありますが、それは問題ではありません。)したがって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]));}

2つの個別のリストを入力します。文字列は1ベースです。


1
サイトへようこそ!いい最初の答え。
DJMcMayhem

@DJMcMayhem:ありがとう:-)
タコ

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 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]し、残りのリストからフレットのインデックスで音符を選択します。


残念ながら、文字列間の間隔はすべて同じではありません。
ニール

@ニール:...修正。
nimi

JavaScriptの簡単な修正であることが判明しました(s*7)+(s>2)--私は今、答えでそれを使用しています。
ニール

@ニール:...それに取り組んでいます。
nimi

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

'[[2,0]、[5,3]、[2,12]、[3,8]、[0,3]]'のように両方とも0に基づく複数の配列として入力

Mod 7一致に基づいて#を設定するための素晴らしい代替106バイト

<?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]._;
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.