Konsonanz oder Dissonanz?

36

Bei zwei gegebenen Notennamen müssen Sie ein Programm schreiben, das bestimmt, ob das von diesen beiden Noten gebildete Intervall konsonant oder dissonant ist.

Einführung

In der westlichen Musik gibt es nur 12 "verschiedene" Töne. Ihre Namen, sortiert vom niedrigsten zum höchsten, sind diese: C, C#, D, D#, E, F, F#, G, G#, A, A#, B. Die Abfolge ist zyklisch, dh sie setzt sich unendlich Cnach der anderen fort B.

Der Abstand zwischen zwei Tönen wird als Intervall bezeichnet . Das Intervall zwischen zwei Noten, die in der obigen Reihe benachbart sind (z. B. C — C#oder E — F), wird als Halbton bezeichnet . Das Intervall zwischen weiter entfernten Noten ist als die Anzahl der Halbtonschritte definiert, die erforderlich sind, um von der ersten zur zweiten zu gelangen (wobei möglicherweise die Sequenz umbrochen wird). Einige Beispiele: D to E= 2 Halbtöne, C to G= 7 Halbtöne, B to D#= 4 Halbtöne (dies umgibt die Sequenz). 1

Nun werden diese Intervalle in zwei Kategorien unterteilt: Konsonant (angenehm klingend, wenn Sie die beiden Noten gleichzeitig spielen) und Dissonant (nicht so sehr).

Definieren wir die Konsonantenintervalle als: 0, 3, 4, 5, 7, 8 und 9 Halbtöne.

Der Rest ist dissonant, nämlich: 1, 2, 6, 10 und 11 Halbtöne.

Die Herausforderung

Schreiben Sie ein "Programm" (im weitesten Sinne des Wortes: eine Funktion ist vollkommen in Ordnung), um Folgendes zu tun:

  • Nehmen Sie zwei Notennamen (Zeichenfolgen aus der obigen Sequenz) als Eingabe. Sie können sie verwenden, wie Sie möchten (von stdin als Argumente, getrennt durch beliebige Zeichen ["C","#"]). Sie können sie auch als Liste von Zeichen verwenden (z . B. ). Sie dürfen den Noten jedoch keine anderen Namen zuweisen (insbesondere Sie nicht) darf sie nicht von 0 bis 11 nummerieren und die Zahlen verwenden).

  • Für Sie Musikfreaks werden die Noten ohne Oktave angegeben. In diesem Fall spielt es auch keine Rolle, in welcher Reihenfolge die Noten kommen und welche niedriger und welche höher sind. Schließlich müssen Sie keine Namen behandeln, die nicht in der obigen Liste aufgeführt sind. Keine anderen Enharmonika wie E#, keine Wohnungen, Doppelveränderungen und so weiter.

  • Wählen Sie zwei verschiedene Werte. Ihr Programm muss immer dann einen davon ausgeben, wenn das Intervall, das durch die beiden Noten in der Eingabe gebildet wird, konsonant ist, und den anderen, wenn dies nicht der Fall ist. (Könnte sein Trueund False, aber auch π und e wenn du willst :))

  • Dies ist ein Code-Golf. Das kürzeste Programm in Bytes in jeder Sprache gewinnt. Habe Spaß!

Beispiele und Testfälle

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

Ich füge keine weiteren hinzu, da diesbezüglich keine besonders tückischen Fälle vorliegen.

Dies ist meine erste Herausforderung, daher ist jede konstruktive Kritik herzlich willkommen: -). Wenn Sie die Erklärung der Theorie schlampig finden, können Sie gerne Fragen stellen. Zum Schluss sagen Sie mir bitte nicht, dass dies ein Betrug von diesem oder jenem ist . Ich habe dafür gesorgt, dass es nicht so ist. (Letzteres ist ziemlich ähnlich, aber komplexer. Ich dachte, dass das Aufstellen einer etwas einfacheren Herausforderung es den Leuten leichter macht, beizutreten.)


