Muzyka: Jak nazywa się ten akord?

9

To jest odwrotność muzyki: co jest w tym akordzie? , czyli wydrukować nuty w danym akordie. Tym razem wejściem jest lista nut akordu, a Twoim zadaniem jest wyprowadzenie, który to akord.

Twój program powinien obsługiwać następujące akordy triadyczne. Przykłady podano z rdzeniem C. Akordy z innymi rdzeniami są tymi samymi akordami ze wszystkimi nutami obróconymi, więc C stanie się tą nutą, np. Dmaj składa się z D, F # i 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

Zauważ, że Caug jest taki sam jak Eaug i G # aug, a Csus4 jest taki sam jak Fsus2. Możesz wypisać jeden, ale jest bonus, jeśli wypiszesz je wszystkie.

A siódme akordy bonusu wymieniono w poniższej tabeli:

        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

Zasady

  • Możesz napisać pełny program lub funkcję.
  • Dane wejściowe to lista notatek oddzielonych spacją lub innym wygodnym znakiem. Może to być również tablica ciągów znaków (jeśli pobiera dane wejściowe z argumentu funkcji) lub ciąg znaków takiej tablicy.
  • Dane wejściowe nie muszą być w określonej kolejności.
  • Dane wejściowe mogą zawierać duplikaty. Należy je traktować tak samo, jak tylko jeden z nich.
  • Wyjście to nazwa akordu. W przypadku, gdy wyświetli wiele nazw, obowiązuje ta sama zasada wprowadzania.
  • Jeśli wejście nie jest obsługiwanym akordem, powinieneś wydrukować nuty tak, jak jest. Twój program może także obsługiwać inne akordy niewymienione w powyższych tabelach (co jest ważne, ale nie ma bonusu).
  • Możesz użyć innych notacji wymienionych w artykule w Wikipedii . Ale jeśli wybierzesz CC-dur, w obu przypadkach dodaj przedrostek czytelny dla człowieka, aby rozróżnić akord za pomocą jednej nuty.
  • Nie można używać wbudowanych funkcji do tego zadania (jeśli takie istnieją).
  • To jest golf golfowy. Najkrótszy kod w bajtach wygrywa.

Przykłady

  • Wejście: C D# GWyjście: Cm.
  • Wejście: C Eb GWyjście: Cm.
  • Wejście: C Eb F#Wyjście: Cdim.
  • Wejście: F A C#Wyjście: Faug, Aaug, C#aug, Dbauglub Faug Aaug C#aug, Faug Aaug Dbaugw dowolnej kolejności.
  • Wejście: F D F F F F A A FWyjście: Dm.
  • Wejście: C DWyjście: C D.

Bonusy

  • -30, jeśli wypisze je wszystkie, jeśli istnieje więcej niż jedna interpretacja (dla aug, sus4 / sus2 i dim7).
  • -70, jeśli obsługuje także siódme akordy.
  • -200, jeśli akceptuje wejście MIDI i drukuje każdy otrzymany akord. Pamiętaj, że nuty nie muszą zaczynać się ani kończyć w tym samym czasie. Ty decydujesz, co stanie się w stanach pośrednich (o ile nie ulegnie awarii lub przestanie działać). Możesz założyć, że nie ma nut w kanałach perkusyjnych (lub jest tylko jeden kanał, jeśli jest to wygodne). Zaleca się również zapewnienie wersji testowej (tekstowej lub tablicowej), szczególnie jeśli zależy ona od platformy.
jimmy23013
źródło
Czy na wejściu mogą znajdować się mieszkania, czy tylko ostry? Czy należy obsługiwać nuty takie jak B #?
feersum
@feersum Może mieć mieszkania (chyba, że ​​ubiegasz się o bonus -200). Dodano kilka przykładów. Nie trzeba do rączki B#, Cbitd
jimmy23013
Mówisz Csus4 is the same as Gsus2. Myślę, że masz na myśli Csus2 is the same as Gsus4, prawda?
Gareth
@Gareth ... Tak. Naprawiony.
jimmy23013

Odpowiedzi:

2

Znak Pyth 190 - 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

Nie bardzo z tego zadowolony. Używane na stałe akordy.

Stosowanie:

Wypróbuj tutaj: Pyth Compiler / Executor . Wyłącz tryb debugowania i użyj "C D# G"jako danych wejściowych.

Wyjaśnienie:

Najpierw jakieś przygotowania:

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

Następnie funkcja konwertująca notatki na liczbę całkowitą

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)

Następnie dla każdej nuty przesuń współrzędną i wyszukaj w tabeli

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
źródło
2

Perl 5: 183 - 100 = 83

Edycja: Udało mi się wyciąć dodatkowe znaki, więc zmieniłem też nazwy akordów, tak jak w rozwiązaniu Python, aby przez chwilę udawać, że prowadzę.

#!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

Przykład:

$ perl chord.pl <<<"C D# G"
C-
nutki
źródło
0

Python 2, 335 bajtów - 30 - 70 = 235

Pierwsza próba nieco dłuższego golfa, więc może mi brakować oczywistych sztuczek.

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

Komentarze:

  • Użyłem alternatywnych nazw akordów ze strony Wiki (patrz koniec długiej linii), aby zaoszczędzić miejsce.
  • Akordy są reprezentowane przez 3 przesunięcia heksów każdy (0 nie jest wymagane, ale dołączone dla triad, aby je ustawić).
  • „#”. find (n [1:]) działa, ponieważ „#”. find („b”) wynosi -1, a „#”. find („”) wynosi 0.

Próbka wyjściowa

>>> 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
źródło