这是大尺度(或同等学历)吗?


16

沙盒

主音阶(或爱奥尼亚音阶)是最常用的音阶之一,尤其是在西方音乐中。它是全音阶音阶之一。像许多音阶一样,它由七个音符组成:第八个音符以其两倍的频率复制第一个音符,因此它被称为同一音符的更高八度。

七个音符是:

C,D,E,F,G,A,B和C(出于示例目的而重复)

大尺度是全音阶。将先前的音符序列作为主要音阶(实际上,它是音阶C Major)。大音阶音符之间的间隔顺序为:

整个,整个,一半,整个,整个,整个,一半

其中“整个”代表整个音调(图中红色的U形曲线),“半”代表半音(图中红色的虚线)。

在此处输入图片说明

在这种情况下,从C到D存在一个整体色调,从D到E存在一个整体色调,从E到F存在一个色调,等等。

我们有2个成分会影响音符之间的音调距离。它们是尖锐符号(♯)和扁平符号(flat)。

尖锐符号(♯)为音符增加半音。例。从C到D,我们提到存在一个完整的音调,如果我们用C♯代替C,那么从C♯到D则存在一个半音。

扁平符号(♭)与夏普符号相反,它从音符中减去半音。示例:从D到E,我们提到存在一个完整的音调,如果我们使用Db代替D,则从Db到E则存在一个音调的一半。

默认情况下,随音符存在一个全音,除了E to FB to C在短短半音。

请注意,在某些情况下,使用谐音音调可以创建与大音阶等效的音调。这样的一个例子是C#, D#, E#, F#, G#, A#, B#, C#其中E#B#是等音但规模如下一个主标度的序列。


挑战

给定标度,如果是大标度或等效标度,则输出真实值,否则输出伪值。

规则

  • 允许使用标准I / O方法
  • 适用标准规则
  • 您无需考虑8号音符。假设输入将仅包含7个注释
  • 假设不存在双平(♭♭),双尖(♯♯)或自然符号(♮)

测试用例

C, D, E, F, G, A, B                 => true
C#, D#, E#, F#, G#, A#, B#          => true
Db, Eb, F, Gb, Ab, Bb, C            => true
D, E, Gb, G, A, Cb, C#              => true
Eb, E#, G, G#, Bb, B#, D            => true
-----------------------------------------------
C, D#, E, F, G, A, B                => false
Db, Eb, F, Gb, Ab, B, C             => false
G#, E, F, A, B, D#, C               => false 
C#, C#, E#, F#, G#, A#, B#          => false
Eb, E#, Gb, G#, Bb, B#, D           => false

@Abigail基本上是。尽管音符不同,但音色相同。
路易斯·费利佩·德·耶稣·穆诺兹

