Check if given chord is minor or major.

_____________________________________________________________
Rules:

1. Basic minor/major chord have three elements.

2. Chord is minor when interval between first and second element equals 3 and between second and third -> 4.

3. Chord is major when interval between first and second element equals 4 and between second and third -> 3.

4. In minor/major chord interval between first and third element equals... 7.

_______________________________________________________________
There is a preloaded list of the 12 notes of a chromatic scale built on C. This means that there are (almost) all allowed note' s names in music.

notes = 
['C', ['C#', 'Db'], 'D', ['D#', 'Eb'], 'E', 'F', ['F#', 'Gb'], 'G', ['G#', 'Ab'], 'A', ['A#', 'Bb'], 'B']

Note that e. g. 'C#' - 'C' = 1, 'C' - 'C#' = 1, 'Db' - 'C' = 1 and 'B' - 'C' = 1. 

Input:
String of notes separated by whitespace, e. g. 'A C# E'

Output:
String message: 'Minor', 'Major' or 'Not a chord'.

Source: codewars | Difficulty: EASY
Tags: String algorithms

Fundamentals

Data structures

Starter code: def minor_or_major(chord):
	

Solutions:
from itertools import product
NOTES = [['C'], ['C#', 'Db'], ['D'], ['D#', 'Eb'], ['E'], ['F'], ['F#', 'Gb'], ['G'], ['G#', 'Ab'], ['A'], ['A#', 'Bb'], ['B']] * 2
config = [('Major', 4), ('Minor', 3)]
DCT_CHORDS = {c: mode for (mode, offset) in config for i in range(len(NOTES) // 2) for c in product(NOTES[i], NOTES[i + offset], NOTES[i + 7])}

def minor_or_major(chord):
	chord = tuple(chord.split()) if isinstance(chord, str) else ''
	return DCT_CHORDS.get(chord, 'Not a chord')


from itertools import product
NOTES = [['C'], ['C#', 'Db'], ['D'], ['D#', 'Eb'], ['E'], ['F'], ['F#', 'Gb'], ['G'], ['G#', 'Ab'], ['A'], ['A#', 'Bb'], ['B']] * 2
MAJOR = set((c for i in range(len(NOTES) // 2) for c in product(NOTES[i], NOTES[i + 4], NOTES[i + 7])))
MINOR = set((c for i in range(len(NOTES) // 2) for c in product(NOTES[i], NOTES[i + 3], NOTES[i + 7])))

def minor_or_major(chord):
	chord = tuple(chord.split()) if isinstance(chord, str) else ('', '', '')
	return 'Major' if chord in MAJOR else 'Minor' if chord in MINOR else 'Not a chord'


notes = ['C', ['C#', 'Db'], 'D', ['D#', 'Eb'], 'E', 'F', ['F#', 'Gb'], 'G', ['G#', 'Ab'], 'A', ['A#', 'Bb'], 'B']
mom = {(3, 4): 'Minor', (4, 3): 'Major'}
levels = {x: i for (i, xs) in enumerate(notes) for x in ([xs] if isinstance(xs, str) else xs)}

def minor_or_major(chord):
	xs = [levels.get(c) for c in chord.split()]
	if None in xs:
		return 'Not a chord'
	deltas = tuple(((b - a) % len(notes) for (a, b) in zip(xs, xs[1:])))
	return mom.get(deltas, 'Not a chord')


base = {'C': 0, 'C#': 1, 'Db': 1, 'D': 2, 'D#': 3, 'Eb': 3, 'E': 4, 'F': 5, 'F#': 6, 'Gb': 6, 'G': 7, 'G#': 8, 'Ab': 8, 'A': 9, 'A#': 10, 'Bb': 10, 'B': 11}
minor_or_major = lambda c: 'Not a chord' if sum((n in base for n in c.split())) != 3 else (lambda ns: 'Major' if (12 + base[ns[1]] - base[ns[0]]) % 12 == 4 and (12 + base[ns[2]] - base[ns[1]]) % 12 == 3 else 'Minor' if (12 + base[ns[1]] - base[ns[0]]) % 12 == 3 and (12 + base[ns[2]] - base[ns[1]]) % 12 == 4 else 'Not a chord')(c.split())


NOTES = {'C': 0, 'C#': 1, 'Db': 1, 'D': 2, 'D#': 3, 'Eb': 3, 'E': 4, 'F': 5, 'F#': 6, 'Gb': 6, 'G': 7, 'G#': 8, 'Ab': 8, 'A': 9, 'A#': 10, 'Bb': 10, 'B': 11}

def minor_or_major(chord):
	notes = chord.split(' ')
	if len(notes) != 3:
		return 'Not a chord'
	(first, second, third) = [NOTES[note] if note in NOTES else 0 for note in notes]
	interval = (second - first + 12) % 12
	return 'Not a chord' if (third - first + 12) % 12 != 7 or interval not in (3, 4) else 'Minor' if interval == 3 else 'Major'


def minor_or_major(chord):
	interval = {'C': 1, 'C#': 2, 'Db': 2, 'D': 3, 'D#': 4, 'Eb': 4, 'E': 5, 'F': 6, 'F#': 7, 'Gb': 7, 'G': 8, 'G#': 9, 'Ab': 9, 'A': 10, 'A#': 11, 'Bb': 11, 'B': 12}
	chord = chord.split()
	if len([i for i in chord if i in interval]) == 3:
		if interval[chord[1]] - interval[chord[0]] in [4, -8] and interval[chord[2]] - interval[chord[1]] in [3, -9]:
			return 'Major'
		elif interval[chord[1]] - interval[chord[0]] in [3, -9] and interval[chord[2]] - interval[chord[1]] in [4, -8]:
			return 'Minor'
		else:
			return 'Not a chord'
	else:
		return 'Not a chord'


def minor_or_major(s):
	p = ['C D EF G A B'.find(n[0]) + ('#' in n) - ('b' in n) for n in s.split()]
	return {(3, 4): 'Minor', (4, 3): 'Major'}.get(tuple(((b - a + 12) % 12 for (a, b) in zip(p, p[1:]))), 'Not a chord')