Ünsüz veya uyumsuzluk?


36

İki nota verildiğinde, bu iki notanın oluşturduğu aralığın sessiz veya uyumsuz olup olmadığını belirleyen bir program yazmanız gerekir.

Giriş

Batı müziğinde, sadece 12 "farklı" ton var. En düşükten en yükseğe doğru sıralanır İsimleri, bunlar: C, C#, D, D#, E, F, F#, G, G#, A, A#, B. Dizi döngüseldir, yani sonsuzdan Csonra birbiriyle devam eder B.

İki ton arasındaki mesafeye aralık adı verilir . Yukarıdaki seriye bitişik olan herhangi iki nota arasındaki aralığa (örneğin C — C#veya E — F) yarım ton denir . Daha uzak notalar arasındaki aralık, birinciden diğerine geçmek için gereken yarı ton adımlarının sayısı olarak tanımlanmaktadır (muhtemelen sekansın etrafına sarılırken). Bazı örnekler: D to E= 2 yarı ton, C to G= 7 yarı ton, B to D#= 4 yarı ton (bu sekans etrafına sarılır). 1

Şimdi, bu aralıklar iki kategoriye ayrılır: ünsüz (iki notayı aynı anda çalarsanız hoşça çalar) ve uyumsuz (çok fazla değil).

Ünsüz aralıklarını şu şekilde tanımlayalım: 0, 3, 4, 5, 7, 8 ve 9 yarı tonlar.

Geri kalanları uyuşmuyor, yani: 1, 2, 6, 10 ve 11 yarı tonlar.

Meydan okuma

Aşağıdakileri yapmak için bir "program" (kelimenin genel olarak geniş anlamında: bir işlev mükemmel bir şekilde tamam) yazın:

  • Giriş olarak iki not adı (yukarıdaki diziden dizeler) alın. Onları ne istersen alabilirsin (stdin'den, argüman olarak, istediğin şekilde ayırarak, onları bir karakter listesi olarak almaktan çekinmeyin (örneğin ["C","#"]). Ancak, notlara başka isimler atamazsın (özellikle sen 0 ile 11 arasında numaralandırılamaz ve rakamları kullanabilir).

  • Dışarıda müzik meraklıları için, notlar oktav olmadan belirtilecektir. Bu durumda, notların hangi sırada gelip hangilerinin daha düşük, hangilerinin daha yüksek olduğu da önemli değildir. Son olarak, yukarıdaki listede bulunmayan isimleri kullanmanıza gerek yoktur. E#Daire, çift değişiklik ve benzeri hiçbir başka enharmonik yok.

  • İki farklı değer seçin. Girişinizdeki iki notanın oluşturduğu aralık ünsüz, diğeri değilse, programınız bunlardan birini çıkarmalıdır. (Olabilir Trueve False, ama π ve e eğer istersen :))

  • Bu bir kod golfü. Her dilde bayt cinsinden en kısa program kazanır. İyi eğlenceler!

Örnekler ve Test Durumları

Note 1    Note 2    Output    Interval [semitones]
  C          D     Dissonant   2
  A#         A#    Consonant   0
  G          D     Consonant   7 (wraparound)
  D#         A     Dissonant   6
  F          E     Dissonant   11
  A          C     Consonant   3

Bunlardan hiçbirini eklemiyorum, çünkü bu konuda hain bir durum olmadığı için.

Bu benim için ilk zorluk, bu yüzden yapıcı eleştiriler sıcak bir şekilde kabul edilir: --). Teori açıklama özensiz bulursanız, sorular sormaya çekinmeyin. Son olarak, lütfen bunun bunun ya da bunun bir kopyası olduğunu söyleme . Olmadığından emin oldum. (İkincisi oldukça benzer fakat daha karmaşık. Biraz daha basit bir meydan okuma hazırlamanın insanların katılmasını kolaylaştıracağını düşündüm.)