1 : Ich habe versucht, diese Erklärung so weit wie möglich zu vereinfachen. Es gibt viel mehr Theorie über Intervalle. Bitte verprügel mich nicht, weil ich es ausgelassen habe.

Ramillies
quelle

Antworten:

12

Jelly , 21 Bytes

Übernimmt die Eingabe als Liste von zwei Zeichenfolgen. Rückgabe 0für dissonant oder 1für konsonant.

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

Probieren Sie es online!

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

Making-of

Wir sollten zuerst beachten, dass die gesuchte Funktion F kommutativ ist: Für jedes Notenpaar (A, B) gilt F (A, B) = F (B, A) .

Da es nicht zu viele mögliche Eingaben und nur 2 mögliche Ausgaben gibt, muss es möglich sein, eine ziemlich einfache Hash-Funktion H zu finden , so dass | H (A) - H (B) | erzeugt einen begrenzten Wertebereich und ist kollisionsfrei für alle möglichen Notenpaare (A, B) in Bezug auf die erwartete Ausgabe.

Wir testen die Menge der Funktionen H (mul, mod) , die wie folgt definiert sind:

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

Wo ORD(s[0])ist der ASCII-Code des ersten Zeichens der Notiz und LEN(s)ist die Länge der Notiz ( 2, wenn es eine gibt '#'und 1, wenn nicht).

Nachfolgend finden Sie eine kommentierte Version des JS-Codes, der verwendet wurde, um ein paar gültige Paare (mul, mod) und die resultierenden Bitmasken zu finden. Es gibt viele mögliche Lösungen, aber * 6 % 21die kürzeste bei dieser Methode.

Arnauld
quelle
3
Wie kommst du überhaupt auf diese Dinge? .. Bekommst du diese Art von 'Algorithmen' von Hand oder mit Brute-Force? Und unabhängig von der Antwort auf die zweite Frage: Wie?! ..: S " Literal Integer 540205; Rechtsverschoben mit (ASCII-Code; Multiplizieren mit 6; Modulo 21; Behalten Sie zuerst; Subtrahieren der Länge ...); Bitweises UND 1 ". Ihre Antworten beeindrucken mich immer wieder ..
Kevin Cruijssen
@ KevinCruijssen Ich habe den ursprünglichen JS-Code hinzugefügt, mit dem diese Werte gefunden wurden.
Arnauld
Danke für die zusätzliche Erklärung. Ich bin immer noch so beeindruckt wie zuvor, aber Sie haben deutlich erklärt, wie Sie darauf gekommen sind. Schade, dass ich nur einmal upvoten kann.
Kevin Cruijssen
9

APL (Dyalog) , 62 39 Bytes

Verwendet ⎕IO←0; 0 ist Konsonant, 1 ist Dissonant. Nimmt die Liste der Grundtonzeichen als linkes Argument und die Liste der Sharps als rechtes Argument.

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

Probieren Sie es online!

{} Anonyme Funktion, wobei das linke Argument und das rechte Argument ist

⎕A[… Ist ]∊'BCGKL' der A lphabet, der durch den folgenden Index gekennzeichnet ist, ein Mitglied der Zeichenfolge?

  ⍕# Formatieren Sie den Root-Namespace (ergibt das scharfe Zeichen)

  ⍵= Sind die richtigen Argument-Zeichen (die Scharfen) gleich?

  ()+ Fügen Sie Folgendes hinzu:

   'C D EF G A '⍳⍺ Indizes des linken Arguments in der Zeichenfolge

  -/ Unterschied zwischen diesen

  | Absolutwert

Uriel
quelle
Würde es Ihnen etwas ausmachen, eine Erklärung für diejenigen von uns hinzuzufügen, die mit APL nicht vertraut sind?
Draconis
@Draconis Erklärung hinzugefügt.
Adám,
9

MATL , 30 27 26 Bytes

,j'DJEFPGIALBC'&mQs]ZP7Mdm

Gibt die beiden Noten in verschiedenen Zeilen ein. Ausgänge 0für Konsonanten, 1für Dissonanten.

Probieren Sie es online! Oder überprüfen Sie alle Testfälle .

Erläuterung

Die 11-stellige Zeichenfolge

