Bu Büyük Ölçekli mi (veya muadili) mi?


16

Kum havuzu

Ana ölçek (veya İyon ölçeği), özellikle Batı müziğinde en yaygın kullanılan müzik ölçeklerinden biridir. Diyatonik ölçeklerden biridir. Birçok müzikal terazi gibi, yedi notadan oluşur: sekizinci, birinciyi frekansının iki katında çoğaltır, böylece aynı notanın daha yüksek bir oktavı olarak adlandırılır.

Yedi nota:

C, D, E, F, G, A, B , C (örneğin amaçlar için tekrarlanır)

Ana ölçek diyatonik bir ölçektir. Önceki notları büyük bir ölçek olarak alın (Aslında, C Major ölçeğidir) . Büyük bir ölçeğin notları arasındaki aralıkların sırası:

bütün, bütün, yarım, bütün, bütün, bütün, yarım

burada "bütün" bütün bir tonu (şekilde kırmızı bir u-şekilli eğri) ve "yarım" bir yarı tonu (şekilde kırmızı kırık bir çizgi) temsil eder.

resim açıklamasını buraya girin

Bu durumda, D'ye C bir mevcut bütün D'den E'ye tonu, bir mevcut bütün mevcut F E'den, sesi yarım sesi vs ...

Notlar arasındaki ton mesafesini etkileyen 2 bileşenimiz var. Bunlar Keskin sembol (♯) ve düz sembol (♭).

Keskin sembol (♯) nota yarım ton ekler. Misal. C'den D'ye bütün bir ton olduğunu söylemiştik, eğer C yerine C if kullanırsak, C♯'den D'ye yarım ton var demektir.

Düz sembolü (♭) Keskin sembolünün tersini yapar, notadan yarım ton çıkarır. Örnek: D'den E'ye bütün bir ton olduğunu söyledik, eğer Db yerine Db kullanırsak Db'den E'ye bir ton bir buçuk var.

Varsayılan olarak, Not'tan Not'a, yalnızca yarım tonun olduğu E to Fve dışındaki bir B to Cton vardır.

Not Binbaşı Ölçeği için bir eş değer oluşturabilir enharmonic sahaları kullanılarak bazı durumlarda. Bunun bir örneği C#, D#, E#, F#, G#, A#, B#, C#nerede E#ve B#enharmoniktir ancak ölçek Büyük Ölçek dizisini takip eder.


Meydan okuma

Bir ölçek verildiğinde, bir Büyük Ölçek veya eşdeğeri ise doğruluk değeri verir, aksi takdirde bir falsey değeri verir.

kurallar

  • Standart G / Ç yöntemine izin verilir
  • Standart kuralları geçerlidir
  • 8. notu dikkate almanıza gerek yoktur. Girişin yalnızca 7 notadan oluştuğunu varsayalım
  • Çift düz (♭♭), çift keskin (♯♯) veya doğal işaret (♮) bulunmadığını varsayalım

Test senaryoları

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 Temel olarak evet. Farklı notalar olmasına rağmen aynı tona sahiptirler.
Luis felipe De jesus Munoz