1 : Bu açıklamayı mümkün olduğunca basitleştirmeye çalıştım. Aralıklar hakkında çok daha fazla teori var. Lütfen beni dışarıda bıraktığım için üzülme.

Yanıtlar:


12

Jöle , 21 bayt

İki dizenin bir listesi olarak girdi alır. 0Hoşnutsuz veya 1ünsüz için döndürür .

OḢ6×%21_Lµ€IA“¬ɠṘ’æ»Ḃ

Çevrimiçi deneyin!

OḢ6×%21_Lµ€IA“¬ɠṘ’æ»Ḃ   - main link
         µ€             - for each note             e.g. ["A#", "C"]
O                       -   convert to ASCII codes  -->  [[65, 35], 67]
 Ḣ                      -   keep the first element  -->  [65, 67]
  6×                    -   multiply by 6           -->  [390, 402]
    %21                 -   modulo 21               -->  [12, 3]
       _L               -   subtract the length     -->  [12, 3] - [2, 1] = [10, 2]
           IA           - absolute difference       -->  8
             “¬ɠṘ’      - the integer 540205
                  æ»    - right-shift               -->  540205 >> 8 = 2110
                    Ḃ   - isolate the LSB           -->  2110 & 1 = 0

Yapma-of

Öncelikle aradığımız F fonksiyonunun değişmeli olduğunu not etmeliyiz : herhangi bir not çifti için (A, B) , F (A, B) = F (B, A) 'ya sahibiz .

Olası çok fazla giriş olmadığından ve ilgilenilmesi gereken sadece 2 olası çıktı olmadığından, oldukça basit bir karma işlevi H bulmak mümkün olmalıdır , öyle ki | H (A) - H (B) | sınırlı bir değer aralığı üretir ve beklenen çıktıya göre olası tüm not çiftleri (A, B) için çarpışmadan muaftır.

H (mul, mod) fonksiyon kümesini test edeceğiz :

H(mul, mod)(s) = ((ORD(s[0]) * mul) MOD mod) - LEN(s)

ORD(s[0])Notun ilk karakterinin ASCII kodu nerede ve notun LEN(s)uzunluğu ( eğer 2 ise a '#'ve 1 ise).

Aşağıda, birkaç geçerli çift (mul, mod) ve sonuçta elde edilen bit maskelerini bulmak için kullanılan JS kodunun yorumlanmış bir sürümüdür . Pek çok olası çözüm var, ancak * 6 % 21bu yöntemde en kısa olanı.


3
Bu şeylerle nasıl başa çıkabildin? .. Bu tür 'algoritmaları' elle mi yoksa kaba kuvvetle mi alıyorsun? Ve ne olursa olsun ikinci sorunun cevabı: nasıl ..:?! S " literal tamsayı 540205; sağ ile kaydırılır (ASCII kodu; çarpın 6 ile; modülo 21; ilk tutmak; çıkarma uzunluğu ...); bitdüzeyi-VE 1 ". Cevaplarınız beni her zaman etkileyici devam ..
Kevin Cruijssen

@KevinCruijssen Bu değerleri bulmak için kullanılan orijinal JS kodunu ekledim.
Arnauld

Eklenen açıklama için teşekkürler. Hala ilk kadar etkilendim ama nasıl geldiğine dair net bir açıklama yaptın. Çok kötü, sadece bir kez oy kullanabilirim.
Kevin Cruijssen 19:17

9

APL (Dyalog) , 62 39 bayt

Kullanır ⎕IO←0; 0 ünsüzdür, 1 eşittir. Temel argüman listelerinin sol argüman ve keskin uçların listesini argüman olarak alır.