DJEFPGIALBC

codiert sowohl die Noten als auch die dissonanten Intervalle wie folgt.

Das Programm findet zuerst die auf 1 basierenden Indizes der eingegebenen Zeichen in der obigen Zeichenfolge. Eine nicht scharfe Eingabe wie Dwird geben 1, Ewird geben 3, ... Cwird geben 11. Diese Zahlen können auch als 1 × 1-Zahlenfelder betrachtet werden. Eine scharfe Eingabe wie C#ergibt das 1 × 2-Array [11 0], was bedeutet, dass Ces an der Position gefunden 11und #nicht gefunden wurde.

Beachten Sie, dass JPILdie Eingabe niemals Buchstaben enthält . Denn jetzt sind sie nur als Platzhalter verwendet, so dass beispielsweise Note Eist zwei Halbtonschritte oben D. Sie sind aber auch nützlich, um dissonante Intervalle zu definieren.

Die Zahlen im ersten Eintrag des 1 × 1- oder 1 × 2-Arrays entsprechen der Tonhöhe in Halbtönen ohne (noch) scharfe Symbole. Beachten Sie, dass die Skala, die durch diese Zahlen definiert wird, nicht bei beginnt C. aber das macht nichts, weil wir nur Intervalle wollen, also Unterschiede zwischen Noten. Das Subtrahieren der erhaltenen Zahlen würde entweder das Intervall oder 12 minus das Intervall ergeben. Aber zuerst müssen wir das scharfe Symbol betrachten.

Um scharfe Noten zu berücksichtigen, müssen Sie (in MATL) 1zu jedem Eintrag des zuvor erhaltenen 1 × 1- oder 1 × 2-Arrays eine Golf-Methode hinzufügen und dann das Array (2 Bytes) summieren. Somit werden nicht scharfe Noten um 1und scharfe Noten um erhöht 2. Dies macht scharfe Noten je nach Bedarf 1 Halbton höher als nicht scharfe Noten. Wir fügen auch allen Noten einen zusätzlichen Halbton hinzu, aber das ändert nichts an den Intervallen zwischen ihnen. Also jetzt Note Dwird Pitch-Nummer geben 2, D#wird geben 3, ... Cwird geben 12, C#wird geben 13.

Dissonante Intervalle sind 1, 2, 6, 10, oder 11. Diese haben eine Modulo-12-Symmetrie : Ein Intervall zwischen zwei Noten ist genau dann dissonant, wenn das Intervall mit den Noten in umgekehrter Reihenfolge, Modulo 12, dissonant ist.

Wenn wir die aufeinanderfolgenden Differenzen der Zeichenkette berechnen, erhalten 'DJEFPGIALBC'wir den numerischen Vektor

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

die genau die dissonanten Intervalle enthält, zusätzlich zu einigen negativen Werten, die weder nützlich noch schädlich sind. Beachten Sie, dass es die Wahl zusätzlicher Buchstaben JPILin der Zeichenfolge ist 'DJEFPGIALBC', die (über aufeinanderfolgende Unterschiede) die dissonanten Intervalle definiert.

Um zu sehen, ob die beiden Eingangsnoten dissonant sind, nehmen wir die absolute Differenz ihrer Tonhöhen. Zum Beispiel Cund D#werden Zahlen geben 12und 3jeweils und die absolute Differenz ist 9. Die tatsächliche Differenz wäre -9und das tatsächliche Intervall wäre 3(erhalten als -9Modulo 12). Aber dank der oben genannten Symmetrie können wir 9statt überlegen 3. Da 9im Vektor der aufeinanderfolgenden Differenzen nicht vorhanden ist, sind die Noten konsonant.

Luis Mendo
quelle
2
Mir gefällt, wie Sie sowohl die Noten als auch die dissonanten Intervalle in derselben Zeichenfolge codiert haben.
Celtschk
8

JavaScript (ES6), 68 64 Byte

Nimmt die Noten als zwei Zeichenfolgen in der Currysyntax auf (a)(b). Rückgabe 0für dissonant oder 1für konsonant.

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