1
和Cx(或C ##)= D
SaggingRufus

1
顺便说一句,五声音调不必每个字母某项:v
路易斯·费利佩·穆尼奥斯耶稣

1
@Neil色标没有独特的字母,我敢肯定有一种类型的标尺并没有遵循升序
Luis felipe De jesus Munoz

1
我将不得不对此进行投票,因为@Neil对其进行了投票非常感谢
David Conrad

Answers:


11

Perl 6的76 65 63 59个字节

-4字节归功于Phil H

{221222==[~] (.skip Z-$_)X%12}o*>>.&{13*.ord+>3+?/\#/-?/b/}

在线尝试!

说明

*>>.&{ ... }  # Map notes to integers
  13*.ord     # 13 * ASCII code:  A=845 B=858 C=871 D=884 E=897 F=910 G=923
  +>3         # Right shift by 3: A=105 B=107 C=108 D=110 E=112 F=113 G=115
              # Subtracting 105 would yield A=0 B=2 C=3 D=5 E=7 F=8 G=10
              # but isn't necessary because we only need differences
  +?/\#/      # Add 1 for '#'
  -?/b/       # Subtract 1 for 'b'

{                           }o  # Compose with block
            (.skip Z-$_)        # Pairwise difference
                        X%12    # modulo 12
         [~]  # Join
 221222==     # Equals 221222

如果您要进行成对的差分和模12,则不需要减去105;这只是一个补偿。-4个字符:tio.run/...
菲尔^ h

@PhilH是的,当然。谢谢!
nwellnhof

这是将笔记映射到它们的相对值的一种非常聪明的方法,我可以+1!
Sok

10

Node.js的v10.9.078个 76 71 69字节

a=>!a.some(n=>(a-(a=~([x,y]=Buffer(n),x/.6)-~y%61)+48)%12-2+!i--,i=3)

在线尝试!

怎么样?

每个音符ñ[-118-71]被转换为负数其中:

[x, y] = Buffer(n) // split n into two ASCII codes x and y
~(x / .6)          // base value, using the ASCII code of the 1st character
- ~y % 61          // +36 if the 2nd character is a '#' (ASCII code 35)
                   // +38 if the 2nd character is a 'b' (ASCII code 98)
                   // +1  if the 2nd character is undefined

这使:

  n   | x  | x / 0.6 | ~(x / 0.6) | -~y % 61 | sum
------+----+---------+------------+----------+------
 "Ab" | 65 | 108.333 |    -109    |    38    |  -71
 "A"  | 65 | 108.333 |    -109    |     1    | -108
 "A#" | 65 | 108.333 |    -109    |    36    |  -73
 "Bb" | 66 | 110.000 |    -111    |    38    |  -73
 "B"  | 66 | 110.000 |    -111    |     1    | -110
 "B#" | 66 | 110.000 |    -111    |    36    |  -75
 "Cb" | 67 | 111.667 |    -112    |    38    |  -74
 "C"  | 67 | 111.667 |    -112    |     1    | -111
 "C#" | 67 | 111.667 |    -112    |    36    |  -76
 "Db" | 68 | 113.333 |    -114    |    38    |  -76
 "D"  | 68 | 113.333 |    -114    |     1    | -113
 "D#" | 68 | 113.333 |    -114    |    36    |  -78
 "Eb" | 69 | 115.000 |    -116    |    38    |  -78
 "E"  | 69 | 115.000 |    -116    |     1    | -115
 "E#" | 69 | 115.000 |    -116    |    36    |  -80
 "Fb" | 70 | 116.667 |    -117    |    38    |  -79
 "F"  | 70 | 116.667 |    -117    |     1    | -116
 "F#" | 70 | 116.667 |    -117    |    36    |  -81
 "Gb" | 71 | 118.333 |    -119    |    38    |  -81
 "G"  | 71 | 118.333 |    -119    |     1    | -118
 "G#" | 71 | 118.333 |    -119    |    36    |  -83

我们计算这些值之间的模数成对差异为12

2个音符之间的最小可能差是-47,因此在应用模数以确保我们得到肯定的结果之前,加4×12=48就足够了。

12'#'3612=0'b'3812=2

一种N

[N221个222]

一世1个2


好的方法,比我的回答有趣得多
Skidsdev '18

4

的JavaScript(Node.js的)150个 131 125字节

l=>(l=l.map(x=>'C0D0EF0G0A0B'.search(x[0])+(x[1]=='#'|-(x[1]=='b')))).slice(1).map((n,i)=>(b=n-l[i])<0?2:b)+""=='2,2,1,2,2,2'

在线尝试!

Luis felipe表示-19个
字节Shaggy表示-6个字节

取消高尔夫:

function isMajor(l) {
    // Get tone index of each entry
    let array = l.map(function (x) {
        // Use this to get indices of each note, using 0s as spacers for sharp keys
        let tones = 'C0D0EF0G0A0B';
        // Get the index of the letter component. EG D = 2, F = 5
        let tone = tones.search(x[0]);
        // Add 1 semitone if note is sharp
        // Use bool to number coercion to make this shorter
        tone += x[1] == '#' | -(x[1]=='b');
    });
    // Calculate deltas
    let deltas = array.slice(1).map(function (n,i) {
        // If delta is negative, replace it with 2
        // This accounts for octaves
        if (n - array[i] < 0) return 2;
        // Otherwise return the delta
        return n - array[i];
    });
    // Pseudo array-comparison
    return deltas+"" == '2,2,1,2,2,2';
}

1
[...'C0D0EF0G0A0B']而不是'C0D0EF0G0A0B'.split('')+""不是.toString()保存一些字节
Luis felipe De jesus Munoz '18

x[1]=='#'|-(x[1]=='b')而不是再x[1]=='#'?1:(x[1]=='b'?-1:0)保存一些字节
路易斯·菲利佩·德·耶稣·穆诺兹

@LuisfelipeDejesusMunoz哦,谢谢!我不敢相信我忘记了数组扩展并添加了空字符串
Skidsdev,

“如果delta为负,则将其替换为2”听起来是错误的。我认为您需要取模12的差
。– nwellnhof

@nwellnhof在我的测试中,所有主要音阶都以正确的三角洲开头,或者如果跨度为一个八度音阶,则在-10处有一个三角洲而不是2。替换负三角洲可以解决此问题。我不认为-10 % 12 == 2。尽管想到了它,但在某些情况下可能会失败...
Skidsdev

3

198个197 196 189字节

f(l){var i=0,j='',k,n=l.map((m){k=m.runes.first*2-130;k-=k>3?k>9?2:1:0;return m.length<2?k:m[1]=='#'?k+1:m[1]=='b'?k-1:k;}).toList();for(;++i<7;j+='${(n[i]-n[i-1])%12}');return'221222'==j;}

在线尝试!

旧的Perl 6的端口松动/codegolf//a/175522/64722

f(l){
  var i=0,j='',k,
  n=l.map((m){
    k=m.runes.first*2-130;
    k-=k>3?k>9?2:1:0;
    return m.length<2?k:m[1]=='#'?k+1:m[1]=='b'?k-1:k;
  }).toList();
  for(;++i<7;j+='${(n[i]-n[i-1])%12}');
  return'221222'==j;
}
  • 通过对#/ b使用三元运算符来获得-1字节
  • 通过使用ifs而不是三进制进行-1字节转换
  • -7个字节,感谢@Kevin Cruijssen

旧版本 :

飞镖,210字节

f(l){var i=0,k=0,n={'C':0,'D':2,'E':4,'F':5,'G':7,'A':9,'B':11,'b':-1,'#':1},j='',y=[0,0];for(;++i<7;j+='${(y[0]-y[1])%12}')for(k=0;k<2;k++)y[k]=n[l[i-k][0]]+(l[i-k].length>1?n[l[i-k][1]]:0);return'221222'==j;}

在线尝试!

取消高尔夫:

f(l){
  var i=0,k=0,n={'C':0,'D':2,'E':4,'F':5,'G':7,'A':9,'B':11,'b':-1,'#':1},j='',y=[0,0];
  for(;++i<7;j+='${(y[0]-y[1])%12}')
    for(k=0;k<2;k++)
      y[k]=n[l[i-k][0]]+(l[i-k].length>1?n[l[i-k][1]]:0);

  return'221222'==j;
}

整步为2,四分之一为1。如果您跳到更高的八度音阶,则为Mod 12。遍历所有音符并计算第i个音符与第i-1个音符之间的差。连接结果应为221222(2个整体,1个一半,3个整体)。

  • 通过不将0分配给k -2字节
  • 通过使用j作为字符串而不是列表来获得-4字节
  • @Kevin Cruijssen消除了循环中不必要的混乱,获得了-6个字节

我不了解Dart,但部分内容与Java类似。因此:更改i=1i=0可以通过更改for(;i<7;i++)为来减少一个字节for(;++i<7;)。另外,{}可以通过将循环j+=...的第三部分放在内部将括号移开for(;++i<7;j+='${(y[0]-y[1])%12}')。最后一件事是改变return j=='221222';return'221222'==j;摆脱空间。这些修改后为-6(210字节
凯文·克鲁伊森

谢谢,不知道这些循环技巧
Elcan

Np。在新的196字节的版本中,你也可以是高尔夫到189个字节通过改变if(k>9)k--;if(k>3)k--;k-=k>3?k>9?2:1:0;k+=m.length<2?0:m[1]=='#'?1:m[1]=='b'?-1:0;return k;return m.length<2?k:m[1]=='#'?k+1:m[1]=='b'?k-1:k;。:)
Kevin Cruijssen

该死,看来我还有很多东西要学,谢谢!
Elcan

好吧,我已经打了2.5年的高尔夫球,甚至我一直都在打高尔夫球。:)最初很容易错过自己的东西,随着时间的流逝,您会想到各种打高尔夫球的方式。:) 如果您还没有阅读过<all language>打高尔夫球的技巧,可能会很有趣。Java打高尔夫球的一些技巧也可能适用于Dart,因为我在您的答案中所做的高尔夫都是基于我的Java知识,因为这是我第一次见到Dart。;)
Kevin Cruijssen