{⎕A[|-/('C D EF G A '⍳⍺)+⍵=⍕#]∊'BCGKL'}

Çevrimiçi deneyin!

{} Anonim işlev , sol argümandır ve doğru argümandır.

⎕A[... ]∊'BCGKL' olan bir Aşağıdakilerden dize bir üyesi tarafından endeksli lphabet?

  ⍕# kök ad alanını biçimlendir (keskin karakteri verir)

  ⍵= Doğru argüman karakterleri (keskin nişancılar) buna eşit mi?

  ()+ Aşağıdakini ekleyin:

   'C D EF G A '⍳⍺ karakter dizisindeki sol argüman indeksleri

  -/ bunlar arasındaki fark

  | mutlak değer


APL'ye aşina olmayanlarımız için bir açıklama ekler misiniz?
Draconis

@Draconis Açıklama eklendi.
Adem

9

MATL , 30 27 26 bayt

,j'DJEFPGIALBC'&mQs]ZP7Mdm

İki notayı farklı satırlara girer. Çıkışlar 0ünsüz için, 1ahenksiz için.

Çevrimiçi deneyin! Veya tüm test durumlarını doğrulayın .

açıklama

11 karakterli dize

DJEFPGIALBC

aşağıdaki gibi hem notları hem de uyumsuz aralıkları kodlar.

Program önce giriş karakterinin 1-temelli indekslerini yukarıdaki dizgede bulur . Keskin olmayan bir giriş Dverecek 1, Everecek 3, verecek ... Cverecek 11. Bu sayılar ayrıca 1 × 1 sayısal diziler olarak da kabul edilebilir. Bunun gibi keskin bir giriş C#1 × 2 dizisini verecektir, [11 0]bu C, pozisyonda bulunduğu 11ve bulunamadığı anlamına gelir #.

Harflerin JPILgirişte asla bulunmayacağına dikkat edin . Şimdilik sadece örneğin not böylece, tutucu olarak kullanılan Ebir iki semitones yukarıda D. Fakat aynı zamanda uyumsuz aralıkları tanımlamakta da faydalı olacaktır.

1 × 1 veya 1 × 2 dizisinin ilk girişindeki sayılar, keskin semboller sayılmadan (henüz) yarı tonlardaki not aralığına karşılık gelir. Bu sayılarla tanımlanan ölçeğin başlamadığını gözlemleyin C; ama bu önemli değil çünkü sadece aralıklar istiyoruz, yani notlar arasındaki farkları . Elde edilen sayıları çıkarmak, aralığı ya da 12 eksi aralığı verir. Ama önce keskin sembolü düşünmemiz gerekiyor.

Keskin notaları düşünmek için, 1daha önce elde edilen 1 × 1 veya 1 × 2 dizisinin her girişine bir golf yolu (MATL'de) eklemek ve daha sonra diziyi (2 bayt) toplamaktır. Böylece keskin olmayan notlar artar 1ve keskin notlar artar 2. Bu, keskin notaları gerektiğinde keskin olmayan notalardan 1 yarı ton daha yüksek yapar. Ayrıca tüm notlara ekstra bir yarı ton ekliyoruz, ancak bu aralarındaki aralıkları değiştirmiyor. Yani şimdi dikkat Dzift numarasını verecek 2, D#verecek 3, ..., Cverecek 12, C#verecek 13.

Dissonant aralıkları vardır 1, 2, 6, 10, veya 11. Bunların bir modulo-12 simetrisi vardır : İki nota arasındaki bir aralık, sadece notaları ters sırada olan modulo 12'nin uyumsuz olması durumunda uyumsuzdur.

Dizenin ardışık farklarını hesaplarsak 'DJEFPGIALBC', sayısal vektör elde ederiz.

6 -5 1 10 -9 2 -8 11 -10 1

ne faydalı ne de zararlı olacak bazı olumsuz değerlere ek olarak, kesinlikle uyumsuz aralıklar içerir. Ek harflerin seçim olduğunu gözlemleyin JPILdizede 'DJEFPGIALBC'ki (ardışık farkların üzerinden) tanımlar uyumsuz aralıklarla.

İki giriş notunun uyumsuz olup olmadığını görmek için adım numaralarının mutlak farkını alırız . Örneğin, Cve D#numaralar verecek 12ve 3sırasıyla ve mutlak farktır 9. Gerçek fark olacaktır -9ve gerçek aralık 3( -9modulo 12 olarak elde edilmiştir ). Ancak yukarıda belirtilen simetri sayesinde 9yerine düşünebiliriz 3. Yana 9ardışık farklılıkların vektörü bulunmaz, notlar ünsüz vardır.


2
Aynı dizedeki hem notları hem de uyumsuz aralıkları nasıl kodladığınızı seviyorum.
celtschk

8

JavaScript (ES6), 68 64 bayt

Notları köretme sözdiziminde iki karakter olarak alır (a)(b). 0Hoşnutsuz veya 1ünsüz için döndürür .

a=>b=>488055>>(g=s=>'C D EF G A'.search(s[0])-!s[1])(a)-g(b)+9&1

Test durumları

Biçimlendi ve yorumlandı

a => b =>                       // given the two notes 'a' and 'b'
  488055 >>                     // 19-bit lookup bitmask: 1110111001001110111
    (g = s =>                   // we use g() to convert a note 's' into a semitone index
      'C D EF G A'.search(s[0]) // position of the note: -1 for 'B' (not found) to 9 for 'A'
      - !s[1]                   // subtract 1 semitone if the '#' is not there
    )(a)                        // compute the result for 'a'  --> [ -2 ...  9]
    - g(b)                      // subtract the result for 'b' --> [-11 ... 11]
    + 9                         // add 9                       --> [ -2 ... 20]
  & 1                           // test the bitmask at this position (0 if negative or > 18)

7

Jöle , 26 bayt

i@€ØAo.SḤ’d5ḅ4µ€ạ/“¢£©½¿‘ċ

İki notanın bir listesini (tek bir karakter listesi olarak) alan ve 0ünsüz ve 1uyuşukluk için dönen bir monadik bağlantı .

Çevrimiçi deneyin! veya test takımındaki tüm girişleri görün.

Nasıl?

i@€ØAo.SḤ’d5ḅ4µ€ạ/“¢£©½¿‘ċ - Link: list of lists of characters, notes
              µ€           - for €ach note in notes: (call the resulting list x)
   ØA                      -   yield the uppercase alphabet
i@€                        -   first index of c in ^ for €ach character, c
                           -     ...note '#' is not there so yields 0 (A->1, B->2,...)
      .                    -   literal one half
     o                     -   or (vectorised)  - e.g. "C#" -> [3, 0] -> [3, 0.5]
       S                   -   sum
        Ḥ                  -   double - that is ...  C C#  D D#  E  F F#  G G#  A A#  B
                                                 ->  6  7  8  9 10 12 13 14 15  2  3  4
         ’                 -   decrement         ->  5  6  7  8  9 11 12 13 14  1  2  3
           5               -   literal five
          d                -   divmod                (e.g. 9 -> [1,4] or 11 -> [2,1])
             4             -   literal four
            ḅ              -   convert from base     (e.g. [1,4] -> 8 or [2,1] -> 9)
                                                 ->  4  5  6  7  8  9 10 11 12  1  2  3
                 /         - reduce x with:
                ạ          -   absolute difference   (e.g. ["G#", "A"] -> [12, 1] -> 11)
                  “¢£©½¿‘  - code-page indices = [1, 2, 6, 10, 11]
                         ċ - count occurrences (1 if in the list, 0 if not)

5

Jöle , 31 bayt

O_65ị“¢[ḋṃ’b⁴¤+L$€Ḣ€ạ/e“cṾ’b12¤

Çevrimiçi deneyin!

32 bayt çok uzun

açıklama

O_65ị“¢[ḋṃ’b⁴¤+L$€Ḣ€ạ/e“cṾ’b12¤  Main link
O                                Cast each character to an int using Python `ord`
 _65                             Subtract 65 (A is 0, G is 7)
     “¢[ḋṃ’b⁴¤                   [2, 3, 5, 7, 9, 10, 0]
     “¢[ḋṃ’                      37058720
           b                     Digits in base
            ⁴                    16
    ị                            Index into this list; this creates the gaps for sharps
                 €               For each sublist
              +L$                Add the length to each element (Sharpens sharp notes)
              +                  Add
               L                 Length
                   €             For each sublist
                  Ḣ              Take the first element
                    ạ/           Absolute difference between the two (unoctaved) pitches # It's convenient that every interval's inverse (?) has the same consonance/dissonance
                      e          Is the semitone difference in
                       “cṾ’b12¤  [1, 2, 6, 10, 11]?
                       “cṾ’      25178
                           b     base
                            12   12

Hey, bu harika bir cevap! Birinin simetriyi kullanıp kullanmadığını merak ediyordum ve sen yaptın. Ve not adlarını sayılarla eşleştirme yönteminizi de seviyorum! +1.
Ramillies

Yarı ton farkı simetrik olabilir, ancak yine de farklı sonuçlar elde edersiniz - örneğin "G#", "A"(uyumsuz) bir farkın 11olmadığı bir[1,2,6] sonuç verir .
Jonathan Allan

@ JonathanAllan oh uh, bu utanç verici; Mutlak farkın bunu düzelttiğini düşündüm ... lol düzeltecek
HyperNeutrino 18:17


4

Mathematica, 55 bayt

function                                                  arguments        bytes

FreeQ[1|2|6|10|11]@Abs[#-#2&@@Sound`PitchToNumber/@#]&    [{"C","F#"}]     55

Girişteki dahili Sound`PitchToNumberyerleşimi (iki dizenin listesi) eşleştirin, mutlak farkı alın, ardından uyuşmayan aralık numaraları için örüntü eşleştirin.


Sadece eğlence için (rekabet etmeyen)

İşte kısıtlama ihlal bazı kısa fonksiyonlardır “Eğer notlara başka isim atamak olmayabilir.” İlkel Music`paket notu sabitleri (gibi önceden tanımlanmış A4 = 440.) ve fonksiyon HertzToCents(golfed edilebilir). Dizeler yerine, not sabitlerini argüman olarak kullanacağız, ancak her fonksiyon için farklı bir formatta vereceğiz.

FreeQ[1|2|6|10|11]@Abs@@Round[.01HertzToCents@#]&         [{C3,Fsharp3}]   50+9=59
FreeQ[1|2|6|10|11]@Abs@Round[17Log[#2/#]]&                [C3,Fsharp3]     43+9=52
FreeQ[1|2|6|10|11]@Abs@Round[17Log@#]&                    [C3/Fsharp3]     39+9=48

Paket içeri aktarma <<Music`;9 bayt alır.

Bu işlev bir dizgiyi (like "F#") bir nota sabitine (like Fsharp3) dönüştürür:

Symbol[StringReplace[#,"#"->"sharp"]<>"3"]&                                44

Bir oktav daha büyük aralıklarını kabul etmek yerine Abs[…]sahip Mod[…,12].


Neden bazı aralıklar uyumsuz olarak kabul edilir? Bir aralık, iki frekansın oranıdır. Oranın “basit” bir pay ve paydası varsa, daha ünsüz olma eğilimindedir. İçinde 5-sınır ayarlama , oranlar daha az ancak asal sayıların tam sayı güçleri çarpanlarına veya oktav yanı sıra, a, eşit mizaç 5. Hiçbir aralığına eşit sadece aralığı ; 2'nin 12. kökünün güçlerini kullanarak yalnızca yakın yaklaşımlardır.

Hangi aralık sayılarının birbiriyle uyuşmadığını kodlamak yerine, aralığın rasyonel bir yaklaşımını bulabilir ve daha sonra pay ve paydasının “basit” olup olmadığına karar verebiliriz (yani payda 5'ten küçük ve oran 7'yi bölmez).

Bu tablo, bu işlemdeki adımların her birini gösterir.

Table[
  Module[{compoundInterval,simpleInterval,rationalApprox,denomLeq5,div7,consonant},
    compoundInterval = Power[2, i/12];
    simpleInterval   = 2^Mod[Log2[compoundInterval], 1];
    rationalApprox   = Rationalize[N@simpleInterval, 1/17];
    denomLeq5        = Denominator[rationalApprox]<=5;
    div7             = Denominator[rationalApprox]>1 && rationalApprox\[Divides]7;
    consonant        = FreeQ[1|2|6|10|11][Mod[i,12]];

    InputForm/@{
      i, simpleInterval, rationalApprox, 
      denomLeq5, div7, denomLeq5 && !div7,
      consonant
    }
  ], {i, 0, 12}
]

i   sInterval  ratio   denomLeq5  div7       den&&!div  | consonant?

0   1          1       True       False      True       | True
1   2^(1/12)   17/16   False      False      False      | False
2   2^(1/6)    9/8     False      False      False      | False
3   2^(1/4)    6/5     True       False      True       | True
4   2^(1/3)    5/4     True       False      True       | True
5   2^(5/12)   4/3     True       False      True       | True
6   Sqrt[2]    7/5     True       True       False      | False
7   2^(7/12)   3/2     True       False      True       | True
8   2^(2/3)    8/5     True       False      True       | True
9   2^(3/4)    5/3     True       False      True       | True
10  2^(5/6)    7/4     True       True       False      | False
11  2^(11/12)  11/6    False      False      False      | False
12  1          1       True       False      True       | True

Rasyonel yaklaşım 1/17aralığın içindedir , çünkü bu, 12 eşit temperlenmiş aralığın tamamını ayıran en büyük eşiktir. Rasyonel sayıları önce kalıpla Rational[a_,b_](ya da sadece a_~_~b_), sonra da tamsayıları sadece ile eşleştiriyoruz _.

Bu, rastgele bir frekans oranının (1'den büyük) ünsüz veya uyumsuz olup olmadığını belirleyen oldukça kısa bir fonksiyonla sonuçlanır.

Rationalize[#,1/17]/.{a_~_~b_:>b<=5&&!a∣7,_->True}&       [Fsharp3/C3]     51+9=60

1
Tanrım, Mathematica için bile bir yerleşiği vardır deme bu ...: D
Ramillies

3

Mathematica, 118 bayt

FreeQ[{1,2,6,10,11},Min@Mod[Differences[Min@Position["C|C#|D|D#|E|F|F#|G|G#|A|A#|B"~StringSplit~"|",#]&/@{#,#2}],12]]&


Giriş formu

[ "A #", "D"]

çıktılar

True->Consonant  
False->Dissonant   

teşekkürler @JonathanFrech -16 bayt


Sadece bir açıklama: Consonantve dizeleri çıkarmanız gerekmez Dissonant. Bunların yerine iki değer yazabilirsiniz (0/1, ... neyse). Bu bazı baytları kurtarabilir.
Ramillies

1
Eğer ihmal edemez If[...,0,1]ve tanımlar True->Consonant; False->Dissonant?
Jonathan Frech

1
StringCases["CC#DD#EFF#GG#AA#B",_~~"#"...]- 42 Bayt
celtschk 19:17

1
Ayrıca, 2 bayt {1,2,6,10,11}1|2|6|10|11
celtschk

1
@Skyler Aşağıdaki cevaba bakınız.
hftf

3

Kömür , 30 bayt

≔B#A#G#FE#D#C槔o∧⌈ς”⁻⌕ζ⮌θ⌕ζ⮌η

Çevrimiçi deneyin! Bağlantı, kodun ayrıntılı bir versiyonudur. Ünsüz için 1, uyuşmayan için 0 çıkışı. Açıklama:

≔B#A#G#FE#D#Cζ                  Store reversed note names in z
                        θ       First input
                       ⮌        Reversed
                     ⌕ζ         Find index in z
                            η   Second input
                           ⮌    Reversed
                         ⌕ζ     Find index in z
                     ⁻          Subtract
               ”o∧⌈ς”           Compressed string 100111011100
              §                 Circularly index
                                Implicitly print

Meraktan, glif ⌕ζ"dizin bulmak" için kullanılan bir anımsatıcı neden var mı?
Jonah

@Jonah ζ, öncekilere atanan değişkendir.
Neil

2

J, 68 bayt

[:e.&1 2 6 10 11[:(12| -~/)(<;._1',C,C#,D,D#,E,F,F#,G,G#,A,A#,B')i.]

açıklama

J'de basit, süper golf oynamayan bir uygulama:

  • Girdi, sırayla, kutulanmış not şeklinde (kesme kullanılarak üretilir) verilir.

  • Dizinlerini not aralığında bulun: (<;._1',C,C#,D,D#,E,F,F#,G,G#,A,A#,B')i.]

  • İlkini ikinciden çıkartın: -~/

  • 12'ye bölündüğünde kalanı alın: 12|

  • Hoş olmayan notlardan biri olup olmadığını kontrol edin: e.&1 2 6 10 11

Çevrimiçi deneyin!


2

/// , 90 88 bayt

/^/"\///^\/\///C^D/##"E/DD"F/E#"G/FD"A/GD"B/AD"#,#/,"B#^B/#"A#/#"A^G#^G^F#/#"F^E^D#^D/#/

Çevrimiçi deneyin! (aynı anda tüm test durumları)

  • Girdiyi koddan sonra koyun.
  • ,B#Her test durumunda not adlarını ayırın .
  • Çıktı ,ünsüz, ,#uyumsuz içindir.
  • İki değişiklik ( ##) veya E#bazı özel durumlarda destek. Aksi halde çıkış ,ünsüzler #,için, uyumsuzlar içindir (modulo 12 simetrisi sayesinde)
  • Aynı anda birden fazla test vakasını kaldırabilir (makul şekilde ayrılırsa)
  • Küçük harf karakterler tam olarak yazdırılır.

2

C (gcc) , 91 bayt

g(char*s){return (s[1]&1|2**s&15)*4/5;}f(char*x,char*y){return (1952220<<g(x)>>g(y))&2048;}

aramak: f("A#", "D")

Geri dönüş değeri:

  • Ünsüz: 2048
  • Uyuşmaz: 0

Bonus: İşlev büyük / küçük harfe duyarsızdır.

Çevrimiçi deneyin!


Her ikisinde de iki gereksiz alan yok return (mu?
Jonathan Frech

Deneyebilir g(char*s){s=(s[1]&1|2**s&15)*4/5;}f(char*x,char*y){x=1952220<<g(x)>>g(y)&2048;}ve güzel bir çözüm olabilir!
Keyu Gan

1

Python 2, 125 117 83 78 77 bayt

a,b=map("C C#D D#E F F#G G#A A#B".index,input())
print chr(abs(a-b))in""

Nerede ""sonunda aslında karakterler içeriyor"\x02\x04\x0c\x14\x16"

Çevrimiçi Deneyin!

(+3, listede 11 veya 22'yi unuttuğumu unuttum)

- Jonathan Frech'ten 8 bayt ve Python 2'ye geçiyor .

Jonathan Frech'in önerileriyle -34 bayt ve str'yerine list' dizini kullanıldı .

Satır içi -4 bayt ive Neil dizge önerisini tersine çeviriyor ( ()bir jeneratörün etrafında unuttuğum gibi sadece -2

-5 bayt çizgiden çıkarma ive giriş biçimini değiştirme

Jonathan Frech ile gelen map()ve yazılamayan -1 bayt .

Stdin'in bir satırındaki girişi alır:

'C','C#'

Trueuyumsuz, Falseünsüzdür.

Eski Açıklama:

i='C C#D D#E F F#G G#A A#B'.index
a,b=input()
print abs(i(a)-i(b))in[2,4,12,20]

Python str.indexeşleşen bir alt dizinin en düşük (pozitif) başlangıç ​​dizinini döndürür, "ABACABA".index("A") == 0ve "ABACABA".index("BA") == 1. Bu nedenle, not adlarını bir dizgede eşit aralıklarla yerleştirebiliriz (örneğin) Adaha önce geldiği sürece A#, paylaşılan Abir sorun olmaz.

i='C C#D D#E F F#G G#A A#B'.index

işimdi dizini 'C C#D D#E F F#G G#A A#B'argümanında döndüren bir işlevdir (not adı), 2 * (notun bulunduğu yarı tonların sayısı C)

a,b=input()

Python 2'ler input()(çoğunlukla) eval(input())Python3'e eşdeğerdir , bu nedenle biçimin geçerli bir girişi 'C#','F'(örneğin) a='C#'veb='F'

print abs(i(a)-i(b))in[2,4,12,20]

Dizideki ilk not ile ikinci not arasındaki fark 2, 4, 12 veya 20 değilse (not adları 2 karakterde gösterildiğinden), aralık uyumsuzdur, True yazılır, aksi halde Yanlış yazdır.


Giriş biçimi katı olmadığından, eval(input())(15 bayt) yerine (13 bayt) kullanabilirsiniz input().split().
Jonathan Frech




1
Bir emtpy dizesi yerine Unicode karakterleri ( ) kullanabilirsiniz .
Jonathan Frech

1

C (gcc) , 115117 120 bayt

g(char*a){a=*a-65+!!a[1]*(7-*a/70-*a/67);}f(x,y)char*x,*y;{x="(pP$HL<lt<X"[g(x)]*32+"=ZukW-^h1F6"[g(x)]>>g(y)&1;}

Çevrimiçi deneyin!

Ünsüz ve saygısızlık için 1/0 döndür. Saf C ile string manipülasyon yapmak her zaman ilginçtir.f("A#", "C")


0

PowerShell , 107 bayt

param($a,$b)[math]::abs(($x=-split'C C# D D# E F F# G G# A A# B').indexof($b)-$x.indexof($a))-in1,2,6,10,11

Çevrimiçi deneyin!

TrueUyumsuz ve Falseünsüz çıktılar .

Girdiyi $ave $biki notayı dizge olarak alır. -splitÖlçek üzerinde, bir dizi not oluşturmak üzere boşlukta bölen bir işlemi gerçekleştirir , içine depolar $x. .indexof $bBu dizide bulunanı bulur, dizini çıkarır $ave sonra absbunun olute değerini alır . Bu sayının -inuyuşmayan aralıklar olup olmadığını kontrol eder .



0

SQL, 582 bayt

SQL Fiddle

Hala üzerinde golf oynamıştım, fakat tamamen bitirmeden önce buraya almak istedim.

Girdi harf biçimindeyse, bu harfleri değerleri olan bir tabloya koymak tamam mı?

CREATE TABLE N(N char(2),v int)
Insert Into N values('A',1),('A#',2),('B',3),('C',4),('C#',5),('D',6),('D#',7),('E',8),('F',9),('F#',10),('G',11),('G#',12);
CREATE TABLE D(D char(9),v int) 
Insert Into D values('C',0),('D',1),('D',2),('C',3),('C',4),('C',5),('D',6);
CREATE FUNCTION I(@A char(2),@B char(2))
RETURNS char(9) as
BEGIN
DECLARE @E int=(SELECT v from N where n=@A),@F int=(SELECT v from N where n=@B)
DECLARE @C char(9) = (SELECT case D when 'D' then 'Dissonant' when 'C' then 'Consonant' END from D where v in(abs(@e-@f),12-abs(@e-@f)))
RETURN isnull(@C,'NotANote')
END

0

Perl 5 , 106 bayt

("C,C#,D,D#,E,F,F#,G,G#,A,A#,B,"x2)=~/$F[0],(.*?)$F[1],/;$r=(1+($1=~y/,//))%12;say(grep/$r/,(0,3..5,7..9))

Çevrimiçi deneyin!

Hoşnutsuz için false, ünsüz için true döndürür.

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.