1
ve Cx (veya C ##) = D
SarkmaRufus

1
Btw, Pentatonic pulların her harfinden birine sahip değil: v
Luis felipe De jesus Munoz

1
@Neil Kromatik ölçeklerin benzersiz harfleri yoktur ve eminim artan bir düzeni takip etmeyen bir ölçek türü vardır
Luis felipe De jesus Munoz

1
@Veil çok teşekkür ederim çünkü çok teşekkür ederim
David Conrad

Yanıtlar:


11

Perl 6 , 76 65 63 59 bayt

Phil H sayesinde -4 bayt

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

Çevrimiçi deneyin!

açıklama

*>>.&{ ... }  # 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

İkili bir fark ve modulo 12 yapacaksanız, 105 çıkarmanız gerekmez; bu sadece bir ofset. -4 karakter: tio.run/…
Phil H

@PhilH Evet, elbette. Teşekkürler!
nwellnhof

Bu notları göreceli değerlerine eşlemenin gerçekten akıllıca bir yolu, benden +1!
Sok

10

Node.js v10.9.0 , 78 76 71 69 bayt

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

Çevrimiçi deneyin!

Nasıl?

Her n notası [-118,-71] de negatif bir sayıya dönüştürülür :

[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

Hangi verir:

  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

Bu değerler arasındaki modulo 12 ikili farklarını hesaplıyoruz .

2 nota arasındaki olası en düşük fark -47 , bu nedenle olumlu bir sonuç elde ettiğimizden emin olmak için modüloyu uygulamadan önce 4x12=48 eklemek yeterlidir .

12'#'36şık12=0'b'38şık12=2

birNaN

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

ben12


Harika bir yaklaşım,
cevabımdan

4

JavaScript (node.js) , 150 131 125 bayt

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'

Çevrimiçi deneyin!

Luis felipe sayesinde -19 bayt
Shaggy sayesinde -6 bayt

Ungolfed:

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']yerine 'C0D0EF0G0A0B'.split('')ve bazı baytları kurtarmak +""yerine.toString()
Luis felipe De jesus Munoz

x[1]=='#'|-(x[1]=='b')x[1]=='#'?1:(x[1]=='b'?-1:0)bazı baytları da kaydetmek yerine
Luis felipe De jesus Munoz

@LuisfelipeDejesusMunoz Ah güzel teşekkürler! Dizi genişletmeyi ve boş bir dize eklemeyi unuttuğuma inanamıyorum
Skidsdev

"Delta negatifse, 2" ile değiştirin. Yanlış geliyor. Ben fark modulo 12. almak gerektiğini düşünüyorum
nwellnhof

@nwellnhof Testlerimde, tüm büyük ölçeklerde ya başlangıç ​​için doğru deltalar vardı ya da bir oktav yayıyorlarsa, 2 yerine -10'da bir delta vardı. Negatif deltaların değiştirilmesi bunu düzeltiyor. Düşünmüyorum -10 % 12 == 2. Her ne kadar düşünmeye gelse de bu bazı durumlarda başarısız olabilir ...
Skidsdev

3

Dart , 198197196189 bayt

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

Çevrimiçi deneyin!

Eski Perl 6 cevabının gevşek limanı /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 için üçlü işleçler kullanarak -1 bayt
  • Ölçek kaydırmalarında üçlü yerine ifs kullanarak -1 bayt
  • @Kevin Cruijssen sayesinde -7 bayt

Eski versiyon :

Dart , 210 bayt

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

Çevrimiçi deneyin!

Ungolfed:

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

Tüm adım 2, çeyrek 1'dir. Daha yüksek bir oktav atlamanız durumunda Mod 12. Tüm notaları yineler ve i no'lu ve i-1 no'lu not arasındaki farkı hesaplar. Sonucu birleştirir ve 221222 (2 tam, 1 yarım, 3 wholes) beklemelidir.

  • 0'a k atamadan -2 bayt
  • Liste değil, dize olarak j kullanarak -4 bayt
  • @Kevin Cruijssen sayesinde döngülerdeki gereksiz dağınıklığı gidererek -6 bayt

Dart'ı bilmiyorum, ama parçalar Java ile benzer. Bu nedenle: Değişen i=1hiç i=0değiştirerek byte azaltabilir for(;i<7;i++)için for(;++i<7;). Buna ek olarak, parantez {}koyarak, bu döngü etrafında çıkarılabilir j+=...döngüsünün üçüncü parçası içinde: for(;++i<7;j+='${(y[0]-y[1])%12}'). Ve son bir şey değişiyor return j=='221222';için return'221222'==j;boşluk kurtulmak için. Bu değişikliklerden sonra -6 ( 210 bayt ) .
Kevin Cruijssen

Teşekkürler, döngüler için bu hileleri bilmiyordum
Elcan

Np. Yeni 196-byte sürümünde golf bunu da yapabilirsiniz 189 bayt değiştirerek if(k>9)k--;if(k>3)k--;etmek k-=k>3?k>9?2:1:0;ve k+=m.length<2?0:m[1]=='#'?1:m[1]=='b'?-1:0;return k;karşı return m.length<2?k:m[1]=='#'?k+1:m[1]=='b'?k-1:k;. :)
Kevin Cruijssen

Kahretsin, hala göründüğü öğrenecek çok şeyim var, teşekkürler!
Elcan

2.5 yıldır golf oynuyorum ve hatta her zaman golf oynamak için ipuçları alıyorum. :) Başlangıçta bir şeyleri kaçırmak oldukça kolaydır ve zamanla golfün farklı yollarını düşünürsünüz. :) Henüz yapmadıysanız , <tüm dillerde> golf oynamak için ipuçları okumak ilginç olabilir. Ve Java'da golf için ipuçları için bazı ipuçları Dart'da da uygulanabilir, çünkü cevaplarınızda yaptığım golfler Java bilgime dayanıyordu, çünkü Dart'ı ilk kez görüyorum. ;)
Kevin Cruijssen

