Musik: Wie heißt dieser Akkord?

9

Dies ist das Gegenteil von Musik: Was ist in diesem Akkord? , das heißt, die Noten in einem bestimmten Akkord zu drucken. Diesmal ist die Eingabe eine Liste von Noten in einem Akkord, und Ihre Aufgabe besteht darin, den Akkord auszugeben, um den es sich handelt.

Ihr Programm sollte die folgenden Triadenakkorde unterstützen. Beispiele werden mit Grundton C angegeben. Akkorde mit anderen Grundtönen sind dieselben Akkorde, wobei alle Noten gedreht werden, sodass C zu diesem Grundton wird, z. B. besteht Dmaj aus D, F # und A.

        C C#D D#E F F#G G#A A#B
          Db  Eb    Gb  Ab  Bb
Cmaj    C       E     G
Cm      C     D#      G
Caug    C       E       G#
Cdim    C     D#    F#
Csus4   C         F   G
Csus2   C   D         G

Beachten Sie, dass Caug mit Eaug und G # aug identisch ist und Csus4 mit Fsus2 identisch ist. Sie können beide ausgeben, aber es gibt einen Bonus, wenn Sie alle ausgeben.

Die siebten Akkorde für den Bonus sind in der folgenden Tabelle aufgeführt:

        C C#D D#E F F#G G#A A#B
          Db  Eb    Gb  Ab  Bb
C7      C       E     G     A#
Cm7     C     D#      G     A#
Cmmaj7  C     D#      G       B
Cmaj7   C       E     G       B
Caug7   C       E       G#  A#
Cdim7   C     D#    F#    A

Regeln

  • Sie können entweder ein komplettes Programm oder eine Funktion schreiben.
  • Die Eingabe ist eine Liste von Notizen, die durch ein Leerzeichen oder ein anderes geeignetes Zeichen getrennt sind. Es kann sich auch um ein Array von Zeichenfolgen handeln (wenn Eingaben vom Funktionsargument vorgenommen werden) oder um die Zeichenfolgendarstellung eines solchen Arrays.
  • Die Eingabe muss nicht in einer bestimmten Reihenfolge erfolgen.
  • Die Eingabe enthält möglicherweise doppelte Notizen. Sie müssen genauso behandelt werden, wie es nur einen von ihnen gibt.
  • Die Ausgabe ist der Name des Akkords. Für den Fall, dass mehrere Namen ausgegeben werden, gilt dieselbe Regel für die Eingabe.
  • Wenn die Eingabe kein unterstützter Akkord ist, sollten Sie die Noten unverändert drucken. Ihr Programm kann auch andere Akkorde unterstützen, die nicht in den obigen Tabellen aufgeführt sind (gültig, aber ohne Bonus).
  • Sie können andere im Wikipedia-Artikel aufgeführte Notationen verwenden . Wenn Sie sich jedoch Cfür C-Dur entscheiden, sollten Sie in beiden Fällen ein lesbares Präfix hinzufügen, um einen Akkord mit einer einzelnen Note zu unterscheiden.
  • Sie können für diese Aufgabe keine integrierten Funktionen verwenden (falls vorhanden).
  • Das ist Code-Golf. Der kürzeste Code in Bytes gewinnt.

Beispiele

  • Eingabe: C D# GAusgabe : Cm.
  • Eingabe: C Eb GAusgabe : Cm.
  • Eingabe: C Eb F#Ausgabe : Cdim.
  • Input: F A C#Output: Faug, Aaug, C#aug, Dbaugoder Faug Aaug C#aug, Faug Aaug Dbaugin beliebiger Reihenfolge.
  • Eingabe: F D F F F F A A FAusgabe : Dm.
  • Eingabe: C DAusgabe : C D.

Boni

  • -30, wenn alle gedruckt werden, wenn mehr als eine Interpretation vorhanden ist (für aug, sus4 / sus2 und dim7).
  • -70, wenn es auch Septakkorde unterstützt.
  • -200, wenn es einen MIDI-Eingang akzeptiert und jeden empfangenen Akkord druckt. Beachten Sie, dass die Notizen nicht gleichzeitig beginnen oder enden müssen. Sie entscheiden, was in den Zwischenzuständen passiert (solange es nicht abstürzt oder nicht mehr funktioniert). Sie können davon ausgehen, dass die Percussion-Kanäle keine Noten enthalten (oder es gibt nur einen Kanal, wenn dies zweckmäßig ist). Es wird empfohlen, zum Testen auch eine Text- (oder Array-) Version bereitzustellen, insbesondere wenn diese plattformabhängig ist.
