Is this a Major Scale (or equivalent)?











up vote
16
down vote

favorite












Sandbox



The major scale (or Ionian scale) is one of the most commonly used musical scales, especially in Western music. It is one of the diatonic scales. Like many musical scales, it is made up of seven notes: the eighth duplicates the first at double its frequency so that it is called a higher octave of the same note.



The seven musical notes are:




C, D, E, F, G, A, B, C (repeated for example purposes)




A major scale is a diatonic scale. Take the previous succession of notes as a major scale (Actually, It is the scale C Major). The sequence of intervals between the notes of a major scale is:




whole, whole, half, whole, whole, whole, half




where "whole" stands for a whole tone (a red u-shaped curve in the figure), and "half" stands for a semitone (a red broken line in the figure).



enter image description here



In this case, from C to D exist a whole tone, from D to E exist a whole tone, from E to F exist half tone, etc...



We have 2 components that affects the tone distance between notes. These are the Sharp symbol (♯) and the flat symbol (♭).



The Sharp symbol (♯) adds half tone to the note. Example. From C to D we mentioned that exists a whole tone, if we use C♯ instead C then from C♯ to D exists half tone.



The Flat symbol (♭) do the opposite of the Sharp symbol, it subtract half tone from the note. Example: From D to E we mentioned that exists a whole tone, if we use Db instead D then from Db to E exists a tone and a half.



By default, from Note to Note exist a whole tone except for E to F and B to C in where just half tone exists.



Note in some cases using enharmonic pitches can create an equivalent to a Major Scale. An example of this is C#, D#, E#, F#, G#, A#, B#, C# where E# and B# are enharmonic but the scale follows the sequence of a Major Scale.





Challenge



Given a scale, output a truthy value if it is a Major Scale or equivalent, otherwise output a falsey value.



Rules




  • Standard I/O method allowed

  • Standard code-golf rules apply

  • You don't need to take in consideration the 8th note. Assume the input will only consist of 7 notes

  • Assume double flat (♭♭), double sharp (♯♯) or natural sign (♮) don't exist




Test cases



C, D, E, F, G, A, B                 => true
C#, D#, E#, F#, G#, A#, B# => true
Db, Eb, F, Gb, Ab, Bb, C => true
D, E, Gb, G, A, Cb, C# => true
Eb, E#, G, G#, Bb, B#, D => true
-----------------------------------------------
C, D#, E, F, G, A, B => false
Db, Eb, F, Gb, Ab, B, C => false
G#, E, F, A, B, D#, C => false
C#, C#, E#, F#, G#, A#, B# => false
Eb, E#, Gb, G#, Bb, B#, D => false