2

C (gcc) , -DA=a[i]+ 183 = 191 bayt

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

Çevrimiçi deneyin!

Perl cevabına göre.

Girişi geniş bir dize olarak alır.

Ungolfed:

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 Dili (Mathematica) + Müzik` paketi], 114 bayt

Ben müziği seviyorum ve bu ilginç buldum, ama benim boyun eğme biraz tardy bu kod golf fırsatı pike aşağı geldiğinde gerçek golf oynamaya oldu.

Bazı gerçek müzik bilgisini kullanarak bunu tamamen farklı bir şekilde deneyeceğim diye düşündüm. Mathematica'nın müzik paketinin adlandırılmış notların temel frekansını bildiği ortaya çıkıyor. İlk olarak girdi dizesini adlandırılmış not dizisine dönüştürüyorum. Sonra, birbirini izleyen her notun oranlarını alıyorum ve 2'den küçük olanları (oktav kaymasını hesaba katmak için) iki katına çıkarıyorum. Sonra bu oranları, yarım notalar arasında kabaca% 6 ve tam notalar arasında% 12 frekans farkına sahip İyon ölçeğinin oranlarıyla karşılaştırıyorum.

Burada harcanan baytların yarısından fazlası, girdiyi adlandırılmış sembollere dönüştürmektir.

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

Çevrimiçi deneyin!


2

Piton 3 , 175 136 134 114 112 bayt

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]

Çevrimiçi deneyin!


Tek katmanlı bir Python 3 uygulaması.

Bölme ve modulo kullanarak tonları hesaplama fikri için @Arnauld'a teşekkürler.
-39 bayt için @Jo King'e teşekkürler.



1

[Python] 269 bayt

Geliştirmeler 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])

Dene!

Test sürücüsü ile Ungolfed:

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

Evet, beyaz alanı görüyorum - hala çok fazla PEP-8 ile aşılanmış, korkuyorum. Görünüşe göre bir şey kaçırdım; burada bir yürütme bağlantısı gerekli mi?
Erik

1
Rağmen, bağlantı istiyorsanız, bazı hızlı golf ile 202 bayt . Farklı bir giriş formatına geçerek kesinlikle biraz daha golf oynayabilirsiniz
Jo King

Ah ... Python'a son ifadeyi işlem değeri olarak döndürmeye çok alışkınım. İşaretçiler ve ipuçları için teşekkürler.
Erik

Dizelerin listesini alan bir işleve geçerseniz 156 bayt alabilirsiniz . Ayrıca, TIO'nun bağlantı bölümünde kullanabileceğiniz bir otomatik formatlayıcı var
Jo King

@ JoKing, bu yanıtı düzenleyebilir veya kendi yanıtınızı gönderebilirsiniz; bir link ile yorum yapmak gelişmeleri bir seviye ayırır.
Erik

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.