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 C
nach 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
True
undFalse
, 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.
APL (Dyalog) ,
6239 BytesVerwendet
⎕IO←0
; 0 ist Konsonant, 1 ist Dissonant. Nimmt die Liste der Grundtonzeichen als linkes Argument und die Liste der Sharps als rechtes Argument.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|
Absolutwertquelle
MATL ,
302726 BytesGibt die beiden Noten in verschiedenen Zeilen ein. Ausgänge
0
für Konsonanten,1
für Dissonanten.Probieren Sie es online! Oder überprüfen Sie alle Testfälle .
Erläuterung
Die 11-stellige Zeichenfolge
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
D
wird geben1
,E
wird geben3
, ...C
wird geben11
. Diese Zahlen können auch als 1 × 1-Zahlenfelder betrachtet werden. Eine scharfe Eingabe wieC#
ergibt das 1 × 2-Array[11 0]
, was bedeutet, dassC
es an der Position gefunden11
und#
nicht gefunden wurde.Beachten Sie, dass
JPIL
die Eingabe niemals Buchstaben enthält . Denn jetzt sind sie nur als Platzhalter verwendet, so dass beispielsweise NoteE
ist zwei Halbtonschritte obenD
. 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)
1
zu 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 um1
und scharfe Noten um erhöht2
. 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 NoteD
wird Pitch-Nummer geben2
,D#
wird geben3
, ...C
wird geben12
,C#
wird geben13
.Dissonante Intervalle sind
1
,2
,6
,10
, oder11
. 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 Vektordie 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
JPIL
in 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
C
undD#
werden Zahlen geben12
und3
jeweils und die absolute Differenz ist9
. Die tatsächliche Differenz wäre-9
und das tatsächliche Intervall wäre3
(erhalten als-9
Modulo 12). Aber dank der oben genannten Symmetrie können wir9
statt überlegen3
. Da9
im Vektor der aufeinanderfolgenden Differenzen nicht vorhanden ist, sind die Noten konsonant.quelle
JavaScript (ES6),
6864 ByteNimmt die Noten als zwei Zeichenfolgen in der Currysyntax auf
(a)(b)
. Rückgabe0
für dissonant oder1
für konsonant.Testfälle
Code-Snippet anzeigen
Formatiert und kommentiert
quelle
Gelee , 26 Bytes
Ein monadischer Link, der eine Liste der beiden Noten (als Liste von Zeichen)
0
aufnimmt und1
für Konsonanten und Dissonanten zurückkehrt.Probieren Sie es online! oder sehen Sie alle Eingaben in der Testsuite .
Wie?
quelle
Gelee , 31 Bytes
Probieren Sie es online!
Wheeeeee 32 Bytes zu lang
Erläuterung
quelle
"G#", "A"
(dissonant) ergibt einen Unterschied, der11
nicht in ist[1,2,6]
.Mathematica, 55 Bytes
Ordnen Sie die interne Funktion
Sound`PitchToNumber
der 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 (wieA4 = 440.
) und die FunktionHertzToCents
(die gespielt werden kann). Anstelle von Strings werden die Noten-Konstanten als Argumente verwendet, jedoch für jede Funktion in einem anderen Format angegeben.Der Paketimport
<<Music`;
dauert 9 Bytes.Diese Funktion konvertiert einen String (like
"F#"
) in eine Noten-Konstante (likeFsharp3
):Ersetzen Sie
Abs[…]
durch , um Intervalle zu akzeptieren, die länger als eine Oktave sindMod[…,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.
Die rationale Näherung liegt innerhalb
1/17
des Intervalls, da dies die größte Schwelle ist, die alle 12 gleich temperierten Intervalle unterscheidet. Wir ordnen rationale Zahlen zuerst dem MusterRational[a_,b_]
(oder nur dem Mustera_~_~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.
quelle
Mathematica, 118 Bytes
Eingabeformular
Ausgänge
danke @ JonathanFrech -16 Bytes
quelle
Consonant
und ausgebenDissonant
. Sie können stattdessen zwei beliebige Werte ausgeben (0/1, ... was auch immer). Das könnte einige Bytes einsparen.If[...,0,1]
und definierenTrue->Consonant; False->Dissonant
?StringCases["CC#DD#EFF#GG#AA#B",_~~"#"...]
- 42 Bytes{1,2,6,10,11}
von1|2|6|10|11
Kohle , 30 Bytes
Probieren Sie es online! Link ist eine ausführliche Version des Codes. Ausgänge 1 für Konsonanten, 0 für Dissonanten. Erläuterung:
quelle
⌕ζ
für "Index suchen" verwendet wird?ζ
ist die Variable, die zuvor zugewiesen wurde.J, 68 Bytes
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!
quelle
/// ,
9088 BytesProbieren Sie es online! (alle Testfälle auf einmal)
,B#
in jedem Testfall mit.,
für Konsonanten,,#
für Dissonanten.##
) oderE#
in bestimmten Fällen. Ansonsten ist der Ausgang,
für Konsonanten,#,
für Dissonanten (dank Modulo 12-Symmetrie)quelle
C (gcc) 91 Bytes
Anruf:
f("A#", "D")
Rückgabewert:
Bonus: Die Funktion unterscheidet nicht zwischen Groß- und Kleinschreibung.
Probieren Sie es online!
quelle
return (
?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!Python 2,
125 117 83 7877 BytesWo 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
str
des Index anstelle vonlist
.-4 Bytes von Inlining
i
und Neils Umkehrung des String-Vorschlags (nur -2 wirklich, da ich()
einen Generator vergessen habe )-5 Bytes nach dem Aufheben des Inlinings
i
und Ändern des Eingabeformats-1 Bytes von Jonathan Frech mit
map()
und unprintables.Übernimmt die Eingabe in einer Zeile von stdin im Format:
True
ist dissonant,False
ist konsonant.Alte Erklärung:
Python
str.index
gibt den niedrigsten (positiven) Startindex einer übereinstimmenden Teilzeichenfolge zurück, also"ABACABA".index("A") == 0
und"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 nichtA
geschehen istA#
, ist die gemeinsameA
Nutzung kein Problem.i
ist 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 abweichtC
).Python 2
input()
ist (meistens) äquivalent zueval(input())
Python3, also mit einer gültigen Eingabe des Formats'C#','F'
(zum Beispiel)a='C#'
undb='F'
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.
quelle
eval(input())
(13 Byte) anstelle voninput().split()
(15 Byte) verwenden.
anstelle einer leeren Zeichenfolge auch Unicode-Zeichen ( ) verwenden.C (gcc) , 115
117120BytesProbieren Sie es online!
Geben Sie 1/0 für consonat und dissonat zurück. Es ist immer interessant, Zeichenfolgen mit reinem C zu manipulieren
f("A#", "C")
quelle
PowerShell , 107 Byte
Probieren Sie es online!
Ausgänge
True
für dissonant undFalse
für konsonant.Nimmt die Eingabe
$a
und$b
die beiden Noten als Zeichenfolgen. Führt eine-split
Operation auf der Skala aus, die in Leerzeichen aufgeteilt wird, um ein Array der Noten zu erstellen, und speichert diese in$x
. Findet das.indexof
$b
in diesem Array, subtrahiert den Index von$a
und nimmt dann denabs
Olutewert davon. Überprüft, ob diese Zahl-in
den dissonanten Bereichen entspricht.quelle
Python 2 , 68 Bytes
Probieren Sie es online!
Outputs:
1
ist dissonant,0
ist konsonant.quelle
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?
quelle
Perl 5 , 106 Bytes
Probieren Sie es online!
Gibt false für den Dissonanten zurück, true für den Konsonanten.
quelle