share|improve this question
























  • So, E# is equal to F, and Cb equal to B?
    – Abigail
    Nov 8 at 14:13






  • 1




    and Cx (or C##) = D
    – SaggingRufus
    Nov 8 at 18:32






  • 1




    Btw, Pentatonic scales do not have one of each letter :v
    – Luis felipe De jesus Munoz
    Nov 8 at 19:48






  • 1




    @Neil Chromatic scales do not have unique letters and I'm sure there is a type of scale that doesnt follow an ascending order
    – Luis felipe De jesus Munoz
    Nov 8 at 21:38








  • 1




    I'm going to have to upvote this because @Neil downvoted it thank you very much
    – David Conrad
    Nov 9 at 18:03















up vote
16
down vote

favorite












Sandbox



The major scale (or Ionian scale) is one of the most commonly used musical scales, especially in Western music. It is one of the diatonic scales. Like many musical scales, it is made up of seven notes: the eighth duplicates the first at double its frequency so that it is called a higher octave of the same note.



The seven musical notes are:




C, D, E, F, G, A, B, C (repeated for example purposes)




A major scale is a diatonic scale. Take the previous succession of notes as a major scale (Actually, It is the scale C Major). The sequence of intervals between the notes of a major scale is:




whole, whole, half, whole, whole, whole, half




where "whole" stands for a whole tone (a red u-shaped curve in the figure), and "half" stands for a semitone (a red broken line in the figure).



enter image description here



In this case, from C to D exist a whole tone, from D to E exist a whole tone, from E to F exist half tone, etc...



We have 2 components that affects the tone distance between notes. These are the Sharp symbol (♯) and the flat symbol (♭).



The Sharp symbol (♯) adds half tone to the note. Example. From C to D we mentioned that exists a whole tone, if we use C♯ instead C then from C♯ to D exists half tone.



The Flat symbol (♭) do the opposite of the Sharp symbol, it subtract half tone from the note. Example: From D to E we mentioned that exists a whole tone, if we use Db instead D then from Db to E exists a tone and a half.



By default, from Note to Note exist a whole tone except for E to F and B to C in where just half tone exists.



Note in some cases using enharmonic pitches can create an equivalent to a Major Scale. An example of this is C#, D#, E#, F#, G#, A#, B#, C# where E# and B# are enharmonic but the scale follows the sequence of a Major Scale.





Challenge



Given a scale, output a truthy value if it is a Major Scale or equivalent, otherwise output a falsey value.



Rules




  • Standard I/O method allowed

  • Standard code-golf rules apply

  • You don't need to take in consideration the 8th note. Assume the input will only consist of 7 notes

  • Assume double flat (♭♭), double sharp (♯♯) or natural sign (♮) don't exist




Test cases



C, D, E, F, G, A, B                 => true
C#, D#, E#, F#, G#, A#, B# => true
Db, Eb, F, Gb, Ab, Bb, C => true
D, E, Gb, G, A, Cb, C# => true
Eb, E#, G, G#, Bb, B#, D => true
-----------------------------------------------
C, D#, E, F, G, A, B => false
Db, Eb, F, Gb, Ab, B, C => false
G#, E, F, A, B, D#, C => false
C#, C#, E#, F#, G#, A#, B# => false
Eb, E#, Gb, G#, Bb, B#, D => false









share|improve this question
























  • So, E# is equal to F, and Cb equal to B?
    – Abigail
    Nov 8 at 14:13






  • 1




    and Cx (or C##) = D
    – SaggingRufus
    Nov 8 at 18:32






  • 1




    Btw, Pentatonic scales do not have one of each letter :v
    – Luis felipe De jesus Munoz
    Nov 8 at 19:48






  • 1




    @Neil Chromatic scales do not have unique letters and I'm sure there is a type of scale that doesnt follow an ascending order
    – Luis felipe De jesus Munoz
    Nov 8 at 21:38








  • 1




    I'm going to have to upvote this because @Neil downvoted it thank you very much
    – David Conrad
    Nov 9 at 18:03













up vote
16
down vote

favorite









up vote
16
down vote

favorite











Sandbox



The major scale (or Ionian scale) is one of the most commonly used musical scales, especially in Western music. It is one of the diatonic scales. Like many musical scales, it is made up of seven notes: the eighth duplicates the first at double its frequency so that it is called a higher octave of the same note.



The seven musical notes are:




C, D, E, F, G, A, B, C (repeated for example purposes)




A major scale is a diatonic scale. Take the previous succession of notes as a major scale (Actually, It is the scale C Major). The sequence of intervals between the notes of a major scale is:




whole, whole, half, whole, whole, whole, half




where "whole" stands for a whole tone (a red u-shaped curve in the figure), and "half" stands for a semitone (a red broken line in the figure).



enter image description here



In this case, from C to D exist a whole tone, from D to E exist a whole tone, from E to F exist half tone, etc...



We have 2 components that affects the tone distance between notes. These are the Sharp symbol (♯) and the flat symbol (♭).



The Sharp symbol (♯) adds half tone to the note. Example. From C to D we mentioned that exists a whole tone, if we use C♯ instead C then from C♯ to D exists half tone.



The Flat symbol (♭) do the opposite of the Sharp symbol, it subtract half tone from the note. Example: From D to E we mentioned that exists a whole tone, if we use Db instead D then from Db to E exists a tone and a half.



By default, from Note to Note exist a whole tone except for E to F and B to C in where just half tone exists.



Note in some cases using enharmonic pitches can create an equivalent to a Major Scale. An example of this is C#, D#, E#, F#, G#, A#, B#, C# where E# and B# are enharmonic but the scale follows the sequence of a Major Scale.





Challenge



Given a scale, output a truthy value if it is a Major Scale or equivalent, otherwise output a falsey value.



Rules




  • Standard I/O method allowed

  • Standard code-golf rules apply

  • You don't need to take in consideration the 8th note. Assume the input will only consist of 7 notes

  • Assume double flat (♭♭), double sharp (♯♯) or natural sign (♮) don't exist




Test cases



C, D, E, F, G, A, B                 => true
C#, D#, E#, F#, G#, A#, B# => true
Db, Eb, F, Gb, Ab, Bb, C => true
D, E, Gb, G, A, Cb, C# => true
Eb, E#, G, G#, Bb, B#, D => true
-----------------------------------------------
C, D#, E, F, G, A, B => false
Db, Eb, F, Gb, Ab, B, C => false
G#, E, F, A, B, D#, C => false
C#, C#, E#, F#, G#, A#, B# => false
Eb, E#, Gb, G#, Bb, B#, D => false









share|improve this question















Sandbox



The major scale (or Ionian scale) is one of the most commonly used musical scales, especially in Western music. It is one of the diatonic scales. Like many musical scales, it is made up of seven notes: the eighth duplicates the first at double its frequency so that it is called a higher octave of the same note.



The seven musical notes are:




C, D, E, F, G, A, B, C (repeated for example purposes)




A major scale is a diatonic scale. Take the previous succession of notes as a major scale (Actually, It is the scale C Major). The sequence of intervals between the notes of a major scale is:




whole, whole, half, whole, whole, whole, half




where "whole" stands for a whole tone (a red u-shaped curve in the figure), and "half" stands for a semitone (a red broken line in the figure).



enter image description here



In this case, from C to D exist a whole tone, from D to E exist a whole tone, from E to F exist half tone, etc...



We have 2 components that affects the tone distance between notes. These are the Sharp symbol (♯) and the flat symbol (♭).



The Sharp symbol (♯) adds half tone to the note. Example. From C to D we mentioned that exists a whole tone, if we use C♯ instead C then from C♯ to D exists half tone.



The Flat symbol (♭) do the opposite of the Sharp symbol, it subtract half tone from the note. Example: From D to E we mentioned that exists a whole tone, if we use Db instead D then from Db to E exists a tone and a half.



By default, from Note to Note exist a whole tone except for E to F and B to C in where just half tone exists.



Note in some cases using enharmonic pitches can create an equivalent to a Major Scale. An example of this is C#, D#, E#, F#, G#, A#, B#, C# where E# and B# are enharmonic but the scale follows the sequence of a Major Scale.





Challenge



Given a scale, output a truthy value if it is a Major Scale or equivalent, otherwise output a falsey value.



Rules




  • Standard I/O method allowed

  • Standard code-golf rules apply

  • You don't need to take in consideration the 8th note. Assume the input will only consist of 7 notes

  • Assume double flat (♭♭), double sharp (♯♯) or natural sign (♮) don't exist




Test cases



C, D, E, F, G, A, B                 => true
C#, D#, E#, F#, G#, A#, B# => true
Db, Eb, F, Gb, Ab, Bb, C => true
D, E, Gb, G, A, Cb, C# => true
Eb, E#, G, G#, Bb, B#, D => true
-----------------------------------------------
C, D#, E, F, G, A, B => false
Db, Eb, F, Gb, Ab, B, C => false
G#, E, F, A, B, D#, C => false
C#, C#, E#, F#, G#, A#, B# => false
Eb, E#, Gb, G#, Bb, B#, D => false






code-golf decision-problem music






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 8 at 17:44









Arnauld

69.1k584292




69.1k584292










asked Nov 8 at 13:16









Luis felipe De jesus Munoz

3,99421253




3,99421253












  • So, E# is equal to F, and Cb equal to B?
    – Abigail
    Nov 8 at 14:13






  • 1




    and Cx (or C##) = D
    – SaggingRufus
    Nov 8 at 18:32






  • 1




    Btw, Pentatonic scales do not have one of each letter :v
    – Luis felipe De jesus Munoz
    Nov 8 at 19:48






  • 1




    @Neil Chromatic scales do not have unique letters and I'm sure there is a type of scale that doesnt follow an ascending order
    – Luis felipe De jesus Munoz
    Nov 8 at 21:38








  • 1




    I'm going to have to upvote this because @Neil downvoted it thank you very much
    – David Conrad
    Nov 9 at 18:03


















  • So, E# is equal to F, and Cb equal to B?
    – Abigail
    Nov 8 at 14:13






  • 1




    and Cx (or C##) = D
    – SaggingRufus
    Nov 8 at 18:32






  • 1




    Btw, Pentatonic scales do not have one of each letter :v
    – Luis felipe De jesus Munoz
    Nov 8 at 19:48






  • 1




    @Neil Chromatic scales do not have unique letters and I'm sure there is a type of scale that doesnt follow an ascending order
    – Luis felipe De jesus Munoz
    Nov 8 at 21:38








  • 1




    I'm going to have to upvote this because @Neil downvoted it thank you very much
    – David Conrad
    Nov 9 at 18:03
















So, E# is equal to F, and Cb equal to B?
– Abigail
Nov 8 at 14:13




So, E# is equal to F, and Cb equal to B?
– Abigail
Nov 8 at 14:13




1




1




and Cx (or C##) = D
– SaggingRufus
Nov 8 at 18:32




and Cx (or C##) = D
– SaggingRufus
Nov 8 at 18:32




1




1




Btw, Pentatonic scales do not have one of each letter :v
– Luis felipe De jesus Munoz
Nov 8 at 19:48




Btw, Pentatonic scales do not have one of each letter :v
– Luis felipe De jesus Munoz
Nov 8 at 19:48




1




1




@Neil Chromatic scales do not have unique letters and I'm sure there is a type of scale that doesnt follow an ascending order
– Luis felipe De jesus Munoz
Nov 8 at 21:38






@Neil Chromatic scales do not have unique letters and I'm sure there is a type of scale that doesnt follow an ascending order
– Luis felipe De jesus Munoz
Nov 8 at 21:38






1




1




I'm going to have to upvote this because @Neil downvoted it thank you very much
– David Conrad
Nov 9 at 18:03




I'm going to have to upvote this because @Neil downvoted it thank you very much
– David Conrad
Nov 9 at 18:03










9 Answers
9






active

oldest

votes

















up vote
11
down vote














Perl 6, 76 65 63 59 bytes



-4 bytes thanks to Phil H





{221222==[~] (.skip Z-$_)X%12}o*>>.&{13*.ord+>3+?/#/-?/b/}


Try it online!



Explanation



*>>.&{ ... }  # Map notes to integers
13*.ord # 13 * ASCII code: A=845 B=858 C=871 D=884 E=897 F=910 G=923
+>3 # Right shift by 3: A=105 B=107 C=108 D=110 E=112 F=113 G=115
# Subtracting 105 would yield A=0 B=2 C=3 D=5 E=7 F=8 G=10
# but isn't necessary because we only need differences
+?/#/ # Add 1 for '#'
-?/b/ # Subtract 1 for 'b'

{ }o # Compose with block
(.skip Z-$_) # Pairwise difference
X%12 # modulo 12
[~] # Join
221222== # Equals 221222





share|improve this answer























  • If you're going to do a pairwise difference and modulo 12, you don't need to subtract 105; it's just an offset. -4 chars: tio.run/…
    – Phil H
    Nov 8 at 16:46










  • @PhilH Yes, of course. Thanks!
    – nwellnhof
    Nov 8 at 16:53










  • That's a really clever way of mapping the notes to their relative values, +1 from me!
    – Sok
    Nov 9 at 15:44


















up vote
10
down vote














Node.js v10.9.0, 78 76 71 69 bytes



a=>!a.some(n=>(a-(a=~([x,y]=Buffer(n),x/.6)-~y%61)+48)%12-2+!i--,i=3)


Try it online!



How?



Each note $n$ is converted to a negative number in $[-118,-71]$ with:



[x, y] = Buffer(n) // split n into two ASCII codes x and y
~(x / .6) // base value, using the ASCII code of the 1st character
- ~y % 61 // +36 if the 2nd character is a '#' (ASCII code 35)
// +38 if the 2nd character is a 'b' (ASCII code 98)
// +1 if the 2nd character is undefined


Which gives:



  n   | x  | x / 0.6 | ~(x / 0.6) | -~y % 61 | sum
------+----+---------+------------+----------+------
"Ab" | 65 | 108.333 | -109 | 38 | -71
"A" | 65 | 108.333 | -109 | 1 | -108
"A#" | 65 | 108.333 | -109 | 36 | -73
"Bb" | 66 | 110.000 | -111 | 38 | -73
"B" | 66 | 110.000 | -111 | 1 | -110
"B#" | 66 | 110.000 | -111 | 36 | -75
"Cb" | 67 | 111.667 | -112 | 38 | -74
"C" | 67 | 111.667 | -112 | 1 | -111
"C#" | 67 | 111.667 | -112 | 36 | -76
"Db" | 68 | 113.333 | -114 | 38 | -76
"D" | 68 | 113.333 | -114 | 1 | -113
"D#" | 68 | 113.333 | -114 | 36 | -78
"Eb" | 69 | 115.000 | -116 | 38 | -78
"E" | 69 | 115.000 | -116 | 1 | -115
"E#" | 69 | 115.000 | -116 | 36 | -80
"Fb" | 70 | 116.667 | -117 | 38 | -79
"F" | 70 | 116.667 | -117 | 1 | -116
"F#" | 70 | 116.667 | -117 | 36 | -81
"Gb" | 71 | 118.333 | -119 | 38 | -81
"G" | 71 | 118.333 | -119 | 1 | -118
"G#" | 71 | 118.333 | -119 | 36 | -83


We compute the pairwise differences modulo $12$ between these values.



The lowest possible difference between 2 notes is $-47$, so it's enough to add $4times12=48$ before applying the modulo to make sure that we get a positive result.



Because we apply a modulo $12$, the offset produced by a '#' is actually $36 bmod 12 = 0$ semitone, while the offset produced by a 'b' is $38 bmod 12 = 2$ semitones.



We are reusing the input variable $a$ to store the previous value, so the first iteration just generates $text{NaN}$.



For a major scale, we should get $[ text{NaN}, 2, 2, 1, 2, 2, 2 ]$.



We use the counter $i$ to compare the 4th value with $1$ rather than $2$.






share|improve this answer























  • Great approach, much more interesting than my answer
    – Skidsdev
    10 hours ago


















up vote
4
down vote














JavaScript (Node.js), 150 131 125 bytes





l=>(l=l.map(x=>'C0D0EF0G0A0B'.search(x[0])+(x[1]=='#'|-(x[1]=='b')))).slice(1).map((n,i)=>(b=n-l[i])<0?2:b)+""=='2,2,1,2,2,2'


Try it online!



-19 bytes thanks to Luis felipe
-6 bytes thanks to Shaggy



Ungolfed:



function isMajor(l) {
// Get tone index of each entry
let array = l.map(function (x) {
// Use this to get indices of each note, using 0s as spacers for sharp keys
let tones = 'C0D0EF0G0A0B';
// Get the index of the letter component. EG D = 2, F = 5
let tone = tones.search(x[0]);
// Add 1 semitone if note is sharp
// Use bool to number coercion to make this shorter
tone += x[1] == '#' | -(x[1]=='b');
});
// Calculate deltas
let deltas = array.slice(1).map(function (n,i) {
// If delta is negative, replace it with 2
// This accounts for octaves
if (n - array[i] < 0) return 2;
// Otherwise return the delta
return n - array[i];
});
// Pseudo array-comparison
return deltas+"" == '2,2,1,2,2,2';
}





share|improve this answer



















  • 1




    [...'C0D0EF0G0A0B'] instead of 'C0D0EF0G0A0B'.split('') and +"" instead of .toString() to save some bytes
    – Luis felipe De jesus Munoz
    Nov 8 at 14:36










  • x[1]=='#'|-(x[1]=='b') instead of x[1]=='#'?1:(x[1]=='b'?-1:0) save some bytes too
    – Luis felipe De jesus Munoz
    Nov 8 at 14:39












  • @LuisfelipeDejesusMunoz Oh nice thanks! I can't believe I forgot about array expansion and adding an empty string
    – Skidsdev
    Nov 8 at 14:43










  • "If delta is negative, replace it with 2" sounds wrong. I think you need to take the difference modulo 12.
    – nwellnhof
    Nov 8 at 15:58










  • @nwellnhof In my tests, all major scales either had the correct deltas to begin with, or, if they spanned an octave, had one delta at -10 rather than 2. Replacing negative deltas fixes that. I don't think -10 % 12 == 2. Although come to think of it this might fail in some cases...
    – Skidsdev
    Nov 8 at 16:33


















up vote
3
down vote














Dart, 198 197 196 189 bytes



f(l){var i=0,j='',k,n=l.map((m){k=m.runes.first*2-130;k-=k>3?k>9?2:1:0;return m.length<2?k:m[1]=='#'?k+1:m[1]=='b'?k-1:k;}).toList();for(;++i<7;j+='${(n[i]-n[i-1])%12}');return'221222'==j;}


Try it online!



Loose port of the old Perl 6 answer https://codegolf.stackexchange.com/a/175522/64722



f(l){
var i=0,j='',k,
n=l.map((m){
k=m.runes.first*2-130;
k-=k>3?k>9?2:1:0;
return m.length<2?k:m[1]=='#'?k+1:m[1]=='b'?k-1:k;
}).toList();
for(;++i<7;j+='${(n[i]-n[i-1])%12}');
return'221222'==j;
}



  • -1 byte by using ternary operators for #/b

  • -1 byte by using ifs instead of ternaries for the scale shifts

  • -7 bytes thanks to @Kevin Cruijssen




Old version :




Dart, 210 bytes



f(l){var i=0,k=0,n={'C':0,'D':2,'E':4,'F':5,'G':7,'A':9,'B':11,'b':-1,'#':1},j='',y=[0,0];for(;++i<7;j+='${(y[0]-y[1])%12}')for(k=0;k<2;k++)y[k]=n[l[i-k][0]]+(l[i-k].length>1?n[l[i-k][1]]:0);return'221222'==j;}


Try it online!



Ungolfed:



f(l){
var i=0,k=0,n={'C':0,'D':2,'E':4,'F':5,'G':7,'A':9,'B':11,'b':-1,'#':1},j='',y=[0,0];
for(;++i<7;j+='${(y[0]-y[1])%12}')
for(k=0;k<2;k++)
y[k]=n[l[i-k][0]]+(l[i-k].length>1?n[l[i-k][1]]:0);

return'221222'==j;
}


A whole step is 2, a quarter is 1. Mod 12 in case you jump to a higher octave.
Iterates through all notes and computes the difference between the ith note and the i-1th note.
Concatenates the result and should expect 221222 (2 whole, 1 half, 3 wholes).




  • -2 bytes by not assigning 0 to k

  • -4 bytes by using j as a String and not a List

  • -6 bytes thanks to @Kevin Cruijssen by removing unnecessary clutter in loops






share|improve this answer























  • I don't know Dart, but parts are similar as Java. Therefore: changing i=1 to i=0 can reduce a byte by changing for(;i<7;i++) to for(;++i<7;). In addition, the brackets {} can be removed around that loop, by putting the j+=... inside the third part of the loop: for(;++i<7;j+='${(y[0]-y[1])%12}'). And one last thing is changing return j=='221222'; to return'221222'==j; to get rid of the space. -6 (210 bytes) after these modifications.
    – Kevin Cruijssen
    Nov 8 at 15:02












  • Thanks, didn't know about those tricks for the loops
    – Elcan
    Nov 8 at 15:28










  • Np. In your new 196-bytes version you can also golf it to 189 bytes by changing if(k>9)k--;if(k>3)k--; to k-=k>3?k>9?2:1:0; and k+=m.length<2?0:m[1]=='#'?1:m[1]=='b'?-1:0;return k; to return m.length<2?k:m[1]=='#'?k+1:m[1]=='b'?k-1:k;. :)
    – Kevin Cruijssen
    Nov 8 at 17:49










  • Damn, I still have a lot to learn it seems, thanks !
    – Elcan
    Nov 8 at 19:00










  • Well, I've been golfing for 2.5 years now, and even I get tips on things to golf all the time. :) It's pretty easy to miss something yourself initially, and with time you think about different ways to golf. :) Tips for golfing in <all languages> might be interesting to read through if you haven't yet. And some of the Tips for golfing in Java might also be applicable in Dart, since the golfs I did in your answers were based on my Java knowledge, since this is the first time I see Dart. ;)
    – Kevin Cruijssen
    Nov 8 at 20:38


















up vote
2
down vote














C (gcc), -DA=a[i] + 183 = 191 bytes





f(int*a){char s[9],b[9],h=0,i=0,j=0,d;for(;A;A==35?b[i-h++-1]++:A^98?(b[i-h]=A*13>>3):b[i-h++-1]--,i++);for(;j<7;d=(b[j]-b[j-1])%12,d=d<0?d+12:d,s[j++-1]=d+48);a=!strcmp(s,"221222");}


Try it online!



Based on the Perl answer.



Takes input as a wide string.



Ungolfed:



int f(int *a){
char s[9], b[9];
int h, i, j;
h = 0;
for(i = 0; a[i] != NULL; i++){
if(a[i] == '#'){
b[i-h-1] += 1;
h++;
}
else if(a[i] == 'b'){
b[i-1-h] -= 1;
h++;
}
else{
b[i-h] = (a[i] * 13) >> 3;
}
}
for(j = 1; j < 7; j++){
int d = (b[j] - b[j-1]) % 12;
d = d < 0? d + 12: d;
s[j-1] = d + '0';
}
return strcmp(s, "221222") == 0;
}





share|improve this answer























  • Suggest i-++h instead of i-h++-1
    – ceilingcat
    Nov 15 at 23:59


















up vote
2
down vote














Python 3, 175 136 134 114 112 bytes





def f(t):r=[ord(x[0])//.6+ord(x[1:]or'"')%13-8for x in t];return[(y-x)%12for x,y in zip(r,r[1:])]==[2,2,1,2,2,2]


Try it online!





An one-liner Python 3 implementation.



Thanks to @Arnauld for idea of calculate tones using division and modulo.

Thanks to @Jo King for -39 bytes.






share|improve this answer



















  • 1




    136 bytes
    – Jo King
    Nov 9 at 7:27










  • @JoKing Wow, thanks!
    – cobaltp
    Nov 9 at 7:43


















up vote
1
down vote













[Python] 269 202 bytes



Improvements from Jo King:



p=lambda z:"A BC D EF G".index(z[0])+"b #".index(z[1:]or' ')-1
def d(i,j):f=abs(p(i)-p(j));return min(f,12-f)
q=input().replace(' ','').split(',')
print([d(q[i],q[i+1])for i in range(6)]==[2,2,1,2,2,2])


Try it!



Ungolfed, with test driver:



tone = "A BC D EF G"   # tones in "piano" layout
adj = "b #" # accidentals

def note_pos(note):
if len(note) == 1:
note += ' '
n,a = note
return tone.index(n) + adj[a]

def note_diff(i, j):
x, y = note_pos(i), note_pos(j)
diff = abs(x-y)
return min(diff, 12-diff)

def is_scale(str):
seq = str.replace(' ','').split(',')
div = [note_diff(seq[i], seq[i+1]) for i in (0,1,2,3,4,5)]
return div == [2,2,1,2,2,2]

case = [
("C, D, E, F, G, A, B", True),
("C#, D#, E#, F#, G#, A#, B#", True),
("Db, Eb, F, Gb, Ab, Bb, C", True),
("D, E, Gb, G, A, Cb, C#", True),
("Eb, E#, G, G#, Bb, B#, D", True),

("C, D#, E, F, G, A, B", False),
("Db, Eb, F, Gb, Ab, B, C", False),
("G#, E, F, A, B, D#, C", False),
("C#, C#, E#, F#, G#, A#, B#", False),
("Eb, E#, Gb, G#, Bb, B#, D", False),
]

for test, result in case:
print(test + ' '*(30-len(test)), result, 't',
"valid" if is_scale(test) == result else "ERROR")





share|improve this answer























  • Yes, I see the white space -- still inculcated with too much PEP-8, I'm afraid. I apparently missed something; is an execution link required here?
    – Prune
    Nov 9 at 2:03






  • 1




    Though, if you want the link, 202 bytes with some quick golfing. You could definitely golf some more by changing to a different input format
    – Jo King
    Nov 9 at 2:28












  • Ah ... I'm too used to Python returning the final expression as the process value. Thanks for the pointers and hints.
    – Prune
    Nov 9 at 2:32










  • You can get 156 bytes if you switch to a function taking a list of strings. Also, TIO has an auto formatter in the link section that you can use
    – Jo King
    Nov 9 at 2:49










  • @JoKing, you're perfectly welcome to edit this answer or post your own; commenting with a link separates the improvements by one level.
    – Prune
    Nov 9 at 16:40


















up vote
1
down vote














Ruby, 109 bytes





->s{(0..11).any?{|t|s.map{|n|(w="Cef;DXg<E=Fhi>G j8A d9B:")[(w.index(""<<n.sum%107)/2-t)%12]}*''=='CfDX<=h'}}


Try it online!






share|improve this answer




























    up vote
    0
    down vote













    [Wolfram Language (Mathematica) + Music` package], 114 bytes



    I love music and found this interesting, but I was out playing real golf when this code golf opportunity came down the pike so my submission is a little tardy.



    I figured I'd try this a totally different way, utilizing some actual music knowledge. It turns out the music package of Mathematica knows the fundamental frequency of the named notes. First I convert the input string into sequence of named notes. Next, I take the ratios of each successive note and double any that are less than 2 (to account for octave shift). Then I compare these ratios to the ratios of the Ionian scale which has roughly a 6% frequency difference between half notes and 12% between full notes.



    More than half of the bytes spent here are to convert the input into named symbols.



    .06{2,2,1,2,2,2}+1==Round[Ratios[Symbol[#~~"0"]&/@StringReplace[# ,{"b"->"flat","#"->"sharp"}]]/.x_/;x<1->2x,.01]&


    Try it online!






    share|improve this answer





















      Your Answer





      StackExchange.ifUsing("editor", function () {
      return StackExchange.using("mathjaxEditing", function () {
      StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix) {
      StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
      });
      });
      }, "mathjax-editing");

      StackExchange.ifUsing("editor", function () {
      StackExchange.using("externalEditor", function () {
      StackExchange.using("snippets", function () {
      StackExchange.snippets.init();
      });
      });
      }, "code-snippets");

      StackExchange.ready(function() {
      var channelOptions = {
      tags: "".split(" "),
      id: "200"
      };
      initTagRenderer("".split(" "), "".split(" "), channelOptions);

      StackExchange.using("externalEditor", function() {
      // Have to fire editor after snippets, if snippets enabled
      if (StackExchange.settings.snippets.snippetsEnabled) {
      StackExchange.using("snippets", function() {
      createEditor();
      });
      }
      else {
      createEditor();
      }
      });

      function createEditor() {
      StackExchange.prepareEditor({
      heartbeatType: 'answer',
      convertImagesToLinks: false,
      noModals: true,
      showLowRepImageUploadWarning: true,
      reputationToPostImages: null,
      bindNavPrevention: true,
      postfix: "",
      imageUploader: {
      brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
      contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
      allowUrls: true
      },
      onDemand: true,
      discardSelector: ".discard-answer"
      ,immediatelyShowMarkdownHelp:true
      });


      }
      });














       

      draft saved


      draft discarded


















      StackExchange.ready(
      function () {
      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodegolf.stackexchange.com%2fquestions%2f175516%2fis-this-a-major-scale-or-equivalent%23new-answer', 'question_page');
      }
      );

      Post as a guest















      Required, but never shown

























      9 Answers
      9






      active

      oldest

      votes








      9 Answers
      9






      active

      oldest

      votes









      active

      oldest

      votes






      active

      oldest

      votes








      up vote
      11
      down vote














      Perl 6, 76 65 63 59 bytes



      -4 bytes thanks to Phil H





      {221222==[~] (.skip Z-$_)X%12}o*>>.&{13*.ord+>3+?/#/-?/b/}


      Try it online!



      Explanation



      *>>.&{ ... }  # Map notes to integers
      13*.ord # 13 * ASCII code: A=845 B=858 C=871 D=884 E=897 F=910 G=923
      +>3 # Right shift by 3: A=105 B=107 C=108 D=110 E=112 F=113 G=115
      # Subtracting 105 would yield A=0 B=2 C=3 D=5 E=7 F=8 G=10
      # but isn't necessary because we only need differences
      +?/#/ # Add 1 for '#'
      -?/b/ # Subtract 1 for 'b'

      { }o # Compose with block
      (.skip Z-$_) # Pairwise difference
      X%12 # modulo 12
      [~] # Join
      221222== # Equals 221222





      share|improve this answer























      • If you're going to do a pairwise difference and modulo 12, you don't need to subtract 105; it's just an offset. -4 chars: tio.run/…
        – Phil H
        Nov 8 at 16:46










      • @PhilH Yes, of course. Thanks!
        – nwellnhof
        Nov 8 at 16:53










      • That's a really clever way of mapping the notes to their relative values, +1 from me!
        – Sok
        Nov 9 at 15:44















      up vote
      11
      down vote














      Perl 6, 76 65 63 59 bytes



      -4 bytes thanks to Phil H





      {221222==[~] (.skip Z-$_)X%12}o*>>.&{13*.ord+>3+?/#/-?/b/}


      Try it online!



      Explanation



      *>>.&{ ... }  # Map notes to integers
      13*.ord # 13 * ASCII code: A=845 B=858 C=871 D=884 E=897 F=910 G=923
      +>3 # Right shift by 3: A=105 B=107 C=108 D=110 E=112 F=113 G=115
      # Subtracting 105 would yield A=0 B=2 C=3 D=5 E=7 F=8 G=10
      # but isn't necessary because we only need differences
      +?/#/ # Add 1 for '#'
      -?/b/ # Subtract 1 for 'b'

      { }o # Compose with block
      (.skip Z-$_) # Pairwise difference
      X%12 # modulo 12
      [~] # Join
      221222== # Equals 221222





      share|improve this answer























      • If you're going to do a pairwise difference and modulo 12, you don't need to subtract 105; it's just an offset. -4 chars: tio.run/…
        – Phil H
        Nov 8 at 16:46










      • @PhilH Yes, of course. Thanks!
        – nwellnhof
        Nov 8 at 16:53










      • That's a really clever way of mapping the notes to their relative values, +1 from me!
        – Sok
        Nov 9 at 15:44













      up vote
      11
      down vote










      up vote
      11
      down vote










      Perl 6, 76 65 63 59 bytes



      -4 bytes thanks to Phil H





      {221222==[~] (.skip Z-$_)X%12}o*>>.&{13*.ord+>3+?/#/-?/b/}


      Try it online!



      Explanation



      *>>.&{ ... }  # Map notes to integers
      13*.ord # 13 * ASCII code: A=845 B=858 C=871 D=884 E=897 F=910 G=923
      +>3 # Right shift by 3: A=105 B=107 C=108 D=110 E=112 F=113 G=115
      # Subtracting 105 would yield A=0 B=2 C=3 D=5 E=7 F=8 G=10
      # but isn't necessary because we only need differences
      +?/#/ # Add 1 for '#'
      -?/b/ # Subtract 1 for 'b'

      { }o # Compose with block
      (.skip Z-$_) # Pairwise difference
      X%12 # modulo 12
      [~] # Join
      221222== # Equals 221222





      share|improve this answer















      Perl 6, 76 65 63 59 bytes



      -4 bytes thanks to Phil H





      {221222==[~] (.skip Z-$_)X%12}o*>>.&{13*.ord+>3+?/#/-?/b/}


      Try it online!



      Explanation



      *>>.&{ ... }  # Map notes to integers
      13*.ord # 13 * ASCII code: A=845 B=858 C=871 D=884 E=897 F=910 G=923
      +>3 # Right shift by 3: A=105 B=107 C=108 D=110 E=112 F=113 G=115
      # Subtracting 105 would yield A=0 B=2 C=3 D=5 E=7 F=8 G=10
      # but isn't necessary because we only need differences
      +?/#/ # Add 1 for '#'
      -?/b/ # Subtract 1 for 'b'

      { }o # Compose with block
      (.skip Z-$_) # Pairwise difference
      X%12 # modulo 12
      [~] # Join
      221222== # Equals 221222






      share|improve this answer














      share|improve this answer



      share|improve this answer








      edited Nov 8 at 16:53

























      answered Nov 8 at 14:31









      nwellnhof

      5,9981122




      5,9981122












      • If you're going to do a pairwise difference and modulo 12, you don't need to subtract 105; it's just an offset. -4 chars: tio.run/…
        – Phil H
        Nov 8 at 16:46










      • @PhilH Yes, of course. Thanks!
        – nwellnhof
        Nov 8 at 16:53










      • That's a really clever way of mapping the notes to their relative values, +1 from me!
        – Sok
        Nov 9 at 15:44


















      • If you're going to do a pairwise difference and modulo 12, you don't need to subtract 105; it's just an offset. -4 chars: tio.run/…
        – Phil H
        Nov 8 at 16:46










      • @PhilH Yes, of course. Thanks!
        – nwellnhof
        Nov 8 at 16:53










      • That's a really clever way of mapping the notes to their relative values, +1 from me!
        – Sok
        Nov 9 at 15:44
















      If you're going to do a pairwise difference and modulo 12, you don't need to subtract 105; it's just an offset. -4 chars: tio.run/…
      – Phil H
      Nov 8 at 16:46




      If you're going to do a pairwise difference and modulo 12, you don't need to subtract 105; it's just an offset. -4 chars: tio.run/…
      – Phil H
      Nov 8 at 16:46












      @PhilH Yes, of course. Thanks!
      – nwellnhof
      Nov 8 at 16:53




      @PhilH Yes, of course. Thanks!
      – nwellnhof
      Nov 8 at 16:53












      That's a really clever way of mapping the notes to their relative values, +1 from me!
      – Sok
      Nov 9 at 15:44




      That's a really clever way of mapping the notes to their relative values, +1 from me!
      – Sok
      Nov 9 at 15:44










      up vote
      10
      down vote














      Node.js v10.9.0, 78 76 71 69 bytes



      a=>!a.some(n=>(a-(a=~([x,y]=Buffer(n),x/.6)-~y%61)+48)%12-2+!i--,i=3)


      Try it online!



      How?



      Each note $n$ is converted to a negative number in $[-118,-71]$ with:



      [x, y] = Buffer(n) // split n into two ASCII codes x and y
      ~(x / .6) // base value, using the ASCII code of the 1st character
      - ~y % 61 // +36 if the 2nd character is a '#' (ASCII code 35)
      // +38 if the 2nd character is a 'b' (ASCII code 98)
      // +1 if the 2nd character is undefined


      Which gives:



        n   | x  | x / 0.6 | ~(x / 0.6) | -~y % 61 | sum
      ------+----+---------+------------+----------+------
      "Ab" | 65 | 108.333 | -109 | 38 | -71
      "A" | 65 | 108.333 | -109 | 1 | -108
      "A#" | 65 | 108.333 | -109 | 36 | -73
      "Bb" | 66 | 110.000 | -111 | 38 | -73
      "B" | 66 | 110.000 | -111 | 1 | -110
      "B#" | 66 | 110.000 | -111 | 36 | -75
      "Cb" | 67 | 111.667 | -112 | 38 | -74
      "C" | 67 | 111.667 | -112 | 1 | -111
      "C#" | 67 | 111.667 | -112 | 36 | -76
      "Db" | 68 | 113.333 | -114 | 38 | -76
      "D" | 68 | 113.333 | -114 | 1 | -113
      "D#" | 68 | 113.333 | -114 | 36 | -78
      "Eb" | 69 | 115.000 | -116 | 38 | -78
      "E" | 69 | 115.000 | -116 | 1 | -115
      "E#" | 69 | 115.000 | -116 | 36 | -80
      "Fb" | 70 | 116.667 | -117 | 38 | -79
      "F" | 70 | 116.667 | -117 | 1 | -116
      "F#" | 70 | 116.667 | -117 | 36 | -81
      "Gb" | 71 | 118.333 | -119 | 38 | -81
      "G" | 71 | 118.333 | -119 | 1 | -118
      "G#" | 71 | 118.333 | -119 | 36 | -83


      We compute the pairwise differences modulo $12$ between these values.



      The lowest possible difference between 2 notes is $-47$, so it's enough to add $4times12=48$ before applying the modulo to make sure that we get a positive result.



      Because we apply a modulo $12$, the offset produced by a '#' is actually $36 bmod 12 = 0$ semitone, while the offset produced by a 'b' is $38 bmod 12 = 2$ semitones.



      We are reusing the input variable $a$ to store the previous value, so the first iteration just generates $text{NaN}$.



      For a major scale, we should get $[ text{NaN}, 2, 2, 1, 2, 2, 2 ]$.



      We use the counter $i$ to compare the 4th value with $1$ rather than $2$.






      share|improve this answer























      • Great approach, much more interesting than my answer
        – Skidsdev
        10 hours ago















      up vote
      10
      down vote














      Node.js v10.9.0, 78 76 71 69 bytes



      a=>!a.some(n=>(a-(a=~([x,y]=Buffer(n),x/.6)-~y%61)+48)%12-2+!i--,i=3)


      Try it online!



      How?



      Each note $n$ is converted to a negative number in $[-118,-71]$ with:



      [x, y] = Buffer(n) // split n into two ASCII codes x and y
      ~(x / .6) // base value, using the ASCII code of the 1st character
      - ~y % 61 // +36 if the 2nd character is a '#' (ASCII code 35)
      // +38 if the 2nd character is a 'b' (ASCII code 98)
      // +1 if the 2nd character is undefined


      Which gives:



        n   | x  | x / 0.6 | ~(x / 0.6) | -~y % 61 | sum
      ------+----+---------+------------+----------+------
      "Ab" | 65 | 108.333 | -109 | 38 | -71
      "A" | 65 | 108.333 | -109 | 1 | -108
      "A#" | 65 | 108.333 | -109 | 36 | -73
      "Bb" | 66 | 110.000 | -111 | 38 | -73
      "B" | 66 | 110.000 | -111 | 1 | -110
      "B#" | 66 | 110.000 | -111 | 36 | -75
      "Cb" | 67 | 111.667 | -112 | 38 | -74
      "C" | 67 | 111.667 | -112 | 1 | -111
      "C#" | 67 | 111.667 | -112 | 36 | -76
      "Db" | 68 | 113.333 | -114 | 38 | -76
      "D" | 68 | 113.333 | -114 | 1 | -113
      "D#" | 68 | 113.333 | -114 | 36 | -78
      "Eb" | 69 | 115.000 | -116 | 38 | -78
      "E" | 69 | 115.000 | -116 | 1 | -115
      "E#" | 69 | 115.000 | -116 | 36 | -80
      "Fb" | 70 | 116.667 | -117 | 38 | -79
      "F" | 70 | 116.667 | -117 | 1 | -116
      "F#" | 70 | 116.667 | -117 | 36 | -81
      "Gb" | 71 | 118.333 | -119 | 38 | -81
      "G" | 71 | 118.333 | -119 | 1 | -118
      "G#" | 71 | 118.333 | -119 | 36 | -83


      We compute the pairwise differences modulo $12$ between these values.



      The lowest possible difference between 2 notes is $-47$, so it's enough to add $4times12=48$ before applying the modulo to make sure that we get a positive result.



      Because we apply a modulo $12$, the offset produced by a '#' is actually $36 bmod 12 = 0$ semitone, while the offset produced by a 'b' is $38 bmod 12 = 2$ semitones.



      We are reusing the input variable $a$ to store the previous value, so the first iteration just generates $text{NaN}$.



      For a major scale, we should get $[ text{NaN}, 2, 2, 1, 2, 2, 2 ]$.



      We use the counter $i$ to compare the 4th value with $1$ rather than $2$.






      share|improve this answer























      • Great approach, much more interesting than my answer
        – Skidsdev
        10 hours ago













      up vote
      10
      down vote










      up vote
      10
      down vote










      Node.js v10.9.0, 78 76 71 69 bytes



      a=>!a.some(n=>(a-(a=~([x,y]=Buffer(n),x/.6)-~y%61)+48)%12-2+!i--,i=3)


      Try it online!



      How?



      Each note $n$ is converted to a negative number in $[-118,-71]$ with:



      [x, y] = Buffer(n) // split n into two ASCII codes x and y
      ~(x / .6) // base value, using the ASCII code of the 1st character
      - ~y % 61 // +36 if the 2nd character is a '#' (ASCII code 35)
      // +38 if the 2nd character is a 'b' (ASCII code 98)
      // +1 if the 2nd character is undefined


      Which gives:



        n   | x  | x / 0.6 | ~(x / 0.6) | -~y % 61 | sum
      ------+----+---------+------------+----------+------
      "Ab" | 65 | 108.333 | -109 | 38 | -71
      "A" | 65 | 108.333 | -109 | 1 | -108
      "A#" | 65 | 108.333 | -109 | 36 | -73
      "Bb" | 66 | 110.000 | -111 | 38 | -73
      "B" | 66 | 110.000 | -111 | 1 | -110
      "B#" | 66 | 110.000 | -111 | 36 | -75
      "Cb" | 67 | 111.667 | -112 | 38 | -74
      "C" | 67 | 111.667 | -112 | 1 | -111
      "C#" | 67 | 111.667 | -112 | 36 | -76
      "Db" | 68 | 113.333 | -114 | 38 | -76
      "D" | 68 | 113.333 | -114 | 1 | -113
      "D#" | 68 | 113.333 | -114 | 36 | -78
      "Eb" | 69 | 115.000 | -116 | 38 | -78
      "E" | 69 | 115.000 | -116 | 1 | -115
      "E#" | 69 | 115.000 | -116 | 36 | -80
      "Fb" | 70 | 116.667 | -117 | 38 | -79
      "F" | 70 | 116.667 | -117 | 1 | -116
      "F#" | 70 | 116.667 | -117 | 36 | -81
      "Gb" | 71 | 118.333 | -119 | 38 | -81
      "G" | 71 | 118.333 | -119 | 1 | -118
      "G#" | 71 | 118.333 | -119 | 36 | -83


      We compute the pairwise differences modulo $12$ between these values.



      The lowest possible difference between 2 notes is $-47$, so it's enough to add $4times12=48$ before applying the modulo to make sure that we get a positive result.



      Because we apply a modulo $12$, the offset produced by a '#' is actually $36 bmod 12 = 0$ semitone, while the offset produced by a 'b' is $38 bmod 12 = 2$ semitones.



      We are reusing the input variable $a$ to store the previous value, so the first iteration just generates $text{NaN}$.



      For a major scale, we should get $[ text{NaN}, 2, 2, 1, 2, 2, 2 ]$.



      We use the counter $i$ to compare the 4th value with $1$ rather than $2$.






      share|improve this answer















      Node.js v10.9.0, 78 76 71 69 bytes



      a=>!a.some(n=>(a-(a=~([x,y]=Buffer(n),x/.6)-~y%61)+48)%12-2+!i--,i=3)


      Try it online!



      How?



      Each note $n$ is converted to a negative number in $[-118,-71]$ with:



      [x, y] = Buffer(n) // split n into two ASCII codes x and y
      ~(x / .6) // base value, using the ASCII code of the 1st character
      - ~y % 61 // +36 if the 2nd character is a '#' (ASCII code 35)
      // +38 if the 2nd character is a 'b' (ASCII code 98)
      // +1 if the 2nd character is undefined


      Which gives:



        n   | x  | x / 0.6 | ~(x / 0.6) | -~y % 61 | sum
      ------+----+---------+------------+----------+------
      "Ab" | 65 | 108.333 | -109 | 38 | -71
      "A" | 65 | 108.333 | -109 | 1 | -108
      "A#" | 65 | 108.333 | -109 | 36 | -73
      "Bb" | 66 | 110.000 | -111 | 38 | -73
      "B" | 66 | 110.000 | -111 | 1 | -110
      "B#" | 66 | 110.000 | -111 | 36 | -75
      "Cb" | 67 | 111.667 | -112 | 38 | -74
      "C" | 67 | 111.667 | -112 | 1 | -111
      "C#" | 67 | 111.667 | -112 | 36 | -76
      "Db" | 68 | 113.333 | -114 | 38 | -76
      "D" | 68 | 113.333 | -114 | 1 | -113
      "D#" | 68 | 113.333 | -114 | 36 | -78
      "Eb" | 69 | 115.000 | -116 | 38 | -78
      "E" | 69 | 115.000 | -116 | 1 | -115
      "E#" | 69 | 115.000 | -116 | 36 | -80
      "Fb" | 70 | 116.667 | -117 | 38 | -79
      "F" | 70 | 116.667 | -117 | 1 | -116
      "F#" | 70 | 116.667 | -117 | 36 | -81
      "Gb" | 71 | 118.333 | -119 | 38 | -81
      "G" | 71 | 118.333 | -119 | 1 | -118
      "G#" | 71 | 118.333 | -119 | 36 | -83


      We compute the pairwise differences modulo $12$ between these values.



      The lowest possible difference between 2 notes is $-47$, so it's enough to add $4times12=48$ before applying the modulo to make sure that we get a positive result.



      Because we apply a modulo $12$, the offset produced by a '#' is actually $36 bmod 12 = 0$ semitone, while the offset produced by a 'b' is $38 bmod 12 = 2$ semitones.



      We are reusing the input variable $a$ to store the previous value, so the first iteration just generates $text{NaN}$.



      For a major scale, we should get $[ text{NaN}, 2, 2, 1, 2, 2, 2 ]$.



      We use the counter $i$ to compare the 4th value with $1$ rather than $2$.







      share|improve this answer














      share|improve this answer



      share|improve this answer








      edited Nov 9 at 8:03

























      answered Nov 8 at 17:46









      Arnauld

      69.1k584292




      69.1k584292












      • Great approach, much more interesting than my answer
        – Skidsdev
        10 hours ago


















      • Great approach, much more interesting than my answer
        – Skidsdev
        10 hours ago
















      Great approach, much more interesting than my answer
      – Skidsdev
      10 hours ago




      Great approach, much more interesting than my answer
      – Skidsdev
      10 hours ago










      up vote
      4
      down vote














      JavaScript (Node.js), 150 131 125 bytes





      l=>(l=l.map(x=>'C0D0EF0G0A0B'.search(x[0])+(x[1]=='#'|-(x[1]=='b')))).slice(1).map((n,i)=>(b=n-l[i])<0?2:b)+""=='2,2,1,2,2,2'


      Try it online!



      -19 bytes thanks to Luis felipe
      -6 bytes thanks to Shaggy



      Ungolfed:



      function isMajor(l) {
      // Get tone index of each entry
      let array = l.map(function (x) {
      // Use this to get indices of each note, using 0s as spacers for sharp keys
      let tones = 'C0D0EF0G0A0B';
      // Get the index of the letter component. EG D = 2, F = 5
      let tone = tones.search(x[0]);
      // Add 1 semitone if note is sharp
      // Use bool to number coercion to make this shorter
      tone += x[1] == '#' | -(x[1]=='b');
      });
      // Calculate deltas
      let deltas = array.slice(1).map(function (n,i) {
      // If delta is negative, replace it with 2
      // This accounts for octaves
      if (n - array[i] < 0) return 2;
      // Otherwise return the delta
      return n - array[i];
      });
      // Pseudo array-comparison
      return deltas+"" == '2,2,1,2,2,2';
      }





      share|improve this answer



















      • 1




        [...'C0D0EF0G0A0B'] instead of 'C0D0EF0G0A0B'.split('') and +"" instead of .toString() to save some bytes
        – Luis felipe De jesus Munoz
        Nov 8 at 14:36










      • x[1]=='#'|-(x[1]=='b') instead of x[1]=='#'?1:(x[1]=='b'?-1:0) save some bytes too
        – Luis felipe De jesus Munoz
        Nov 8 at 14:39












      • @LuisfelipeDejesusMunoz Oh nice thanks! I can't believe I forgot about array expansion and adding an empty string
        – Skidsdev
        Nov 8 at 14:43










      • "If delta is negative, replace it with 2" sounds wrong. I think you need to take the difference modulo 12.
        – nwellnhof
        Nov 8 at 15:58










      • @nwellnhof In my tests, all major scales either had the correct deltas to begin with, or, if they spanned an octave, had one delta at -10 rather than 2. Replacing negative deltas fixes that. I don't think -10 % 12 == 2. Although come to think of it this might fail in some cases...
        – Skidsdev
        Nov 8 at 16:33















      up vote
      4
      down vote














      JavaScript (Node.js), 150 131 125 bytes





      l=>(l=l.map(x=>'C0D0EF0G0A0B'.search(x[0])+(x[1]=='#'|-(x[1]=='b')))).slice(1).map((n,i)=>(b=n-l[i])<0?2:b)+""=='2,2,1,2,2,2'


      Try it online!



      -19 bytes thanks to Luis felipe
      -6 bytes thanks to Shaggy



      Ungolfed:



      function isMajor(l) {
      // Get tone index of each entry
      let array = l.map(function (x) {
      // Use this to get indices of each note, using 0s as spacers for sharp keys
      let tones = 'C0D0EF0G0A0B';
      // Get the index of the letter component. EG D = 2, F = 5
      let tone = tones.search(x[0]);
      // Add 1 semitone if note is sharp
      // Use bool to number coercion to make this shorter
      tone += x[1] == '#' | -(x[1]=='b');
      });
      // Calculate deltas
      let deltas = array.slice(1).map(function (n,i) {
      // If delta is negative, replace it with 2
      // This accounts for octaves
      if (n - array[i] < 0) return 2;
      // Otherwise return the delta
      return n - array[i];
      });
      // Pseudo array-comparison
      return deltas+"" == '2,2,1,2,2,2';
      }





      share|improve this answer



















      • 1




        [...'C0D0EF0G0A0B'] instead of 'C0D0EF0G0A0B'.split('') and +"" instead of .toString() to save some bytes
        – Luis felipe De jesus Munoz
        Nov 8 at 14:36










      • x[1]=='#'|-(x[1]=='b') instead of x[1]=='#'?1:(x[1]=='b'?-1:0) save some bytes too
        – Luis felipe De jesus Munoz
        Nov 8 at 14:39












      • @LuisfelipeDejesusMunoz Oh nice thanks! I can't believe I forgot about array expansion and adding an empty string
        – Skidsdev
        Nov 8 at 14:43










      • "If delta is negative, replace it with 2" sounds wrong. I think you need to take the difference modulo 12.
        – nwellnhof
        Nov 8 at 15:58










      • @nwellnhof In my tests, all major scales either had the correct deltas to begin with, or, if they spanned an octave, had one delta at -10 rather than 2. Replacing negative deltas fixes that. I don't think -10 % 12 == 2. Although come to think of it this might fail in some cases...
        – Skidsdev
        Nov 8 at 16:33













      up vote
      4
      down vote










      up vote
      4
      down vote










      JavaScript (Node.js), 150 131 125 bytes





      l=>(l=l.map(x=>'C0D0EF0G0A0B'.search(x[0])+(x[1]=='#'|-(x[1]=='b')))).slice(1).map((n,i)=>(b=n-l[i])<0?2:b)+""=='2,2,1,2,2,2'


      Try it online!



      -19 bytes thanks to Luis felipe
      -6 bytes thanks to Shaggy



      Ungolfed:



      function isMajor(l) {
      // Get tone index of each entry
      let array = l.map(function (x) {
      // Use this to get indices of each note, using 0s as spacers for sharp keys
      let tones = 'C0D0EF0G0A0B';
      // Get the index of the letter component. EG D = 2, F = 5
      let tone = tones.search(x[0]);
      // Add 1 semitone if note is sharp
      // Use bool to number coercion to make this shorter
      tone += x[1] == '#' | -(x[1]=='b');
      });
      // Calculate deltas
      let deltas = array.slice(1).map(function (n,i) {
      // If delta is negative, replace it with 2
      // This accounts for octaves
      if (n - array[i] < 0) return 2;
      // Otherwise return the delta
      return n - array[i];
      });
      // Pseudo array-comparison
      return deltas+"" == '2,2,1,2,2,2';
      }





      share|improve this answer















      JavaScript (Node.js), 150 131 125 bytes





      l=>(l=l.map(x=>'C0D0EF0G0A0B'.search(x[0])+(x[1]=='#'|-(x[1]=='b')))).slice(1).map((n,i)=>(b=n-l[i])<0?2:b)+""=='2,2,1,2,2,2'


      Try it online!



      -19 bytes thanks to Luis felipe
      -6 bytes thanks to Shaggy



      Ungolfed:



      function isMajor(l) {
      // Get tone index of each entry
      let array = l.map(function (x) {
      // Use this to get indices of each note, using 0s as spacers for sharp keys
      let tones = 'C0D0EF0G0A0B';
      // Get the index of the letter component. EG D = 2, F = 5
      let tone = tones.search(x[0]);
      // Add 1 semitone if note is sharp
      // Use bool to number coercion to make this shorter
      tone += x[1] == '#' | -(x[1]=='b');
      });
      // Calculate deltas
      let deltas = array.slice(1).map(function (n,i) {
      // If delta is negative, replace it with 2
      // This accounts for octaves
      if (n - array[i] < 0) return 2;
      // Otherwise return the delta
      return n - array[i];
      });
      // Pseudo array-comparison
      return deltas+"" == '2,2,1,2,2,2';
      }






      share|improve this answer














      share|improve this answer



      share|improve this answer








      edited Nov 9 at 18:18

























      answered Nov 8 at 14:32









      Skidsdev

      5,9132664




      5,9132664








      • 1




        [...'C0D0EF0G0A0B'] instead of 'C0D0EF0G0A0B'.split('') and +"" instead of .toString() to save some bytes
        – Luis felipe De jesus Munoz
        Nov 8 at 14:36










      • x[1]=='#'|-(x[1]=='b') instead of x[1]=='#'?1:(x[1]=='b'?-1:0) save some bytes too
        – Luis felipe De jesus Munoz
        Nov 8 at 14:39












      • @LuisfelipeDejesusMunoz Oh nice thanks! I can't believe I forgot about array expansion and adding an empty string
        – Skidsdev
        Nov 8 at 14:43










      • "If delta is negative, replace it with 2" sounds wrong. I think you need to take the difference modulo 12.
        – nwellnhof
        Nov 8 at 15:58










      • @nwellnhof In my tests, all major scales either had the correct deltas to begin with, or, if they spanned an octave, had one delta at -10 rather than 2. Replacing negative deltas fixes that. I don't think -10 % 12 == 2. Although come to think of it this might fail in some cases...
        – Skidsdev
        Nov 8 at 16:33














      • 1




        [...'C0D0EF0G0A0B'] instead of 'C0D0EF0G0A0B'.split('') and +"" instead of .toString() to save some bytes
        – Luis felipe De jesus Munoz
        Nov 8 at 14:36










      • x[1]=='#'|-(x[1]=='b') instead of x[1]=='#'?1:(x[1]=='b'?-1:0) save some bytes too
        – Luis felipe De jesus Munoz
        Nov 8 at 14:39












      • @LuisfelipeDejesusMunoz Oh nice thanks! I can't believe I forgot about array expansion and adding an empty string
        – Skidsdev
        Nov 8 at 14:43










      • "If delta is negative, replace it with 2" sounds wrong. I think you need to take the difference modulo 12.
        – nwellnhof
        Nov 8 at 15:58










      • @nwellnhof In my tests, all major scales either had the correct deltas to begin with, or, if they spanned an octave, had one delta at -10 rather than 2. Replacing negative deltas fixes that. I don't think -10 % 12 == 2. Although come to think of it this might fail in some cases...
        – Skidsdev
        Nov 8 at 16:33








      1




      1




      [...'C0D0EF0G0A0B'] instead of 'C0D0EF0G0A0B'.split('') and +"" instead of .toString() to save some bytes
      – Luis felipe De jesus Munoz
      Nov 8 at 14:36




      [...'C0D0EF0G0A0B'] instead of 'C0D0EF0G0A0B'.split('') and +"" instead of .toString() to save some bytes
      – Luis felipe De jesus Munoz
      Nov 8 at 14:36












      x[1]=='#'|-(x[1]=='b') instead of x[1]=='#'?1:(x[1]=='b'?-1:0) save some bytes too
      – Luis felipe De jesus Munoz
      Nov 8 at 14:39






      x[1]=='#'|-(x[1]=='b') instead of x[1]=='#'?1:(x[1]=='b'?-1:0) save some bytes too
      – Luis felipe De jesus Munoz
      Nov 8 at 14:39














      @LuisfelipeDejesusMunoz Oh nice thanks! I can't believe I forgot about array expansion and adding an empty string
      – Skidsdev
      Nov 8 at 14:43




      @LuisfelipeDejesusMunoz Oh nice thanks! I can't believe I forgot about array expansion and adding an empty string
      – Skidsdev
      Nov 8 at 14:43












      "If delta is negative, replace it with 2" sounds wrong. I think you need to take the difference modulo 12.
      – nwellnhof
      Nov 8 at 15:58




      "If delta is negative, replace it with 2" sounds wrong. I think you need to take the difference modulo 12.
      – nwellnhof
      Nov 8 at 15:58












      @nwellnhof In my tests, all major scales either had the correct deltas to begin with, or, if they spanned an octave, had one delta at -10 rather than 2. Replacing negative deltas fixes that. I don't think -10 % 12 == 2. Although come to think of it this might fail in some cases...
      – Skidsdev
      Nov 8 at 16:33




      @nwellnhof In my tests, all major scales either had the correct deltas to begin with, or, if they spanned an octave, had one delta at -10 rather than 2. Replacing negative deltas fixes that. I don't think -10 % 12 == 2. Although come to think of it this might fail in some cases...
      – Skidsdev
      Nov 8 at 16:33










      up vote
      3
      down vote














      Dart, 198 197 196 189 bytes



      f(l){var i=0,j='',k,n=l.map((m){k=m.runes.first*2-130;k-=k>3?k>9?2:1:0;return m.length<2?k:m[1]=='#'?k+1:m[1]=='b'?k-1:k;}).toList();for(;++i<7;j+='${(n[i]-n[i-1])%12}');return'221222'==j;}


      Try it online!



      Loose port of the old Perl 6 answer https://codegolf.stackexchange.com/a/175522/64722



      f(l){
      var i=0,j='',k,
      n=l.map((m){
      k=m.runes.first*2-130;
      k-=k>3?k>9?2:1:0;
      return m.length<2?k:m[1]=='#'?k+1:m[1]=='b'?k-1:k;
      }).toList();
      for(;++i<7;j+='${(n[i]-n[i-1])%12}');
      return'221222'==j;
      }



      • -1 byte by using ternary operators for #/b

      • -1 byte by using ifs instead of ternaries for the scale shifts

      • -7 bytes thanks to @Kevin Cruijssen




      Old version :




      Dart, 210 bytes



      f(l){var i=0,k=0,n={'C':0,'D':2,'E':4,'F':5,'G':7,'A':9,'B':11,'b':-1,'#':1},j='',y=[0,0];for(;++i<7;j+='${(y[0]-y[1])%12}')for(k=0;k<2;k++)y[k]=n[l[i-k][0]]+(l[i-k].length>1?n[l[i-k][1]]:0);return'221222'==j;}


      Try it online!



      Ungolfed:



      f(l){
      var i=0,k=0,n={'C':0,'D':2,'E':4,'F':5,'G':7,'A':9,'B':11,'b':-1,'#':1},j='',y=[0,0];
      for(;++i<7;j+='${(y[0]-y[1])%12}')
      for(k=0;k<2;k++)
      y[k]=n[l[i-k][0]]+(l[i-k].length>1?n[l[i-k][1]]:0);

      return'221222'==j;
      }


      A whole step is 2, a quarter is 1. Mod 12 in case you jump to a higher octave.
      Iterates through all notes and computes the difference between the ith note and the i-1th note.
      Concatenates the result and should expect 221222 (2 whole, 1 half, 3 wholes).




      • -2 bytes by not assigning 0 to k

      • -4 bytes by using j as a String and not a List

      • -6 bytes thanks to @Kevin Cruijssen by removing unnecessary clutter in loops






      share|improve this answer























      • I don't know Dart, but parts are similar as Java. Therefore: changing i=1 to i=0 can reduce a byte by changing for(;i<7;i++) to for(;++i<7;). In addition, the brackets {} can be removed around that loop, by putting the j+=... inside the third part of the loop: for(;++i<7;j+='${(y[0]-y[1])%12}'). And one last thing is changing return j=='221222'; to return'221222'==j; to get rid of the space. -6 (210 bytes) after these modifications.
        – Kevin Cruijssen
        Nov 8 at 15:02












      • Thanks, didn't know about those tricks for the loops
        – Elcan
        Nov 8 at 15:28










      • Np. In your new 196-bytes version you can also golf it to 189 bytes by changing if(k>9)k--;if(k>3)k--; to k-=k>3?k>9?2:1:0; and k+=m.length<2?0:m[1]=='#'?1:m[1]=='b'?-1:0;return k; to return m.length<2?k:m[1]=='#'?k+1:m[1]=='b'?k-1:k;. :)
        – Kevin Cruijssen
        Nov 8 at 17:49










      • Damn, I still have a lot to learn it seems, thanks !
        – Elcan
        Nov 8 at 19:00










      • Well, I've been golfing for 2.5 years now, and even I get tips on things to golf all the time. :) It's pretty easy to miss something yourself initially, and with time you think about different ways to golf. :) Tips for golfing in <all languages> might be interesting to read through if you haven't yet. And some of the Tips for golfing in Java might also be applicable in Dart, since the golfs I did in your answers were based on my Java knowledge, since this is the first time I see Dart. ;)
        – Kevin Cruijssen
        Nov 8 at 20:38















      up vote
      3
      down vote














      Dart, 198 197 196 189 bytes



      f(l){var i=0,j='',k,n=l.map((m){k=m.runes.first*2-130;k-=k>3?k>9?2:1:0;return m.length<2?k:m[1]=='#'?k+1:m[1]=='b'?k-1:k;}).toList();for(;++i<7;j+='${(n[i]-n[i-1])%12}');return'221222'==j;}


      Try it online!



      Loose port of the old Perl 6 answer https://codegolf.stackexchange.com/a/175522/64722



      f(l){
      var i=0,j='',k,
      n=l.map((m){
      k=m.runes.first*2-130;
      k-=k>3?k>9?2:1:0;
      return m.length<2?k:m[1]=='#'?k+1:m[1]=='b'?k-1:k;
      }).toList();
      for(;++i<7;j+='${(n[i]-n[i-1])%12}');
      return'221222'==j;
      }



      • -1 byte by using ternary operators for #/b

      • -1 byte by using ifs instead of ternaries for the scale shifts

      • -7 bytes thanks to @Kevin Cruijssen




      Old version :




      Dart, 210 bytes



      f(l){var i=0,k=0,n={'C':0,'D':2,'E':4,'F':5,'G':7,'A':9,'B':11,'b':-1,'#':1},j='',y=[0,0];for(;++i<7;j+='${(y[0]-y[1])%12}')for(k=0;k<2;k++)y[k]=n[l[i-k][0]]+(l[i-k].length>1?n[l[i-k][1]]:0);return'221222'==j;}


      Try it online!



      Ungolfed:



      f(l){
      var i=0,k=0,n={'C':0,'D':2,'E':4,'F':5,'G':7,'A':9,'B':11,'b':-1,'#':1},j='',y=[0,0];
      for(;++i<7;j+='${(y[0]-y[1])%12}')
      for(k=0;k<2;k++)
      y[k]=n[l[i-k][0]]+(l[i-k].length>1?n[l[i-k][1]]:0);

      return'221222'==j;
      }


      A whole step is 2, a quarter is 1. Mod 12 in case you jump to a higher octave.
      Iterates through all notes and computes the difference between the ith note and the i-1th note.
      Concatenates the result and should expect 221222 (2 whole, 1 half, 3 wholes).




      • -2 bytes by not assigning 0 to k

      • -4 bytes by using j as a String and not a List

      • -6 bytes thanks to @Kevin Cruijssen by removing unnecessary clutter in loops






      share|improve this answer























      • I don't know Dart, but parts are similar as Java. Therefore: changing i=1 to i=0 can reduce a byte by changing for(;i<7;i++) to for(;++i<7;). In addition, the brackets {} can be removed around that loop, by putting the j+=... inside the third part of the loop: for(;++i<7;j+='${(y[0]-y[1])%12}'). And one last thing is changing return j=='221222'; to return'221222'==j; to get rid of the space. -6 (210 bytes) after these modifications.
        – Kevin Cruijssen
        Nov 8 at 15:02












      • Thanks, didn't know about those tricks for the loops
        – Elcan
        Nov 8 at 15:28










      • Np. In your new 196-bytes version you can also golf it to 189 bytes by changing if(k>9)k--;if(k>3)k--; to k-=k>3?k>9?2:1:0; and k+=m.length<2?0:m[1]=='#'?1:m[1]=='b'?-1:0;return k; to return m.length<2?k:m[1]=='#'?k+1:m[1]=='b'?k-1:k;. :)
        – Kevin Cruijssen
        Nov 8 at 17:49










      • Damn, I still have a lot to learn it seems, thanks !
        – Elcan
        Nov 8 at 19:00










      • Well, I've been golfing for 2.5 years now, and even I get tips on things to golf all the time. :) It's pretty easy to miss something yourself initially, and with time you think about different ways to golf. :) Tips for golfing in <all languages> might be interesting to read through if you haven't yet. And some of the Tips for golfing in Java might also be applicable in Dart, since the golfs I did in your answers were based on my Java knowledge, since this is the first time I see Dart. ;)
        – Kevin Cruijssen
        Nov 8 at 20:38













      up vote
      3
      down vote










      up vote
      3
      down vote










      Dart, 198 197 196 189 bytes



      f(l){var i=0,j='',k,n=l.map((m){k=m.runes.first*2-130;k-=k>3?k>9?2:1:0;return m.length<2?k:m[1]=='#'?k+1:m[1]=='b'?k-1:k;}).toList();for(;++i<7;j+='${(n[i]-n[i-1])%12}');return'221222'==j;}


      Try it online!



      Loose port of the old Perl 6 answer https://codegolf.stackexchange.com/a/175522/64722



      f(l){
      var i=0,j='',k,
      n=l.map((m){
      k=m.runes.first*2-130;
      k-=k>3?k>9?2:1:0;
      return m.length<2?k:m[1]=='#'?k+1:m[1]=='b'?k-1:k;
      }).toList();
      for(;++i<7;j+='${(n[i]-n[i-1])%12}');
      return'221222'==j;
      }



      • -1 byte by using ternary operators for #/b

      • -1 byte by using ifs instead of ternaries for the scale shifts

      • -7 bytes thanks to @Kevin Cruijssen




      Old version :




      Dart, 210 bytes



      f(l){var i=0,k=0,n={'C':0,'D':2,'E':4,'F':5,'G':7,'A':9,'B':11,'b':-1,'#':1},j='',y=[0,0];for(;++i<7;j+='${(y[0]-y[1])%12}')for(k=0;k<2;k++)y[k]=n[l[i-k][0]]+(l[i-k].length>1?n[l[i-k][1]]:0);return'221222'==j;}


      Try it online!



      Ungolfed:



      f(l){
      var i=0,k=0,n={'C':0,'D':2,'E':4,'F':5,'G':7,'A':9,'B':11,'b':-1,'#':1},j='',y=[0,0];
      for(;++i<7;j+='${(y[0]-y[1])%12}')
      for(k=0;k<2;k++)
      y[k]=n[l[i-k][0]]+(l[i-k].length>1?n[l[i-k][1]]:0);

      return'221222'==j;
      }


      A whole step is 2, a quarter is 1. Mod 12 in case you jump to a higher octave.
      Iterates through all notes and computes the difference between the ith note and the i-1th note.
      Concatenates the result and should expect 221222 (2 whole, 1 half, 3 wholes).




      • -2 bytes by not assigning 0 to k

      • -4 bytes by using j as a String and not a List

      • -6 bytes thanks to @Kevin Cruijssen by removing unnecessary clutter in loops






      share|improve this answer















      Dart, 198 197 196 189 bytes



      f(l){var i=0,j='',k,n=l.map((m){k=m.runes.first*2-130;k-=k>3?k>9?2:1:0;return m.length<2?k:m[1]=='#'?k+1:m[1]=='b'?k-1:k;}).toList();for(;++i<7;j+='${(n[i]-n[i-1])%12}');return'221222'==j;}


      Try it online!



      Loose port of the old Perl 6 answer https://codegolf.stackexchange.com/a/175522/64722



      f(l){
      var i=0,j='',k,
      n=l.map((m){
      k=m.runes.first*2-130;
      k-=k>3?k>9?2:1:0;
      return m.length<2?k:m[1]=='#'?k+1:m[1]=='b'?k-1:k;
      }).toList();
      for(;++i<7;j+='${(n[i]-n[i-1])%12}');
      return'221222'==j;
      }



      • -1 byte by using ternary operators for #/b

      • -1 byte by using ifs instead of ternaries for the scale shifts

      • -7 bytes thanks to @Kevin Cruijssen




      Old version :




      Dart, 210 bytes



      f(l){var i=0,k=0,n={'C':0,'D':2,'E':4,'F':5,'G':7,'A':9,'B':11,'b':-1,'#':1},j='',y=[0,0];for(;++i<7;j+='${(y[0]-y[1])%12}')for(k=0;k<2;k++)y[k]=n[l[i-k][0]]+(l[i-k].length>1?n[l[i-k][1]]:0);return'221222'==j;}


      Try it online!



      Ungolfed:



      f(l){
      var i=0,k=0,n={'C':0,'D':2,'E':4,'F':5,'G':7,'A':9,'B':11,'b':-1,'#':1},j='',y=[0,0];
      for(;++i<7;j+='${(y[0]-y[1])%12}')
      for(k=0;k<2;k++)
      y[k]=n[l[i-k][0]]+(l[i-k].length>1?n[l[i-k][1]]:0);

      return'221222'==j;
      }


      A whole step is 2, a quarter is 1. Mod 12 in case you jump to a higher octave.
      Iterates through all notes and computes the difference between the ith note and the i-1th note.
      Concatenates the result and should expect 221222 (2 whole, 1 half, 3 wholes).




      • -2 bytes by not assigning 0 to k

      • -4 bytes by using j as a String and not a List

      • -6 bytes thanks to @Kevin Cruijssen by removing unnecessary clutter in loops







      share|improve this answer














      share|improve this answer



      share|improve this answer








      edited Nov 9 at 12:47

























      answered Nov 8 at 14:38









      Elcan

      27115




      27115












      • I don't know Dart, but parts are similar as Java. Therefore: changing i=1 to i=0 can reduce a byte by changing for(;i<7;i++) to for(;++i<7;). In addition, the brackets {} can be removed around that loop, by putting the j+=... inside the third part of the loop: for(;++i<7;j+='${(y[0]-y[1])%12}'). And one last thing is changing return j=='221222'; to return'221222'==j; to get rid of the space. -6 (210 bytes) after these modifications.
        – Kevin Cruijssen
        Nov 8 at 15:02












      • Thanks, didn't know about those tricks for the loops
        – Elcan
        Nov 8 at 15:28










      • Np. In your new 196-bytes version you can also golf it to 189 bytes by changing if(k>9)k--;if(k>3)k--; to k-=k>3?k>9?2:1:0; and k+=m.length<2?0:m[1]=='#'?1:m[1]=='b'?-1:0;return k; to return m.length<2?k:m[1]=='#'?k+1:m[1]=='b'?k-1:k;. :)
        – Kevin Cruijssen
        Nov 8 at 17:49










      • Damn, I still have a lot to learn it seems, thanks !
        – Elcan
        Nov 8 at 19:00










      • Well, I've been golfing for 2.5 years now, and even I get tips on things to golf all the time. :) It's pretty easy to miss something yourself initially, and with time you think about different ways to golf. :) Tips for golfing in <all languages> might be interesting to read through if you haven't yet. And some of the Tips for golfing in Java might also be applicable in Dart, since the golfs I did in your answers were based on my Java knowledge, since this is the first time I see Dart. ;)
        – Kevin Cruijssen
        Nov 8 at 20:38


















      • I don't know Dart, but parts are similar as Java. Therefore: changing i=1 to i=0 can reduce a byte by changing for(;i<7;i++) to for(;++i<7;). In addition, the brackets {} can be removed around that loop, by putting the j+=... inside the third part of the loop: for(;++i<7;j+='${(y[0]-y[1])%12}'). And one last thing is changing return j=='221222'; to return'221222'==j; to get rid of the space. -6 (210 bytes) after these modifications.
        – Kevin Cruijssen
        Nov 8 at 15:02












      • Thanks, didn't know about those tricks for the loops
        – Elcan
        Nov 8 at 15:28










      • Np. In your new 196-bytes version you can also golf it to 189 bytes by changing if(k>9)k--;if(k>3)k--; to k-=k>3?k>9?2:1:0; and k+=m.length<2?0:m[1]=='#'?1:m[1]=='b'?-1:0;return k; to return m.length<2?k:m[1]=='#'?k+1:m[1]=='b'?k-1:k;. :)
        – Kevin Cruijssen
        Nov 8 at 17:49










      • Damn, I still have a lot to learn it seems, thanks !
        – Elcan
        Nov 8 at 19:00










      • Well, I've been golfing for 2.5 years now, and even I get tips on things to golf all the time. :) It's pretty easy to miss something yourself initially, and with time you think about different ways to golf. :) Tips for golfing in <all languages> might be interesting to read through if you haven't yet. And some of the Tips for golfing in Java might also be applicable in Dart, since the golfs I did in your answers were based on my Java knowledge, since this is the first time I see Dart. ;)
        – Kevin Cruijssen
        Nov 8 at 20:38
















      I don't know Dart, but parts are similar as Java. Therefore: changing i=1 to i=0 can reduce a byte by changing for(;i<7;i++) to for(;++i<7;). In addition, the brackets {} can be removed around that loop, by putting the j+=... inside the third part of the loop: for(;++i<7;j+='${(y[0]-y[1])%12}'). And one last thing is changing return j=='221222'; to return'221222'==j; to get rid of the space. -6 (210 bytes) after these modifications.
      – Kevin Cruijssen
      Nov 8 at 15:02






      I don't know Dart, but parts are similar as Java. Therefore: changing i=1 to i=0 can reduce a byte by changing for(;i<7;i++) to for(;++i<7;). In addition, the brackets {} can be removed around that loop, by putting the j+=... inside the third part of the loop: for(;++i<7;j+='${(y[0]-y[1])%12}'). And one last thing is changing return j=='221222'; to return'221222'==j; to get rid of the space. -6 (210 bytes) after these modifications.
      – Kevin Cruijssen
      Nov 8 at 15:02














      Thanks, didn't know about those tricks for the loops
      – Elcan
      Nov 8 at 15:28




      Thanks, didn't know about those tricks for the loops
      – Elcan
      Nov 8 at 15:28












      Np. In your new 196-bytes version you can also golf it to 189 bytes by changing if(k>9)k--;if(k>3)k--; to k-=k>3?k>9?2:1:0; and k+=m.length<2?0:m[1]=='#'?1:m[1]=='b'?-1:0;return k; to return m.length<2?k:m[1]=='#'?k+1:m[1]=='b'?k-1:k;. :)
      – Kevin Cruijssen
      Nov 8 at 17:49




      Np. In your new 196-bytes version you can also golf it to 189 bytes by changing if(k>9)k--;if(k>3)k--; to k-=k>3?k>9?2:1:0; and k+=m.length<2?0:m[1]=='#'?1:m[1]=='b'?-1:0;return k; to return m.length<2?k:m[1]=='#'?k+1:m[1]=='b'?k-1:k;. :)
      – Kevin Cruijssen
      Nov 8 at 17:49












      Damn, I still have a lot to learn it seems, thanks !
      – Elcan
      Nov 8 at 19:00




      Damn, I still have a lot to learn it seems, thanks !
      – Elcan
      Nov 8 at 19:00












      Well, I've been golfing for 2.5 years now, and even I get tips on things to golf all the time. :) It's pretty easy to miss something yourself initially, and with time you think about different ways to golf. :) Tips for golfing in <all languages> might be interesting to read through if you haven't yet. And some of the Tips for golfing in Java might also be applicable in Dart, since the golfs I did in your answers were based on my Java knowledge, since this is the first time I see Dart. ;)
      – Kevin Cruijssen
      Nov 8 at 20:38




      Well, I've been golfing for 2.5 years now, and even I get tips on things to golf all the time. :) It's pretty easy to miss something yourself initially, and with time you think about different ways to golf. :) Tips for golfing in <all languages> might be interesting to read through if you haven't yet. And some of the Tips for golfing in Java might also be applicable in Dart, since the golfs I did in your answers were based on my Java knowledge, since this is the first time I see Dart. ;)
      – Kevin Cruijssen
      Nov 8 at 20:38










      up vote
      2
      down vote














      C (gcc), -DA=a[i] + 183 = 191 bytes





      f(int*a){char s[9],b[9],h=0,i=0,j=0,d;for(;A;A==35?b[i-h++-1]++:A^98?(b[i-h]=A*13>>3):b[i-h++-1]--,i++);for(;j<7;d=(b[j]-b[j-1])%12,d=d<0?d+12:d,s[j++-1]=d+48);a=!strcmp(s,"221222");}


      Try it online!



      Based on the Perl answer.



      Takes input as a wide string.



      Ungolfed:



      int f(int *a){
      char s[9], b[9];
      int h, i, j;
      h = 0;
      for(i = 0; a[i] != NULL; i++){
      if(a[i] == '#'){
      b[i-h-1] += 1;
      h++;
      }
      else if(a[i] == 'b'){
      b[i-1-h] -= 1;
      h++;
      }
      else{
      b[i-h] = (a[i] * 13) >> 3;
      }
      }
      for(j = 1; j < 7; j++){
      int d = (b[j] - b[j-1]) % 12;
      d = d < 0? d + 12: d;
      s[j-1] = d + '0';
      }
      return strcmp(s, "221222") == 0;
      }





      share|improve this answer























      • Suggest i-++h instead of i-h++-1
        – ceilingcat
        Nov 15 at 23:59















      up vote
      2
      down vote














      C (gcc), -DA=a[i] + 183 = 191 bytes





      f(int*a){char s[9],b[9],h=0,i=0,j=0,d;for(;A;A==35?b[i-h++-1]++:A^98?(b[i-h]=A*13>>3):b[i-h++-1]--,i++);for(;j<7;d=(b[j]-b[j-1])%12,d=d<0?d+12:d,s[j++-1]=d+48);a=!strcmp(s,"221222");}


      Try it online!



      Based on the Perl answer.



      Takes input as a wide string.



      Ungolfed:



      int f(int *a){
      char s[9], b[9];
      int h, i, j;
      h = 0;
      for(i = 0; a[i] != NULL; i++){
      if(a[i] == '#'){
      b[i-h-1] += 1;
      h++;
      }
      else if(a[i] == 'b'){
      b[i-1-h] -= 1;
      h++;
      }
      else{
      b[i-h] = (a[i] * 13) >> 3;
      }
      }
      for(j = 1; j < 7; j++){
      int d = (b[j] - b[j-1]) % 12;
      d = d < 0? d + 12: d;
      s[j-1] = d + '0';
      }
      return strcmp(s, "221222") == 0;
      }





      share|improve this answer























      • Suggest i-++h instead of i-h++-1
        – ceilingcat
        Nov 15 at 23:59













      up vote
      2
      down vote










      up vote
      2
      down vote










      C (gcc), -DA=a[i] + 183 = 191 bytes





      f(int*a){char s[9],b[9],h=0,i=0,j=0,d;for(;A;A==35?b[i-h++-1]++:A^98?(b[i-h]=A*13>>3):b[i-h++-1]--,i++);for(;j<7;d=(b[j]-b[j-1])%12,d=d<0?d+12:d,s[j++-1]=d+48);a=!strcmp(s,"221222");}


      Try it online!



      Based on the Perl answer.



      Takes input as a wide string.



      Ungolfed:



      int f(int *a){
      char s[9], b[9];
      int h, i, j;
      h = 0;
      for(i = 0; a[i] != NULL; i++){
      if(a[i] == '#'){
      b[i-h-1] += 1;
      h++;
      }
      else if(a[i] == 'b'){
      b[i-1-h] -= 1;
      h++;
      }
      else{
      b[i-h] = (a[i] * 13) >> 3;
      }
      }
      for(j = 1; j < 7; j++){
      int d = (b[j] - b[j-1]) % 12;
      d = d < 0? d + 12: d;
      s[j-1] = d + '0';
      }
      return strcmp(s, "221222") == 0;
      }





      share|improve this answer















      C (gcc), -DA=a[i] + 183 = 191 bytes





      f(int*a){char s[9],b[9],h=0,i=0,j=0,d;for(;A;A==35?b[i-h++-1]++:A^98?(b[i-h]=A*13>>3):b[i-h++-1]--,i++);for(;j<7;d=(b[j]-b[j-1])%12,d=d<0?d+12:d,s[j++-1]=d+48);a=!strcmp(s,"221222");}


      Try it online!



      Based on the Perl answer.



      Takes input as a wide string.



      Ungolfed:



      int f(int *a){
      char s[9], b[9];
      int h, i, j;
      h = 0;
      for(i = 0; a[i] != NULL; i++){
      if(a[i] == '#'){
      b[i-h-1] += 1;
      h++;
      }
      else if(a[i] == 'b'){
      b[i-1-h] -= 1;
      h++;
      }
      else{
      b[i-h] = (a[i] * 13) >> 3;
      }
      }
      for(j = 1; j < 7; j++){
      int d = (b[j] - b[j-1]) % 12;
      d = d < 0? d + 12: d;
      s[j-1] = d + '0';
      }
      return strcmp(s, "221222") == 0;
      }






      share|improve this answer














      share|improve this answer



      share|improve this answer








      edited Nov 8 at 20:05

























      answered Nov 8 at 19:44









      Logern

      70546




      70546












      • Suggest i-++h instead of i-h++-1
        – ceilingcat
        Nov 15 at 23:59


















      • Suggest i-++h instead of i-h++-1
        – ceilingcat
        Nov 15 at 23:59
















      Suggest i-++h instead of i-h++-1
      – ceilingcat
      Nov 15 at 23:59




      Suggest i-++h instead of i-h++-1
      – ceilingcat
      Nov 15 at 23:59










      up vote
      2
      down vote














      Python 3, 175 136 134 114 112 bytes





      def f(t):r=[ord(x[0])//.6+ord(x[1:]or'"')%13-8for x in t];return[(y-x)%12for x,y in zip(r,r[1:])]==[2,2,1,2,2,2]


      Try it online!





      An one-liner Python 3 implementation.



      Thanks to @Arnauld for idea of calculate tones using division and modulo.

      Thanks to @Jo King for -39 bytes.






      share|improve this answer



















      • 1




        136 bytes
        – Jo King
        Nov 9 at 7:27










      • @JoKing Wow, thanks!
        – cobaltp
        Nov 9 at 7:43















      up vote
      2
      down vote














      Python 3, 175 136 134 114 112 bytes





      def f(t):r=[ord(x[0])//.6+ord(x[1:]or'"')%13-8for x in t];return[(y-x)%12for x,y in zip(r,r[1:])]==[2,2,1,2,2,2]


      Try it online!





      An one-liner Python 3 implementation.



      Thanks to @Arnauld for idea of calculate tones using division and modulo.

      Thanks to @Jo King for -39 bytes.






      share|improve this answer



















      • 1




        136 bytes
        – Jo King
        Nov 9 at 7:27










      • @JoKing Wow, thanks!
        – cobaltp
        Nov 9 at 7:43













      up vote
      2
      down vote










      up vote
      2
      down vote










      Python 3, 175 136 134 114 112 bytes





      def f(t):r=[ord(x[0])//.6+ord(x[1:]or'"')%13-8for x in t];return[(y-x)%12for x,y in zip(r,r[1:])]==[2,2,1,2,2,2]


      Try it online!





      An one-liner Python 3 implementation.



      Thanks to @Arnauld for idea of calculate tones using division and modulo.

      Thanks to @Jo King for -39 bytes.






      share|improve this answer















      Python 3, 175 136 134 114 112 bytes





      def f(t):r=[ord(x[0])//.6+ord(x[1:]or'"')%13-8for x in t];return[(y-x)%12for x,y in zip(r,r[1:])]==[2,2,1,2,2,2]


      Try it online!





      An one-liner Python 3 implementation.



      Thanks to @Arnauld for idea of calculate tones using division and modulo.

      Thanks to @Jo King for -39 bytes.







      share|improve this answer














      share|improve this answer



      share|improve this answer








      edited Nov 15 at 7:48

























      answered Nov 9 at 7:08









      cobaltp

      1716




      1716








      • 1




        136 bytes
        – Jo King
        Nov 9 at 7:27










      • @JoKing Wow, thanks!
        – cobaltp
        Nov 9 at 7:43














      • 1




        136 bytes
        – Jo King
        Nov 9 at 7:27










      • @JoKing Wow, thanks!
        – cobaltp
        Nov 9 at 7:43








      1




      1




      136 bytes
      – Jo King
      Nov 9 at 7:27




      136 bytes
      – Jo King
      Nov 9 at 7:27












      @JoKing Wow, thanks!
      – cobaltp
      Nov 9 at 7:43




      @JoKing Wow, thanks!
      – cobaltp
      Nov 9 at 7:43










      up vote
      1
      down vote













      [Python] 269 202 bytes



      Improvements from Jo King:



      p=lambda z:"A BC D EF G".index(z[0])+"b #".index(z[1:]or' ')-1
      def d(i,j):f=abs(p(i)-p(j));return min(f,12-f)
      q=input().replace(' ','').split(',')
      print([d(q[i],q[i+1])for i in range(6)]==[2,2,1,2,2,2])


      Try it!



      Ungolfed, with test driver:



      tone = "A BC D EF G"   # tones in "piano" layout
      adj = "b #" # accidentals

      def note_pos(note):
      if len(note) == 1:
      note += ' '
      n,a = note
      return tone.index(n) + adj[a]

      def note_diff(i, j):
      x, y = note_pos(i), note_pos(j)
      diff = abs(x-y)
      return min(diff, 12-diff)

      def is_scale(str):
      seq = str.replace(' ','').split(',')
      div = [note_diff(seq[i], seq[i+1]) for i in (0,1,2,3,4,5)]
      return div == [2,2,1,2,2,2]

      case = [
      ("C, D, E, F, G, A, B", True),
      ("C#, D#, E#, F#, G#, A#, B#", True),
      ("Db, Eb, F, Gb, Ab, Bb, C", True),
      ("D, E, Gb, G, A, Cb, C#", True),
      ("Eb, E#, G, G#, Bb, B#, D", True),

      ("C, D#, E, F, G, A, B", False),
      ("Db, Eb, F, Gb, Ab, B, C", False),
      ("G#, E, F, A, B, D#, C", False),
      ("C#, C#, E#, F#, G#, A#, B#", False),
      ("Eb, E#, Gb, G#, Bb, B#, D", False),
      ]

      for test, result in case:
      print(test + ' '*(30-len(test)), result, 't',
      "valid" if is_scale(test) == result else "ERROR")





      share|improve this answer























      • Yes, I see the white space -- still inculcated with too much PEP-8, I'm afraid. I apparently missed something; is an execution link required here?
        – Prune
        Nov 9 at 2:03






      • 1




        Though, if you want the link, 202 bytes with some quick golfing. You could definitely golf some more by changing to a different input format
        – Jo King
        Nov 9 at 2:28












      • Ah ... I'm too used to Python returning the final expression as the process value. Thanks for the pointers and hints.
        – Prune
        Nov 9 at 2:32










      • You can get 156 bytes if you switch to a function taking a list of strings. Also, TIO has an auto formatter in the link section that you can use
        – Jo King
        Nov 9 at 2:49










      • @JoKing, you're perfectly welcome to edit this answer or post your own; commenting with a link separates the improvements by one level.
        – Prune
        Nov 9 at 16:40















      up vote
      1
      down vote













      [Python] 269 202 bytes



      Improvements from Jo King:



      p=lambda z:"A BC D EF G".index(z[0])+"b #".index(z[1:]or' ')-1
      def d(i,j):f=abs(p(i)-p(j));return min(f,12-f)
      q=input().replace(' ','').split(',')
      print([d(q[i],q[i+1])for i in range(6)]==[2,2,1,2,2,2])


      Try it!



      Ungolfed, with test driver:



      tone = "A BC D EF G"   # tones in "piano" layout
      adj = "b #" # accidentals

      def note_pos(note):
      if len(note) == 1:
      note += ' '
      n,a = note
      return tone.index(n) + adj[a]

      def note_diff(i, j):
      x, y = note_pos(i), note_pos(j)
      diff = abs(x-y)
      return min(diff, 12-diff)

      def is_scale(str):
      seq = str.replace(' ','').split(',')
      div = [note_diff(seq[i], seq[i+1]) for i in (0,1,2,3,4,5)]
      return div == [2,2,1,2,2,2]

      case = [
      ("C, D, E, F, G, A, B", True),
      ("C#, D#, E#, F#, G#, A#, B#", True),
      ("Db, Eb, F, Gb, Ab, Bb, C", True),
      ("D, E, Gb, G, A, Cb, C#", True),
      ("Eb, E#, G, G#, Bb, B#, D", True),

      ("C, D#, E, F, G, A, B", False),
      ("Db, Eb, F, Gb, Ab, B, C", False),
      ("G#, E, F, A, B, D#, C", False),
      ("C#, C#, E#, F#, G#, A#, B#", False),
      ("Eb, E#, Gb, G#, Bb, B#, D", False),
      ]

      for test, result in case:
      print(test + ' '*(30-len(test)), result, 't',
      "valid" if is_scale(test) == result else "ERROR")





      share|improve this answer























      • Yes, I see the white space -- still inculcated with too much PEP-8, I'm afraid. I apparently missed something; is an execution link required here?
        – Prune
        Nov 9 at 2:03






      • 1




        Though, if you want the link, 202 bytes with some quick golfing. You could definitely golf some more by changing to a different input format
        – Jo King
        Nov 9 at 2:28












      • Ah ... I'm too used to Python returning the final expression as the process value. Thanks for the pointers and hints.
        – Prune
        Nov 9 at 2:32










      • You can get 156 bytes if you switch to a function taking a list of strings. Also, TIO has an auto formatter in the link section that you can use
        – Jo King
        Nov 9 at 2:49










      • @JoKing, you're perfectly welcome to edit this answer or post your own; commenting with a link separates the improvements by one level.
        – Prune
        Nov 9 at 16:40













      up vote
      1
      down vote










      up vote
      1
      down vote









      [Python] 269 202 bytes



      Improvements from Jo King:



      p=lambda z:"A BC D EF G".index(z[0])+"b #".index(z[1:]or' ')-1
      def d(i,j):f=abs(p(i)-p(j));return min(f,12-f)
      q=input().replace(' ','').split(',')
      print([d(q[i],q[i+1])for i in range(6)]==[2,2,1,2,2,2])


      Try it!



      Ungolfed, with test driver:



      tone = "A BC D EF G"   # tones in "piano" layout
      adj = "b #" # accidentals

      def note_pos(note):
      if len(note) == 1:
      note += ' '
      n,a = note
      return tone.index(n) + adj[a]

      def note_diff(i, j):
      x, y = note_pos(i), note_pos(j)
      diff = abs(x-y)
      return min(diff, 12-diff)

      def is_scale(str):
      seq = str.replace(' ','').split(',')
      div = [note_diff(seq[i], seq[i+1]) for i in (0,1,2,3,4,5)]
      return div == [2,2,1,2,2,2]

      case = [
      ("C, D, E, F, G, A, B", True),
      ("C#, D#, E#, F#, G#, A#, B#", True),
      ("Db, Eb, F, Gb, Ab, Bb, C", True),
      ("D, E, Gb, G, A, Cb, C#", True),
      ("Eb, E#, G, G#, Bb, B#, D", True),

      ("C, D#, E, F, G, A, B", False),
      ("Db, Eb, F, Gb, Ab, B, C", False),
      ("G#, E, F, A, B, D#, C", False),
      ("C#, C#, E#, F#, G#, A#, B#", False),
      ("Eb, E#, Gb, G#, Bb, B#, D", False),
      ]

      for test, result in case:
      print(test + ' '*(30-len(test)), result, 't',
      "valid" if is_scale(test) == result else "ERROR")





      share|improve this answer














      [Python] 269 202 bytes



      Improvements from Jo King:



      p=lambda z:"A BC D EF G".index(z[0])+"b #".index(z[1:]or' ')-1
      def d(i,j):f=abs(p(i)-p(j));return min(f,12-f)
      q=input().replace(' ','').split(',')
      print([d(q[i],q[i+1])for i in range(6)]==[2,2,1,2,2,2])


      Try it!



      Ungolfed, with test driver:



      tone = "A BC D EF G"   # tones in "piano" layout
      adj = "b #" # accidentals

      def note_pos(note):
      if len(note) == 1:
      note += ' '
      n,a = note
      return tone.index(n) + adj[a]

      def note_diff(i, j):
      x, y = note_pos(i), note_pos(j)
      diff = abs(x-y)
      return min(diff, 12-diff)

      def is_scale(str):
      seq = str.replace(' ','').split(',')
      div = [note_diff(seq[i], seq[i+1]) for i in (0,1,2,3,4,5)]
      return div == [2,2,1,2,2,2]

      case = [
      ("C, D, E, F, G, A, B", True),
      ("C#, D#, E#, F#, G#, A#, B#", True),
      ("Db, Eb, F, Gb, Ab, Bb, C", True),
      ("D, E, Gb, G, A, Cb, C#", True),
      ("Eb, E#, G, G#, Bb, B#, D", True),

      ("C, D#, E, F, G, A, B", False),
      ("Db, Eb, F, Gb, Ab, B, C", False),
      ("G#, E, F, A, B, D#, C", False),
      ("C#, C#, E#, F#, G#, A#, B#", False),
      ("Eb, E#, Gb, G#, Bb, B#, D", False),
      ]

      for test, result in case:
      print(test + ' '*(30-len(test)), result, 't',
      "valid" if is_scale(test) == result else "ERROR")






      share|improve this answer














      share|improve this answer



      share|improve this answer








      edited Nov 9 at 2:37

























      answered Nov 8 at 19:28









      Prune

      1114




      1114












      • Yes, I see the white space -- still inculcated with too much PEP-8, I'm afraid. I apparently missed something; is an execution link required here?
        – Prune
        Nov 9 at 2:03






      • 1




        Though, if you want the link, 202 bytes with some quick golfing. You could definitely golf some more by changing to a different input format
        – Jo King
        Nov 9 at 2:28












      • Ah ... I'm too used to Python returning the final expression as the process value. Thanks for the pointers and hints.
        – Prune
        Nov 9 at 2:32










      • You can get 156 bytes if you switch to a function taking a list of strings. Also, TIO has an auto formatter in the link section that you can use
        – Jo King
        Nov 9 at 2:49










      • @JoKing, you're perfectly welcome to edit this answer or post your own; commenting with a link separates the improvements by one level.
        – Prune
        Nov 9 at 16:40


















      • Yes, I see the white space -- still inculcated with too much PEP-8, I'm afraid. I apparently missed something; is an execution link required here?
        – Prune
        Nov 9 at 2:03






      • 1




        Though, if you want the link, 202 bytes with some quick golfing. You could definitely golf some more by changing to a different input format
        – Jo King
        Nov 9 at 2:28












      • Ah ... I'm too used to Python returning the final expression as the process value. Thanks for the pointers and hints.
        – Prune
        Nov 9 at 2:32










      • You can get 156 bytes if you switch to a function taking a list of strings. Also, TIO has an auto formatter in the link section that you can use
        – Jo King
        Nov 9 at 2:49










      • @JoKing, you're perfectly welcome to edit this answer or post your own; commenting with a link separates the improvements by one level.
        – Prune
        Nov 9 at 16:40
















      Yes, I see the white space -- still inculcated with too much PEP-8, I'm afraid. I apparently missed something; is an execution link required here?
      – Prune
      Nov 9 at 2:03




      Yes, I see the white space -- still inculcated with too much PEP-8, I'm afraid. I apparently missed something; is an execution link required here?
      – Prune
      Nov 9 at 2:03




      1




      1




      Though, if you want the link, 202 bytes with some quick golfing. You could definitely golf some more by changing to a different input format
      – Jo King
      Nov 9 at 2:28






      Though, if you want the link, 202 bytes with some quick golfing. You could definitely golf some more by changing to a different input format
      – Jo King
      Nov 9 at 2:28














      Ah ... I'm too used to Python returning the final expression as the process value. Thanks for the pointers and hints.
      – Prune
      Nov 9 at 2:32




      Ah ... I'm too used to Python returning the final expression as the process value. Thanks for the pointers and hints.
      – Prune
      Nov 9 at 2:32












      You can get 156 bytes if you switch to a function taking a list of strings. Also, TIO has an auto formatter in the link section that you can use
      – Jo King
      Nov 9 at 2:49




      You can get 156 bytes if you switch to a function taking a list of strings. Also, TIO has an auto formatter in the link section that you can use
      – Jo King
      Nov 9 at 2:49












      @JoKing, you're perfectly welcome to edit this answer or post your own; commenting with a link separates the improvements by one level.
      – Prune
      Nov 9 at 16:40




      @JoKing, you're perfectly welcome to edit this answer or post your own; commenting with a link separates the improvements by one level.
      – Prune
      Nov 9 at 16:40










      up vote
      1
      down vote














      Ruby, 109 bytes





      ->s{(0..11).any?{|t|s.map{|n|(w="Cef;DXg<E=Fhi>G j8A d9B:")[(w.index(""<<n.sum%107)/2-t)%12]}*''=='CfDX<=h'}}


      Try it online!






      share|improve this answer

























        up vote
        1
        down vote














        Ruby, 109 bytes





        ->s{(0..11).any?{|t|s.map{|n|(w="Cef;DXg<E=Fhi>G j8A d9B:")[(w.index(""<<n.sum%107)/2-t)%12]}*''=='CfDX<=h'}}


        Try it online!






        share|improve this answer























          up vote
          1
          down vote










          up vote
          1
          down vote










          Ruby, 109 bytes





          ->s{(0..11).any?{|t|s.map{|n|(w="Cef;DXg<E=Fhi>G j8A d9B:")[(w.index(""<<n.sum%107)/2-t)%12]}*''=='CfDX<=h'}}


          Try it online!






          share|improve this answer













          Ruby, 109 bytes





          ->s{(0..11).any?{|t|s.map{|n|(w="Cef;DXg<E=Fhi>G j8A d9B:")[(w.index(""<<n.sum%107)/2-t)%12]}*''=='CfDX<=h'}}


          Try it online!







          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered Nov 9 at 7:58









          G B

          7,4561328




          7,4561328






















              up vote
              0
              down vote













              [Wolfram Language (Mathematica) + Music` package], 114 bytes



              I love music and found this interesting, but I was out playing real golf when this code golf opportunity came down the pike so my submission is a little tardy.



              I figured I'd try this a totally different way, utilizing some actual music knowledge. It turns out the music package of Mathematica knows the fundamental frequency of the named notes. First I convert the input string into sequence of named notes. Next, I take the ratios of each successive note and double any that are less than 2 (to account for octave shift). Then I compare these ratios to the ratios of the Ionian scale which has roughly a 6% frequency difference between half notes and 12% between full notes.



              More than half of the bytes spent here are to convert the input into named symbols.



              .06{2,2,1,2,2,2}+1==Round[Ratios[Symbol[#~~"0"]&/@StringReplace[# ,{"b"->"flat","#"->"sharp"}]]/.x_/;x<1->2x,.01]&


              Try it online!






              share|improve this answer

























                up vote
                0
                down vote













                [Wolfram Language (Mathematica) + Music` package], 114 bytes



                I love music and found this interesting, but I was out playing real golf when this code golf opportunity came down the pike so my submission is a little tardy.



                I figured I'd try this a totally different way, utilizing some actual music knowledge. It turns out the music package of Mathematica knows the fundamental frequency of the named notes. First I convert the input string into sequence of named notes. Next, I take the ratios of each successive note and double any that are less than 2 (to account for octave shift). Then I compare these ratios to the ratios of the Ionian scale which has roughly a 6% frequency difference between half notes and 12% between full notes.



                More than half of the bytes spent here are to convert the input into named symbols.



                .06{2,2,1,2,2,2}+1==Round[Ratios[Symbol[#~~"0"]&/@StringReplace[# ,{"b"->"flat","#"->"sharp"}]]/.x_/;x<1->2x,.01]&


                Try it online!






                share|improve this answer























                  up vote
                  0
                  down vote










                  up vote
                  0
                  down vote









                  [Wolfram Language (Mathematica) + Music` package], 114 bytes



                  I love music and found this interesting, but I was out playing real golf when this code golf opportunity came down the pike so my submission is a little tardy.



                  I figured I'd try this a totally different way, utilizing some actual music knowledge. It turns out the music package of Mathematica knows the fundamental frequency of the named notes. First I convert the input string into sequence of named notes. Next, I take the ratios of each successive note and double any that are less than 2 (to account for octave shift). Then I compare these ratios to the ratios of the Ionian scale which has roughly a 6% frequency difference between half notes and 12% between full notes.



                  More than half of the bytes spent here are to convert the input into named symbols.



                  .06{2,2,1,2,2,2}+1==Round[Ratios[Symbol[#~~"0"]&/@StringReplace[# ,{"b"->"flat","#"->"sharp"}]]/.x_/;x<1->2x,.01]&


                  Try it online!






                  share|improve this answer












                  [Wolfram Language (Mathematica) + Music` package], 114 bytes



                  I love music and found this interesting, but I was out playing real golf when this code golf opportunity came down the pike so my submission is a little tardy.



                  I figured I'd try this a totally different way, utilizing some actual music knowledge. It turns out the music package of Mathematica knows the fundamental frequency of the named notes. First I convert the input string into sequence of named notes. Next, I take the ratios of each successive note and double any that are less than 2 (to account for octave shift). Then I compare these ratios to the ratios of the Ionian scale which has roughly a 6% frequency difference between half notes and 12% between full notes.



                  More than half of the bytes spent here are to convert the input into named symbols.



                  .06{2,2,1,2,2,2}+1==Round[Ratios[Symbol[#~~"0"]&/@StringReplace[# ,{"b"->"flat","#"->"sharp"}]]/.x_/;x<1->2x,.01]&


                  Try it online!







                  share|improve this answer












                  share|improve this answer



                  share|improve this answer










                  answered Nov 15 at 2:20









                  Kelly Lowder

                  2,968416




                  2,968416






























                       

                      draft saved


                      draft discarded



















































                       


                      draft saved


                      draft discarded














                      StackExchange.ready(
                      function () {
                      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodegolf.stackexchange.com%2fquestions%2f175516%2fis-this-a-major-scale-or-equivalent%23new-answer', 'question_page');
                      }
                      );

                      Post as a guest















                      Required, but never shown





















































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown

































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown







                      Popular posts from this blog

                      Guess what letter conforming each word

                      Port of Spain

                      Run scheduled task as local user group (not BUILTIN)