이것이 주요 척도입니까?


16

모래 상자

주요 음계 (또는 이오니아 음계)는 특히 서양 음악에서 가장 일반적으로 사용되는 음계 중 하나입니다. 이규모 비늘 중 하나입니다. 많은 음계와 마찬가지로 7 개의 음표로 구성되어 있습니다. 8 분의 1은 주파수의 두 배로 첫 번째 음표를 복제하여 동일한 음의 높은 옥타브라고합니다.

일곱 음표는 다음과 같습니다.

C, D, E, F, G, A, B , C (예시 목적으로 반복)

주요 척도는 음조 척도입니다. 이전의 음표를 주요 음계 (실제로 음계 C 메이저) 로 취합니다 . 메이저 음표 사이의 간격 순서는 다음과 같습니다.

전체, 전체, 반, 전체, 전체, 전체, 반

여기서 "전체"는 전체 톤 (그림에서 빨간색 U 자형 곡선)을 나타내고 "반"은 반음 (그림에서 빨간색 점선)을 나타냅니다.

여기에 이미지 설명을 입력하십시오

이 경우, C에서 D로 전체 톤 이 존재하고 , D에서 E로 전체 톤 이 존재하고 , E에서 F로 중간 톤 이 존재합니다 .

우리는 음 사이의 톤 거리에 영향을주는 2 가지 컴포넌트를 가지고 있습니다. 이것들은 샤프 기호 (♯)와 플랫 기호 (♭)입니다.

샤프 기호 (♯)는 음표에 반음을 추가합니다. 예. C에서 D로 우리는 전체 톤이 존재한다고 언급했습니다. C 대신 C♯를 사용하면 C에서 D까지는 반음이 존재합니다.

플랫 기호 (♭)는 샤프 기호의 반대쪽을 수행하며 음에서 반음을 뺍니다. 예 : D에서 E로 전체 톤이 존재한다고 언급했습니다. D 대신 Db를 사용하면 Db에서 E로 톤과 반이 존재합니다.

기본적으로 주에서 주를 제외하고 전체 톤이 존재 E to F하고 B 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 기본적으로 그렇습니다. 비록 그들은 다른 음이지만 같은 톤을 가지고 있습니다.
Luis felipe De jesus Munoz

1
그리고 Cx (또는 C ##) = D
SaggingRufus 18:32에

1
BTW, 음계 스케일은 각 문자의 하나없는 : V
루이스 펠리페 드 예수님 무 노즈

1
@Neil Chromatic 저울에는 고유 한 글자가 없으며 오름차순을 따르지 않는 스케일종류 가 있다고 확신합니다.
Luis felipe De jesus Munoz

1
@Neil에게 감사의 말을 전하기 때문에 이것을지지해야 할 것입니다
David Conrad

답변:


11

펄 6 , 76 65 63 59 바이트

Phil H 덕분에 -4 바이트

{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/…
Phil H

@PhilH 물론입니다. 감사!
nwellnhof

그것은 메모를 상대 값 +1에서 매핑하는 정말 영리한 방법입니다!
Sok

10

Node.js v10.9.0 , 78 76 71 69 바이트

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

온라인으로 사용해보십시오!

어떻게?

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

474×12=48

12'#'36mod12=0'b'38mod12=2

aNaN

[NaN,2,2,1,2,2,2]

우리는 카운터를 사용합니다 i12


내 대답보다 훨씬 더 흥미로운 접근 방식
Skidsdev

4

자바 스크립트 (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()몇 바이트를 저장
루이스 펠리페 드 예수님 무 노즈

x[1]=='#'|-(x[1]=='b')대신 x[1]=='#'?1:(x[1]=='b'?-1:0)일부는 너무 바이트 저장
루이스 펠리페 드 예수님 무 노즈

@LusfelipeDejesusMunoz 오 감사합니다! 배열 확장과 빈 문자열 추가에 대해 잊어 버렸습니다
Skidsdev

"델타가 음수이면 2로 바꾸십시오."가 잘못 들립니다. 모듈로 12의 차이를 고려해야한다고 생각합니다.
nwellnhof

@nwellnhof 내 테스트에서 모든 주요 스케일에는 올바른 델타가 시작되었거나 옥타브에 걸쳐있는 경우 2가 아닌 -10에서 하나의 델타가있었습니다. 네거티브 델타를 교체하면 문제가 해결됩니다. 나는 생각하지 않습니다 -10 % 12 == 2. 그것을 생각하게되었지만 이것은 어떤 경우에는 실패 할 수 있습니다.
Skidsdev

3

다트 , 19897 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 바이트
  • 스케일 시프트에 삼항 대신 if를 사용하여 -1 바이트
  • @Kevin Cruijssen 덕분에 -7 바이트

구 버전 :

다트 , 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/4은 1입니다. 더 높은 옥타브로 점프 할 경우의 모드 12입니다. 모든 음표를 반복하고 i 번째 음표와 i-1 음표의 차이를 계산합니다. 결과를 연결하고 221222 (2 전체, 절반, 3 전체)를 예상해야합니다.

  • k를 0에 할당하지 않음으로써 -2 바이트
  • j를 목록이 아닌 문자열로 사용하여 -4 바이트
  • 루프에서 불필요한 혼란을 제거하여 @Kevin Cruijssen 덕분에 -6 바이트

다트를 모르지만 부분은 Java와 비슷합니다. 따라서 : 변경 i=1하려면 i=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 바이트 ) .
Kevin Cruijssen

고마워, 루프 트릭에 대해
몰랐어요

Np. 새로운 194 바이트 버전에서는 및 로 변경 하여 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 년 동안 골프를 해왔으며, 심지어 골프를 할 때 항상 팁을 얻었습니다. :) 처음에는 무언가를 놓치기가 쉽고 시간이 지남에 따라 골프를 즐기는 다른 방법에 대해 생각합니다. :) <모든 언어>에서 골프를 치기위한 팁은 아직 읽지 않았다면 흥미로울 것입니다. 내가 대답 한 골프가 Java 지식을 기반으로했기 때문에 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 Language (Mathematica) + Music` 패키지], 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]&

온라인으로 사용해보십시오!



1

[파이썬] 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이 너무 많기 때문에 두렵습니다. 나는 분명히 무언가를 놓쳤다. 여기에 실행 링크가 필요합니까?
Prune

1
그러나 링크를 원하면 202 바이트 로 빠른 골프를칩니다. 다른 입력 형식으로 변경하여 골프를 더
Jo King

아 ... 파이썬에 익숙해 져서 최종 표현을 프로세스 값으로 반환합니다. 포인터와 힌트에 감사드립니다.
Prune

문자열 목록을 가져 오는 함수로 전환 하면 156 바이트 를 얻을 수 있습니다 . 또한, TIO는 링크 섹션에 사용할 수있는 자동 포맷터를 가지고 있습니다
Jo King

@JoKing,이 답변을 편집하거나 직접 게시 할 수 있습니다. 링크로 주석을 달면 개선 사항이 한 수준 씩 분리됩니다.
Prune

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