2

C(gcc)-DA=a[i]+ 183 = 191字节

f(int*a){char s[9],b[9],h=0,i=0,j=0,d;for(;A;A==35?b[i-h++-1]++:A^98?(b[i-h]=A*13>>3):b[i-h++-1]--,i++);for(;j<7;d=(b[j]-b[j-1])%12,d=d<0?d+12:d,s[j++-1]=d+48);a=!strcmp(s,"221222");}

在线尝试!

基于Perl的答案。

将输入作为宽字符串。

取消高尔夫:

int f(int *a){
	char s[9], b[9];
	int h, i, j;
	h = 0;
        for(i = 0; a[i] != NULL; i++){
		if(a[i] == '#'){
			b[i-h-1] += 1;
			h++;
		}
		else if(a[i] == 'b'){
			b[i-1-h] -= 1;
			h++;
		}
		else{
			b[i-h] = (a[i] * 13) >> 3;
		}
	}
	for(j = 1; j < 7; j++){
		int d = (b[j] - b[j-1]) % 12;
		d = d < 0? d + 12: d;
		s[j-1] = d + '0';
	}
	return strcmp(s, "221222") == 0;
}


2

[Wolfram语言(Mathematica)+音乐包],114字节

我喜欢音乐,发现这很有趣,但是当这个代码高尔夫机会降临在长矛上时,我正在玩真正的高尔夫,所以我的投稿有些迟钝。