Testfälle

Formatiert und kommentiert

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)
Arnauld
quelle
7

Gelee , 26 Bytes

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

Ein monadischer Link, der eine Liste der beiden Noten (als Liste von Zeichen) 0aufnimmt und 1für Konsonanten und Dissonanten zurückkehrt.

Probieren Sie es online! oder sehen Sie alle Eingaben in der Testsuite .

Wie?

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)
Jonathan Allan
quelle
5

Gelee , 31 Bytes

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

Probieren Sie es online!

Wheeeeee 32 Bytes zu lang

Erläuterung

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
HyperNeutrino
quelle
Hey, das ist eine großartige Antwort! Ich habe mich gefragt, ob jemand die Symmetrie nutzt, und du hast es getan. Und mir gefällt auch Ihre Methode, die Notennamen mit Zahlen abzugleichen! +1.
Ramillies
Der Halbtonunterschied mag symmetrisch sein, aber Sie erhalten immer noch Duff-Ergebnisse - zum Beispiel "G#", "A"(dissonant) ergibt einen Unterschied, der 11nicht in ist[1,2,6] .
Jonathan Allan
@ JonathanAllan Oh, na ja, das ist peinlich. Ich dachte, dass der absolute Unterschied das ... regelt. behebt lol
HyperNeutrino
1
@ JonathanAllan für ein paar zusätzliche Bytes (3 IIRC)
behoben
4

Mathematica, 55 Bytes

function                                                  arguments        bytes

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

Ordnen Sie die interne Funktion Sound`PitchToNumberder Eingabe zu (Liste mit zwei Zeichenfolgen), nehmen Sie die absolute Differenz und passen Sie die Muster für dissonante Intervallnummern an.


Nur zum Spaß (nicht konkurrierend)

Im Folgenden finden Sie einige kürzere Funktionen, die gegen die Einschränkung verstoßen, dass Sie den Noten keine anderen Namen zuweisen dürfen. Das rudimentäre Music`Paket verfügt über vordefinierte Noten-Konstanten (wie A4 = 440.) und die Funktion HertzToCents(die gespielt werden kann). Anstelle von Strings werden die Noten-Konstanten als Argumente verwendet, jedoch für jede Funktion in einem anderen Format angegeben.

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

