Consider the C Major scale : C, D, E, F, G, A, B

Following are the triads in the C Major scale :

C CEG
Dm DFA
Em EGB
F FAC
G GBD
Am ACE
Bdim BDF

These structure are very fundamental to the major scale and they provide an integral foundation to understand or improvise over the major scale and its derived modes.

In order to improvise over chord changes in a fixed scale, the very first approach is to just play the chord tones. Keeping that in mind, we need an efficient way to map these triads over whatever instrument it is we are playing. A convenient way would be to think in terms of inversions. This will help us in reducing the net distance that we need to move to reach all the chord tones of a chord progression.

This approach works especially well on a linearly mapped instrument like a piano or a guitar.

Let’s take a simple chord progression : Am, Dm, G, C (6251)

The notes that we need to reach would then be :

  1. [ACE], [DFA], [GBD], [CEG]

Looking at just the root notes, they seem to spread over the fretboard. And incorporating all chord tones would result in a large net area on the fretboard (assuming only root positions)

Screenshot 2024-09-07 at 8.19.36 PM.png

A neater way of playing over these changes would be to identify the overlap of consecutive chords and optimize accordingly.

For our chord progresion, we can afford to just stay in a small area as such :

Screenshot 2024-09-07 at 8.20.25 PM.png

This begs the question, what is the minimum number of triads which cover the entire scale?

Right off the bat, 1 and 2 cannot be the answer since they can maximally cover 3 and 6 notes respectively. So we need to look at which set of 3 triads can cover the entire scale.

We have a total of ${7 \choose 3}$ ways which accounts to ${765 \over 321} = 35$ possibilities.

Let’s look at the cover that these permutations provide :

from itertools import combinations 

perm = combinations([1, 2, 3, 4, 5, 6, 7], 3) 
for i in list(perm): 
    cover = set()
    for j in i:
        cover.add(j)
        cover.add((j+1)%7+1)
        cover.add((j+3)%7+1)
    print (i, cover)