jimmy23013
quelle
Kann der Eingang flach sein oder wird nur scharf verwendet? Sollten Notizen wie B # behandelt werden?
Feersum
@feersum Es kann Wohnungen geben (es sei denn, Sie beanspruchen den -200 Bonus). Einige Beispiele hinzugefügt. Sie müssen nicht behandeln B#, Cbetc.
jimmy23013
Du sagst Csus4 is the same as Gsus2. Ich denke du meinst Csus2 is the same as Gsus4nicht wahr?
Gareth
@ Gareth ... Ja. Fest.
Jimmy23013

Antworten:

2

Pyth 190 Zeichen - 30 - 70 = 90

=Q{cQdL+x"C D EF G A B"hb&tlbt%hx" #b"eb3FZQJx[188 212 199 213 200 224 2555 2411 2412 2556 2567 2398)u+*G12hHSm%-dyZ12mykQ0IhJ+Z@c"sus2 maj dim aug m sus4 7 m7 mmaj7 maj7 aug7 dim7"dJ=T0;ITQ

Nicht wirklich glücklich damit. Benutzte hartcodierte Akkorde.

Verwendungszweck:

Probieren Sie es hier aus: Pyth Compiler / Executor . Deaktivieren Sie den Debug-Modus und verwenden Sie ihn "C D# G"als Eingabe.

Erläuterung:

Zuerst einige Vorbereitungen:

=Q{cQd
   cQd  split chord into notes "C D# G" -> ["C", "D#", "G"]
  {     set (eliminate duplicates)
=Q      Q = ...

Dann eine Funktion, die Noten in Ganzzahlen umwandelt

L+x"C D EF G A B"hb&tlbt%hx" #b"eb3
defines a function g(b),
  returns the sum of 
     index of "D" in "C D EF G A B"
     and the index of "#" in " #b" 
       (if b than use -1 instead of 2)

Verschieben Sie dann für jede Note die Koordinate und schlagen Sie sie in einer Tabelle nach

FZQJx[188 ...)u+*G12hHSm%-dyZ12mykQ0IhJ+Z@c"sus2 ..."dJ=T0;ITQ
               implicit T=10
FZQ            for note Z in chord Q:
   mykQ         map each note of Q to it's integer value
   m%-dyZ12     shift it by the integer value of Z modulo 12 
   S            sort it
   u+*G12hH 0   convert it to an integer in base 12
   x[188 ...)   look it up in the list (-1 if not in list)
   J            and store the value in J

   IhJ               if J>=0:
   +Z@c"sus2 ..."dJ   print the note Z and the chord in the list
=T0                   and set T=0
;            end loop
ITQ          if T:print chord (chord not in list)
Jakube
quelle
2

Perl 5: 183-100 = 83

Bearbeiten: Ich habe es geschafft, einige zusätzliche Zeichen zu schneiden, also habe ich auch die Akkordnamen wie in der Python-Lösung geändert, damit ich für einen Moment so tun kann, als würde ich führen.

#!perl -pa
for$z(0..11){$x=0;$x|=1<<((/#/-/b/+$z+1.61*ord)%12or$o=$_)for@F;$x-/\d+_?/-$_*4||push@r,$o.$'
for qw(36M 34- 68+ 18o 40sus2 33sus4 292_7 290-7 546-M7 548M7 324+7 146o7)}$_="@r
"if@r

Beispiel:

$ perl chord.pl <<<"C D# G"
C-
Nutki
quelle
0

Python 2, 335 Bytes - 30 - 70 = 235

Erster Versuch eines etwas längeren Golfspiels, daher fehlen mir möglicherweise einige offensichtliche Tricks.

def f(s,N="C D EF G A B",r=range,u=1):
 for i in r(12):
  for t in r(12):
   if(set((N.find(n[0])+" #".find(n[1:]))%12for n in s.split())==set(map(lambda n:(int(n,16)+i)%12,"0"+"47037048036057027047A37A37B47B48A369"[3*t:3*t+3]))):print(N[i],N[i+1]+"b")[N[i]==" "]+"M - + o sus4 sus2 7 -7 -M7 M7 +7 o7".split()[t];u=0
 if(u):print s

Bemerkungen:

  • Ich habe alternative Akkordnamen von der Wiki-Seite verwendet (siehe Ende der langen Zeile), um Platz zu sparen.
  • Akkorde werden durch jeweils 3 Hex-Offsets dargestellt (0 ist nicht erforderlich, aber für Triaden enthalten, damit sie ausgerichtet werden).
  • "#". find (n [1:]) funktioniert, da "#". find ("b") -1 und "#". find ("") 0 ist.

Beispielausgabe

>>> f("C D# G")
C-
>>> f("C Eb G")
C-
>>> f("C Eb F#")
Co
>>> f("F A C#")
Db+
F+
A+
>>> f("F D F F F F A A F")
D-
>>> f("C D")
C D
>>> f("C Eb Gb A")
Co7
Ebo7
Gbo7
Ao7
Uri Granta
quelle