将数字对转换为吉他音符


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。第三弦上的第四品格是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成对的数字(sf),并输出定界的音符序列。

  • 输入可以是任何合适的格式。元组,2D矩阵,两个单独的列表,一个交织的列表(字符串,字符串,字符串,字符串...)等。
  • 输出音应分开,但定界符是可选的(逗号,空格,破折号...)。输出可以是大写或小写。
  • 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 16/09/27

1
@jamesqf不,只要您知道这首歌就可以了。这是目前最流行的歌曲ultimate-guitar.com。看一下介绍。
Stewie Griffin

Answers:


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#"#短几个字节:)。
阿德南

@Adnan:哦,不错的基数变化:)
Emigna'Sep

也是"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的答案。
尼尔

确实效率更高;)
Arnauld

聪明。非常狡猾的答案
Rohan Jhunjhunwala

7

Mathematica,62个字节(非竞争)

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

{24,19,15,10,5,0}E2代表六根弦吉他的开弦的音调(例如,上面串音符E2上述24个半音)。不竞争,因为它不打印注释的名称,而是播放注释序列!(不幸的是,仅当您拥有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佳能的开头4个小节。(据我所知,这大约是Pachelbel的佳能书)


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

1
@LuisMendo非常好!我喜欢ascii-char索引技巧:)
Emigna

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

Ruby,63个字节

接受2元素数组的数组,顺序为[string,fret]

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

说明

在标准调音中,吉他是为数不多的弦乐器(弓弦或弦拍)之一,弦之间的音程不一致。大多数都在所有相邻弦对之间具有一致的5个半音间隔(“第四”)或在所有相邻弦对之间具有一致的7个半音间隔(“第五”)。这些频率比对应于3:4的频率比。分别为1和2:3,并且仅次于频率比为1:2的“八度”。

吉他的音程大多为5个半音。如果其中有5个,则第一和第六弦之间将有25个半音的差异。取而代之的是,将第二和第三弦之间的间隔减小为4个半音,从而产生24个半音(2个八度)的差异,这更适合演奏和弦。

这对于程序来说很不方便,因此我们首先将1索引的吉他音调更改为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弦“ bass”,但我不确定确切地说有很多)调整)。

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参数。与此处将字符串参数转换为许多字符串的许多其他答案不同,我将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:谢谢您:-)
塔科

1

Clora,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] 使用数组转换输入,例如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]位于字符串索引处的音符数量,然后从其余列表中选择品格索引处的音符。


不幸的是,字符串之间的间隔不是全部相等。
尼尔

@Neil:...固定。
nimi

事实证明这是JavaScript中的简单修复-- (s*7)+(s>2)现在我在答案中使用它。
尼尔

@Neil:...也在努力。
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]._;

作为多个数组,都输入基于0的数字,例如'[[2,0],[5,3],[2,12],[3,8],[0,3]]'

不错的替代106字节来设置基于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]._;
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.