我想我会尝试一些完全不同的方法,利用一些实际的音乐知识。事实证明,Mathematica的音乐包知道命名音符的基本频率。首先,我将输入字符串转换为命名笔记的序列。接下来,我将每个连续音符的比率乘以小于2的比率(以考虑八度音阶偏移)。然后,我将这些比率与爱奥尼亚音阶的比率进行比较,后者在半音符之间的频率差异大约为6%,在全音符之间的频率差异为12%。

这里花费的字节中有一半以上是用于将输入转换为命名符号的。

.06{2,2,1,2,2,2}+1==Round[Ratios[Symbol[#~~"0"]&/@StringReplace[# ,{"b"->"flat","#"->"sharp"}]]/.x_/;x<1->2x,.01]&

在线尝试!


2

Python 3中175个 136 134 114 112字节

def f(t):r=[ord(x[0])//.6+ord(x[1:]or'"')%13-8for x in t];return[(y-x)%12for x,y in zip(r,r[1:])]==[2,2,1,2,2,2]

在线尝试!


单行Python 3实现。

感谢@Arnauld提供了使用除法和模数计算音调的想法。
感谢@Jo King提供-39个字节。



1

[Python] 269202 字节

来自的改进Jo King

p=lambda z:"A BC D EF G".index(z[0])+"b #".index(z[1:]or' ')-1
def d(i,j):f=abs(p(i)-p(j));return min(f,12-f)
q=input().replace(' ','').split(',')
print([d(q[i],q[i+1])for i in range(6)]==[2,2,1,2,2,2])

尝试一下!

脱手,带有测试驱动程序:

tone = "A BC D EF G"   # tones in "piano" layout
adj = "b #"            # accidentals

def note_pos(note):
    if len(note) == 1:
        note += ' '
    n,a = note
    return tone.index(n) + adj[a]

def note_diff(i, j):
    x, y = note_pos(i), note_pos(j)
    diff = abs(x-y)
    return min(diff, 12-diff)

def is_scale(str):
    seq = str.replace(' ','').split(',')
    div = [note_diff(seq[i], seq[i+1]) for i in (0,1,2,3,4,5)]
    return div == [2,2,1,2,2,2]

case = [
("C, D, E, F, G, A, B", True),
("C#, D#, E#, F#, G#, A#, B#", True),
("Db, Eb, F, Gb, Ab, Bb, C", True),
("D, E, Gb, G, A, Cb, C#", True),
("Eb, E#, G, G#, Bb, B#, D", True),

("C, D#, E, F, G, A, B", False),
("Db, Eb, F, Gb, Ab, B, C", False),
("G#, E, F, A, B, D#, C", False),
("C#, C#, E#, F#, G#, A#, B#", False),
("Eb, E#, Gb, G#, Bb, B#, D", False),
]

for test, result in case:
    print(test + ' '*(30-len(test)), result, '\t',
          "valid" if is_scale(test) == result else "ERROR")

是的,我看到空白区域-恐怕仍然灌有太多PEP-8。我显然错过了一些东西;这里需要执行链接吗?
修剪

1
但是,如果您需要链接,可以快速打高尔夫以获取202个字节。您绝对可以通过更改为其他输入格式来打高尔夫
Jo King

啊...我也很习惯Python返回最终表达式作为过程值。感谢您的指示和提示。
修剪

如果切换到采用字符串列表的函数,则可以获得156个字节。另外,TIO在链接部分提供了自动格式化程序,您可以使用
Jo King

@JoKing,非常欢迎您编辑此答案或发布您自己的答案;通过链接发表评论可以将改进分为一个级别。
修剪

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.