Musik: Apa nama chord ini?

9

Ini kebalikan dari Musik: ada apa di chord ini? , yaitu untuk mencetak catatan dalam akord yang diberikan. Kali ini inputnya adalah daftar catatan dalam akor, dan tugas Anda adalah untuk menghasilkan akor mana.

Program Anda harus mendukung akord triadik berikut. Contoh diberikan dengan root C. Akord dengan root lain adalah akord yang sama dengan semua nada diputar sehingga C akan menjadi catatan root, misalnya Dmaj terdiri dari D, F # dan 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

Perhatikan bahwa Caug sama dengan Eaug dan G # aug, dan Csus4 sama dengan Fsus2. Anda dapat menampilkan salah satu tetapi ada bonus jika Anda menampilkan semuanya.

Dan akord ketujuh untuk bonus tercantum dalam tabel berikut:

        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

Aturan

  • Anda dapat menulis program atau fungsi yang lengkap.
  • Input adalah daftar catatan, dipisahkan oleh spasi atau karakter lain yang sesuai. Ini juga bisa berupa array string (jika mengambil input dari argumen fungsi) atau representasi string array tersebut.
  • Input tidak harus dalam urutan tertentu.
  • Mungkin ada duplikat catatan di input. Mereka harus diperlakukan dengan cara yang sama karena hanya ada satu dari mereka.
  • Outputnya adalah nama chord. Dalam hal ini akan menampilkan beberapa nama, aturan yang sama untuk input berlaku.
  • Jika input bukan kunci yang didukung, Anda harus mencetak catatan apa adanya. Program Anda juga dapat mendukung akor lain yang tidak tercantum dalam tabel di atas (yang valid tetapi tidak memiliki bonus).
  • Anda dapat menggunakan notasi lain yang tercantum dalam artikel Wikipedia . Tetapi jika Anda memilih Cuntuk C mayor, Anda harus menambahkan awalan yang dapat dibaca manusia dalam kedua kasus untuk membedakan akor dengan satu not.
  • Anda tidak dapat menggunakan fungsi bawaan untuk tugas ini (jika ada).
  • Ini adalah kode-golf. Kode terpendek dalam byte menang.

Contohnya

  • Input: C D# GOutput: Cm.
  • Input: C Eb GOutput: Cm.
  • Input: C Eb F#Output: Cdim.
  • Input: F A C#Output: Faug, Aaug, C#aug, Dbaugatau Faug Aaug C#aug, Faug Aaug Dbaugdalam urutan apapun.
  • Input: F D F F F F A A FOutput: Dm.
  • Input: C DOutput: C D.

Bonus

  • -30 jika mencetak semuanya jika ada lebih dari satu interpretasi (untuk aug, sus4 / sus2 dan dim7).
  • -70 jika itu juga mendukung akord ketujuh.
  • -200 jika menerima input MIDI dan mencetak setiap chord yang telah diterimanya. Perhatikan bahwa catatan tidak harus dimulai atau berakhir pada saat yang sama. Anda memutuskan apa yang terjadi di kondisi perantara (selama tidak macet atau berhenti bekerja). Anda dapat berasumsi tidak ada catatan di saluran perkusi (atau hanya ada satu saluran jika itu nyaman). Disarankan juga untuk menyediakan versi teks (atau larik) untuk pengujian, terutama jika itu tergantung platform.
jimmy23013
sumber
Dapatkah input memiliki flat atau hanya menggunakan yang tajam? Haruskah catatan seperti B # ditangani?
feersum
@feersum Ini dapat memiliki flat (kecuali jika Anda mengklaim bonus -200). Menambahkan beberapa contoh. Anda tidak perlu pegangan B#, Cb, dll
jimmy23013
Anda mengatakan Csus4 is the same as Gsus2. Saya pikir maksud Csus2 is the same as Gsus4Anda bukan?
Gareth
@ Gareth ... Ya. Tetap.
jimmy23013

Jawaban:

2

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

Tidak begitu senang dengannya. Menggunakan akord kode keras.

Pemakaian:

Cobalah di sini: Pyth Compiler / Executor . Nonaktifkan mode debug dan gunakan "C D# G"sebagai input.

Penjelasan:

Pertama beberapa persiapan:

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

Kemudian fungsi yang mengubah catatan menjadi bilangan bulat

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)

Kemudian untuk setiap not, geser coord dan cari dalam tabel

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
sumber
2

Perl 5: 183 - 100 = 83

Sunting: Saya berhasil memotong beberapa karakter tambahan jadi saya juga mengubah nama akor seperti pada solusi Python, jadi saya bisa berpura-pura sejenak bahwa saya sedang memimpin.

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

Contoh:

$ perl chord.pl <<<"C D# G"
C-
nutki
sumber
0

Python 2, 335 byte - 30 - 70 = 235

Upaya pertama pada golf yang sedikit lebih panjang, jadi saya mungkin kehilangan beberapa trik yang jelas.

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

Komentar:

  • Saya menggunakan nama akor alternatif dari halaman Wiki (lihat akhir dari garis panjang) untuk menghemat ruang.
  • Akor diwakili oleh masing-masing 3 offset hex (0 tidak diperlukan tetapi termasuk untuk triad untuk membuat mereka berbaris).
  • "#". find (n [1:]) berfungsi karena "#". find ("b") adalah -1 dan "#". find ("") adalah 0.

Output sampel

>>> 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
sumber