Der Paketimport <<Music`;dauert 9 Bytes.

Diese Funktion konvertiert einen String (like "F#") in eine Noten-Konstante (like Fsharp3):

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

Ersetzen Sie Abs[…]durch , um Intervalle zu akzeptieren, die länger als eine Oktave sind Mod[…,12].


Warum werden einige Intervalle als dissonant angesehen? Ein Intervall ist ein Verhältnis von zwei Frequenzen. Wenn das Verhältnis einen „einfachen“ Zähler und Nenner hat, ist es tendenziell konsonanter. Bei der 5-Limit-Stimmung können die Verhältnisse in ganzzahlige Potenzen von nur Primzahlen kleiner oder gleich 5 eingeteilt werden. Kein Intervall bei gleichem Temperament ist außer der Oktave ein gerechtes Intervall . Sie sind nur enge Näherungen mit Potenzen der 12. Wurzel von 2.

Anstatt hart zu codieren, welche Intervallzahlen dissonant sind, können wir eine rationale Annäherung des Intervalls finden und dann bestimmen, ob sein Zähler und Nenner "einfach" sind (was bedeutet, dass der Nenner kleiner als 5 ist und das Verhältnis 7 nicht teilt).

Diese Tabelle zeigt die einzelnen Schritte in diesem Prozess.

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

Die rationale Näherung liegt innerhalb 1/17des Intervalls, da dies die größte Schwelle ist, die alle 12 gleich temperierten Intervalle unterscheidet. Wir ordnen rationale Zahlen zuerst dem Muster Rational[a_,b_](oder nur dem Muster a_~_~b_) zu und ordnen dann nur ganzen Zahlen zu _.

Dies führt zu der folgenden ziemlich kurzen Funktion, die bestimmt, ob ein beliebiges Frequenzverhältnis (größer als 1) konsonant oder dissonant ist.

Rationalize[#,1/17]/.{a_~_~b_:>b<=5&&!a∣7,_->True}&       [Fsharp3/C3]     51+9=60
hftf
quelle
1
Meine Güte, sag mir nicht, dass Mathematica auch dafür ein eingebautes System hat ...: D
Ramillies
3

Mathematica, 118 Bytes

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]]&


Eingabeformular

["ANZEIGE"]

Ausgänge

True->Consonant  
False->Dissonant   

danke @ JonathanFrech -16 Bytes

J42161217
quelle
Nur eine Bemerkung: Sie müssen keine Strings Consonantund ausgeben Dissonant. Sie können stattdessen zwei beliebige Werte ausgeben (0/1, ... was auch immer). Das könnte einige Bytes einsparen.
Ramillies
1
Kann man das nicht weglassen If[...,0,1]und definieren True->Consonant; False->Dissonant?
Jonathan Frech
1
StringCases["CC#DD#EFF#GG#AA#B",_~~"#"...]- 42 Bytes
Celtschk
1
Außerdem können durch Ersetzen {1,2,6,10,11}von1|2|6|10|11
celtschk
1
@Skyler Siehe die Antwort unten.
HFTF
3

Kohle , 30 Bytes

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

Probieren Sie es online! Link ist eine ausführliche Version des Codes. Ausgänge 1 für Konsonanten, 0 für Dissonanten. Erläuterung:

≔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
Neil
quelle
Gibt es aus Neugier einen mnemonischen Grund, warum die Glyphe ⌕ζfür "Index suchen" verwendet wird?
Jonah
@Jonah ζist die Variable, die zuvor zugewiesen wurde.
Neil
2

J, 68 Bytes

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

Erläuterung

Eine unkomplizierte, nicht sehr gelungene Implementierung in J:

  • Die Eingabe erfolgt in der angegebenen Reihenfolge in Form von Einzelnotizen in Kästchen (hergestellt mit Schnitt).

  • Finden Sie ihre Indizes im Bereich der Notizen: (<;._1',C,C#,D,D#,E,F,F#,G,G#,A,A#,B')i.]

  • Subtrahiere die erste von der zweiten: -~/

  • Nehmen Sie den Rest, wenn Sie durch 12 teilen: 12|

  • Überprüfen Sie, ob es sich um eine der dissonanten Noten handelt: e.&1 2 6 10 11

Probieren Sie es online!

Jona
quelle
2

/// , 90 88 Bytes

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

Probieren Sie es online! (alle Testfälle auf einmal)

  • Fügen Sie die Eingabe nach dem Code ein.
  • Trennen Sie die Notennamen ,B#in jedem Testfall mit.
  • Die Ausgabe ist ,für Konsonanten, ,#für Dissonanten.
  • Unterstützung für Doppeländerungen ( ##) oder E#in bestimmten Fällen. Ansonsten ist der Ausgang ,für Konsonanten, #,für Dissonanten (dank Modulo 12-Symmetrie)
  • Kann mehrere Testfälle gleichzeitig behandeln (wenn sinnvoll getrennt)
  • Kleinbuchstaben werden exakt gedruckt.
user202729
quelle
2

C (gcc) 91 Bytes

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

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

Rückgabewert:

  • Konsonant: 2048
  • Dissonant: 0

Bonus: Die Funktion unterscheidet nicht zwischen Groß- und Kleinschreibung.

Probieren Sie es online!

Celtschk
quelle
Gibt es nicht zwei unnötige Leerzeichen in beiden return (?
Jonathan Frech
Sie können versuchen, eine g(char*s){s=(s[1]&1|2**s&15)*4/5;}f(char*x,char*y){x=1952220<<g(x)>>g(y)&2048;}schöne Lösung!
Keyu Gan
1

Python 2, 125 117 83 78 77 Bytes

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

Wo die ""am Ende tatsächlich die Zeichen enthält"\x02\x04\x0c\x14\x16"

Probieren Sie es online!

(+3, weil ich 11 oder 22 in der Liste vergessen habe)

-8 Bytes von Jonathan Frech und Umstieg auf Python 2 .

-34 Bytes mit Vorschlägen von Jonathan Frech und Verwendung strdes Index anstelle von list.

-4 Bytes von Inlining iund Neils Umkehrung des String-Vorschlags (nur -2 wirklich, da ich ()einen Generator vergessen habe )

-5 Bytes nach dem Aufheben des Inlinings iund Ändern des Eingabeformats

-1 Bytes von Jonathan Frech mit map()und unprintables.

Übernimmt die Eingabe in einer Zeile von stdin im Format:

'C','C#'

Trueist dissonant, Falseist konsonant.

Alte Erklärung:

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.indexgibt den niedrigsten (positiven) Startindex einer übereinstimmenden Teilzeichenfolge zurück, also "ABACABA".index("A") == 0und "ABACABA".index("BA") == 1. Aus diesem Grund können wir die Notennamen in gleichmäßigen Abständen in einer Zeichenfolge platzieren. Solange (zum Beispiel) dies noch nicht Ageschehen ist A#, ist die gemeinsame ANutzung kein Problem.

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

iist jetzt eine Funktion, die den Index in 'C C#D D#E F F#G G#A A#B'ihrem Argument (ein Notenname) zurückgibt. Dies ist 2 * (die Anzahl der Halbtöne, von denen die Note abweicht C).

a,b=input()

Python 2 input()ist (meistens) äquivalent zu eval(input())Python3, also mit einer gültigen Eingabe des Formats 'C#','F'(zum Beispiel) a='C#'undb='F'

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

Wenn der Abstand zwischen der ersten Note und der zweiten Note in der Zeichenfolge nicht 2, 4, 12 oder 20 beträgt (da die Notennamen aus 2 Zeichen bestehen), ist das Intervall dissonant. Drucken Sie True, andernfalls ist es konsonant. print Falsch.

Pizzapants184
quelle
Da das Eingabeformat nicht streng ist, können Sie eval(input())(13 Byte) anstelle von input().split()(15 Byte) verwenden.
Jonathan Frech
101 Bytes
Jonathan Frech
98 Bytes
Jonathan Frech
79 Bytes
Jonathan Frech
1
Sie können anstelle einer leeren Zeichenfolge auch Unicode-Zeichen ( ) verwenden.
Jonathan Frech
1

C (gcc) , 115117 120 Bytes

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

Probieren Sie es online!

Geben Sie 1/0 für consonat und dissonat zurück. Es ist immer interessant, Zeichenfolgen mit reinem C zu manipulierenf("A#", "C")

Keyu Gan
quelle
0

PowerShell , 107 Byte

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

Probieren Sie es online!

Ausgänge Truefür dissonant und Falsefür konsonant.

Nimmt die Eingabe $aund $bdie beiden Noten als Zeichenfolgen. Führt eine -splitOperation auf der Skala aus, die in Leerzeichen aufgeteilt wird, um ein Array der Noten zu erstellen, und speichert diese in $x. Findet das .indexof $bin diesem Array, subtrahiert den Index von $aund nimmt dann den absOlutewert davon. Überprüft, ob diese Zahl -inden dissonanten Bereichen entspricht.

AdmBorkBork
quelle
0

Python 2 , 68 Bytes

lambda a,b,f='C C#D D#E F F#G G#A A#B'.find:3142>>(f(a)-f(b))/2%12&1

Probieren Sie es online!

Outputs: 1ist dissonant, 0ist konsonant.

Lynn
quelle
0

SQL, 582 Bytes

SQL-Geige

Ich habe noch ein bisschen Golf zu spielen, aber ich wollte es hier runterbringen, bevor ich es komplett kaputt mache.

Wenn die Eingabe in einem Buchstabenformat erfolgt, ist es in Ordnung, diese Buchstaben in einer Tabelle mit Werten abzulegen, oder?

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
phroureo
quelle
0

Perl 5 , 106 Bytes

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

Probieren Sie es online!

Gibt false für den Dissonanten zurück, true für den Konsonanten.

Xcali
quelle