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).
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
|
show 8 more comments
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).
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
So,E#
is equal toF
, andCb
equal toB
?
– Abigail
yesterday
1
and Cx (or C##) = D
– SaggingRufus
yesterday
1
Btw, Pentatonic scales do not have one of each letter :v
– Luis felipe De jesus Munoz
yesterday
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
yesterday
1
I'm going to have to upvote this because @Neil downvoted it thank you very much
– David Conrad
7 hours ago
|
show 8 more comments
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).
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
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).
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
code-golf decision-problem music
edited yesterday
Arnauld
68k584288
68k584288
asked yesterday
Luis felipe De jesus Munoz
3,67211051
3,67211051
So,E#
is equal toF
, andCb
equal toB
?
– Abigail
yesterday
1
and Cx (or C##) = D
– SaggingRufus
yesterday
1
Btw, Pentatonic scales do not have one of each letter :v
– Luis felipe De jesus Munoz
yesterday
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
yesterday
1
I'm going to have to upvote this because @Neil downvoted it thank you very much
– David Conrad
7 hours ago
|
show 8 more comments
So,E#
is equal toF
, andCb
equal toB
?
– Abigail
yesterday
1
and Cx (or C##) = D
– SaggingRufus
yesterday
1
Btw, Pentatonic scales do not have one of each letter :v
– Luis felipe De jesus Munoz
yesterday
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
yesterday
1
I'm going to have to upvote this because @Neil downvoted it thank you very much
– David Conrad
7 hours ago
So,
E#
is equal to F
, and Cb
equal to B
?– Abigail
yesterday
So,
E#
is equal to F
, and Cb
equal to B
?– Abigail
yesterday
1
1
and Cx (or C##) = D
– SaggingRufus
yesterday
and Cx (or C##) = D
– SaggingRufus
yesterday
1
1
Btw, Pentatonic scales do not have one of each letter :v
– Luis felipe De jesus Munoz
yesterday
Btw, Pentatonic scales do not have one of each letter :v
– Luis felipe De jesus Munoz
yesterday
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
yesterday
@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
yesterday
1
1
I'm going to have to upvote this because @Neil downvoted it thank you very much
– David Conrad
7 hours ago
I'm going to have to upvote this because @Neil downvoted it thank you very much
– David Conrad
7 hours ago
|
show 8 more comments
8 Answers
8
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%12o*>>.&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
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
yesterday
@PhilH Yes, of course. Thanks!
– nwellnhof
yesterday
That's a really clever way of mapping the notes to their relative values, +1 from me!
– Sok
9 hours ago
add a comment |
up vote
8
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 $textNaN$.
For a major scale, we should get $[ textNaN, 2, 2, 1, 2, 2, 2 ]$.
We use the counter $i$ to compare the 4th value with $1$ rather than $2$.
add a comment |
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
I don't know Dart, but parts are similar as Java. Therefore: changingi=1
toi=0
can reduce a byte by changingfor(;i<7;i++)
tofor(;++i<7;)
. In addition, the bracketscan 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 changingreturn j=='221222';
toreturn'221222'==j;
to get rid of the space. -6 (210 bytes) after these modifications.
– Kevin Cruijssen
yesterday
Thanks, didn't know about those tricks for the loops
– Elcan
yesterday
Np. In your new 196-bytes version you can also golf it to 189 bytes by changingif(k>9)k--;if(k>3)k--;
tok-=k>3?k>9?2:1:0;
andk+=m.length<2?0:m[1]=='#'?1:m[1]=='b'?-1:0;return k;
toreturn m.length<2?k:m[1]=='#'?k+1:m[1]=='b'?k-1:k;
. :)
– Kevin Cruijssen
yesterday
Damn, I still have a lot to learn it seems, thanks !
– Elcan
yesterday
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
yesterday
|
show 4 more comments
up vote
3
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) -(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';
1
[...'C0D0EF0G0A0B']
instead of'C0D0EF0G0A0B'.split('')
and+""
instead of.toString()
to save some bytes
– Luis felipe De jesus Munoz
yesterday
x[1]=='#'|-(x[1]=='b')
instead ofx[1]=='#'?1:(x[1]=='b'?-1:0)
save some bytes too
– Luis felipe De jesus Munoz
yesterday
@LuisfelipeDejesusMunoz Oh nice thanks! I can't believe I forgot about array expansion and adding an empty string
– Skidsdev
yesterday
"If delta is negative, replace it with 2" sounds wrong. I think you need to take the difference modulo 12.
– nwellnhof
yesterday
@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
yesterday
|
show 2 more comments
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;
add a comment |
up vote
2
down vote
Python 3, 175 136 134 bytes
def f(t):r=[ord(x[0])//.6%12+'b #'.index(x[1:]or' ')-1for x in t];return[12*(r[i+1]<r[i])+r[i+1]-r[i]for i in range(6)]==[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 to save -39 bytes!
-2 bytes by removing parentheses.
New contributor
1
136 bytes
– Jo King
18 hours ago
@JoKing Wow, thanks!
– cobaltp
17 hours ago
add a comment |
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")
New contributor
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
23 hours ago
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
23 hours ago
Ah ... I'm too used to Python returning the final expression as the process value. Thanks for the pointers and hints.
– Prune
23 hours ago
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
22 hours ago
@JoKing, you're perfectly welcome to edit this answer or post your own; commenting with a link separates the improvements by one level.
– Prune
9 hours ago
add a comment |
up vote
1
down vote
Ruby, 109 bytes
->s(0..11).any?s.map(w="Cef;DXg<E=Fhi>G j8A d9B:")[(w.index(""<<n.sum%107)/2-t)%12]*''=='CfDX<=h'
Try it online!
add a comment |
8 Answers
8
active
oldest
votes
8 Answers
8
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%12o*>>.&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
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
yesterday
@PhilH Yes, of course. Thanks!
– nwellnhof
yesterday
That's a really clever way of mapping the notes to their relative values, +1 from me!
– Sok
9 hours ago
add a comment |
up vote
11
down vote
Perl 6, 76 65 63 59 bytes
-4 bytes thanks to Phil H
221222==[~] (.skip Z-$_)X%12o*>>.&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
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
yesterday
@PhilH Yes, of course. Thanks!
– nwellnhof
yesterday
That's a really clever way of mapping the notes to their relative values, +1 from me!
– Sok
9 hours ago
add a comment |
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%12o*>>.&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
Perl 6, 76 65 63 59 bytes
-4 bytes thanks to Phil H
221222==[~] (.skip Z-$_)X%12o*>>.&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
edited yesterday
answered yesterday
nwellnhof
5,548921
5,548921
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
yesterday
@PhilH Yes, of course. Thanks!
– nwellnhof
yesterday
That's a really clever way of mapping the notes to their relative values, +1 from me!
– Sok
9 hours ago
add a comment |
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
yesterday
@PhilH Yes, of course. Thanks!
– nwellnhof
yesterday
That's a really clever way of mapping the notes to their relative values, +1 from me!
– Sok
9 hours ago
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
yesterday
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
yesterday
@PhilH Yes, of course. Thanks!
– nwellnhof
yesterday
@PhilH Yes, of course. Thanks!
– nwellnhof
yesterday
That's a really clever way of mapping the notes to their relative values, +1 from me!
– Sok
9 hours ago
That's a really clever way of mapping the notes to their relative values, +1 from me!
– Sok
9 hours ago
add a comment |
up vote
8
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 $textNaN$.
For a major scale, we should get $[ textNaN, 2, 2, 1, 2, 2, 2 ]$.
We use the counter $i$ to compare the 4th value with $1$ rather than $2$.
add a comment |
up vote
8
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 $textNaN$.
For a major scale, we should get $[ textNaN, 2, 2, 1, 2, 2, 2 ]$.
We use the counter $i$ to compare the 4th value with $1$ rather than $2$.
add a comment |
up vote
8
down vote
up vote
8
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 $textNaN$.
For a major scale, we should get $[ textNaN, 2, 2, 1, 2, 2, 2 ]$.
We use the counter $i$ to compare the 4th value with $1$ rather than $2$.
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 $textNaN$.
For a major scale, we should get $[ textNaN, 2, 2, 1, 2, 2, 2 ]$.
We use the counter $i$ to compare the 4th value with $1$ rather than $2$.
edited 17 hours ago
answered yesterday
Arnauld
68k584288
68k584288
add a comment |
add a comment |
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
I don't know Dart, but parts are similar as Java. Therefore: changingi=1
toi=0
can reduce a byte by changingfor(;i<7;i++)
tofor(;++i<7;)
. In addition, the bracketscan 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 changingreturn j=='221222';
toreturn'221222'==j;
to get rid of the space. -6 (210 bytes) after these modifications.
– Kevin Cruijssen
yesterday
Thanks, didn't know about those tricks for the loops
– Elcan
yesterday
Np. In your new 196-bytes version you can also golf it to 189 bytes by changingif(k>9)k--;if(k>3)k--;
tok-=k>3?k>9?2:1:0;
andk+=m.length<2?0:m[1]=='#'?1:m[1]=='b'?-1:0;return k;
toreturn m.length<2?k:m[1]=='#'?k+1:m[1]=='b'?k-1:k;
. :)
– Kevin Cruijssen
yesterday
Damn, I still have a lot to learn it seems, thanks !
– Elcan
yesterday
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
yesterday
|
show 4 more comments
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
I don't know Dart, but parts are similar as Java. Therefore: changingi=1
toi=0
can reduce a byte by changingfor(;i<7;i++)
tofor(;++i<7;)
. In addition, the bracketscan 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 changingreturn j=='221222';
toreturn'221222'==j;
to get rid of the space. -6 (210 bytes) after these modifications.
– Kevin Cruijssen
yesterday
Thanks, didn't know about those tricks for the loops
– Elcan
yesterday
Np. In your new 196-bytes version you can also golf it to 189 bytes by changingif(k>9)k--;if(k>3)k--;
tok-=k>3?k>9?2:1:0;
andk+=m.length<2?0:m[1]=='#'?1:m[1]=='b'?-1:0;return k;
toreturn m.length<2?k:m[1]=='#'?k+1:m[1]=='b'?k-1:k;
. :)
– Kevin Cruijssen
yesterday
Damn, I still have a lot to learn it seems, thanks !
– Elcan
yesterday
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
yesterday
|
show 4 more comments
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
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
edited 12 hours ago
answered yesterday
Elcan
27115
27115
I don't know Dart, but parts are similar as Java. Therefore: changingi=1
toi=0
can reduce a byte by changingfor(;i<7;i++)
tofor(;++i<7;)
. In addition, the bracketscan 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 changingreturn j=='221222';
toreturn'221222'==j;
to get rid of the space. -6 (210 bytes) after these modifications.
– Kevin Cruijssen
yesterday
Thanks, didn't know about those tricks for the loops
– Elcan
yesterday
Np. In your new 196-bytes version you can also golf it to 189 bytes by changingif(k>9)k--;if(k>3)k--;
tok-=k>3?k>9?2:1:0;
andk+=m.length<2?0:m[1]=='#'?1:m[1]=='b'?-1:0;return k;
toreturn m.length<2?k:m[1]=='#'?k+1:m[1]=='b'?k-1:k;
. :)
– Kevin Cruijssen
yesterday
Damn, I still have a lot to learn it seems, thanks !
– Elcan
yesterday
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
yesterday
|
show 4 more comments
I don't know Dart, but parts are similar as Java. Therefore: changingi=1
toi=0
can reduce a byte by changingfor(;i<7;i++)
tofor(;++i<7;)
. In addition, the bracketscan 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 changingreturn j=='221222';
toreturn'221222'==j;
to get rid of the space. -6 (210 bytes) after these modifications.
– Kevin Cruijssen
yesterday
Thanks, didn't know about those tricks for the loops
– Elcan
yesterday
Np. In your new 196-bytes version you can also golf it to 189 bytes by changingif(k>9)k--;if(k>3)k--;
tok-=k>3?k>9?2:1:0;
andk+=m.length<2?0:m[1]=='#'?1:m[1]=='b'?-1:0;return k;
toreturn m.length<2?k:m[1]=='#'?k+1:m[1]=='b'?k-1:k;
. :)
– Kevin Cruijssen
yesterday
Damn, I still have a lot to learn it seems, thanks !
– Elcan
yesterday
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
yesterday
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
yesterday
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
yesterday
Thanks, didn't know about those tricks for the loops
– Elcan
yesterday
Thanks, didn't know about those tricks for the loops
– Elcan
yesterday
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
yesterday
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
yesterday
Damn, I still have a lot to learn it seems, thanks !
– Elcan
yesterday
Damn, I still have a lot to learn it seems, thanks !
– Elcan
yesterday
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
yesterday
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
yesterday
|
show 4 more comments
up vote
3
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) -(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';
1
[...'C0D0EF0G0A0B']
instead of'C0D0EF0G0A0B'.split('')
and+""
instead of.toString()
to save some bytes
– Luis felipe De jesus Munoz
yesterday
x[1]=='#'|-(x[1]=='b')
instead ofx[1]=='#'?1:(x[1]=='b'?-1:0)
save some bytes too
– Luis felipe De jesus Munoz
yesterday
@LuisfelipeDejesusMunoz Oh nice thanks! I can't believe I forgot about array expansion and adding an empty string
– Skidsdev
yesterday
"If delta is negative, replace it with 2" sounds wrong. I think you need to take the difference modulo 12.
– nwellnhof
yesterday
@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
yesterday
|
show 2 more comments
up vote
3
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) -(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';
1
[...'C0D0EF0G0A0B']
instead of'C0D0EF0G0A0B'.split('')
and+""
instead of.toString()
to save some bytes
– Luis felipe De jesus Munoz
yesterday
x[1]=='#'|-(x[1]=='b')
instead ofx[1]=='#'?1:(x[1]=='b'?-1:0)
save some bytes too
– Luis felipe De jesus Munoz
yesterday
@LuisfelipeDejesusMunoz Oh nice thanks! I can't believe I forgot about array expansion and adding an empty string
– Skidsdev
yesterday
"If delta is negative, replace it with 2" sounds wrong. I think you need to take the difference modulo 12.
– nwellnhof
yesterday
@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
yesterday
|
show 2 more comments
up vote
3
down vote
up vote
3
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) -(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';
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) -(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';
edited 7 hours ago
answered yesterday
Skidsdev
5,8832664
5,8832664
1
[...'C0D0EF0G0A0B']
instead of'C0D0EF0G0A0B'.split('')
and+""
instead of.toString()
to save some bytes
– Luis felipe De jesus Munoz
yesterday
x[1]=='#'|-(x[1]=='b')
instead ofx[1]=='#'?1:(x[1]=='b'?-1:0)
save some bytes too
– Luis felipe De jesus Munoz
yesterday
@LuisfelipeDejesusMunoz Oh nice thanks! I can't believe I forgot about array expansion and adding an empty string
– Skidsdev
yesterday
"If delta is negative, replace it with 2" sounds wrong. I think you need to take the difference modulo 12.
– nwellnhof
yesterday
@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
yesterday
|
show 2 more comments
1
[...'C0D0EF0G0A0B']
instead of'C0D0EF0G0A0B'.split('')
and+""
instead of.toString()
to save some bytes
– Luis felipe De jesus Munoz
yesterday
x[1]=='#'|-(x[1]=='b')
instead ofx[1]=='#'?1:(x[1]=='b'?-1:0)
save some bytes too
– Luis felipe De jesus Munoz
yesterday
@LuisfelipeDejesusMunoz Oh nice thanks! I can't believe I forgot about array expansion and adding an empty string
– Skidsdev
yesterday
"If delta is negative, replace it with 2" sounds wrong. I think you need to take the difference modulo 12.
– nwellnhof
yesterday
@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
yesterday
1
1
[...'C0D0EF0G0A0B']
instead of 'C0D0EF0G0A0B'.split('')
and +""
instead of .toString()
to save some bytes– Luis felipe De jesus Munoz
yesterday
[...'C0D0EF0G0A0B']
instead of 'C0D0EF0G0A0B'.split('')
and +""
instead of .toString()
to save some bytes– Luis felipe De jesus Munoz
yesterday
x[1]=='#'|-(x[1]=='b')
instead of x[1]=='#'?1:(x[1]=='b'?-1:0)
save some bytes too– Luis felipe De jesus Munoz
yesterday
x[1]=='#'|-(x[1]=='b')
instead of x[1]=='#'?1:(x[1]=='b'?-1:0)
save some bytes too– Luis felipe De jesus Munoz
yesterday
@LuisfelipeDejesusMunoz Oh nice thanks! I can't believe I forgot about array expansion and adding an empty string
– Skidsdev
yesterday
@LuisfelipeDejesusMunoz Oh nice thanks! I can't believe I forgot about array expansion and adding an empty string
– Skidsdev
yesterday
"If delta is negative, replace it with 2" sounds wrong. I think you need to take the difference modulo 12.
– nwellnhof
yesterday
"If delta is negative, replace it with 2" sounds wrong. I think you need to take the difference modulo 12.
– nwellnhof
yesterday
@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
yesterday
@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
yesterday
|
show 2 more comments
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;
add a comment |
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;
add a comment |
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;
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;
edited yesterday
answered yesterday
Logern
67546
67546
add a comment |
add a comment |
up vote
2
down vote
Python 3, 175 136 134 bytes
def f(t):r=[ord(x[0])//.6%12+'b #'.index(x[1:]or' ')-1for x in t];return[12*(r[i+1]<r[i])+r[i+1]-r[i]for i in range(6)]==[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 to save -39 bytes!
-2 bytes by removing parentheses.
New contributor
1
136 bytes
– Jo King
18 hours ago
@JoKing Wow, thanks!
– cobaltp
17 hours ago
add a comment |
up vote
2
down vote
Python 3, 175 136 134 bytes
def f(t):r=[ord(x[0])//.6%12+'b #'.index(x[1:]or' ')-1for x in t];return[12*(r[i+1]<r[i])+r[i+1]-r[i]for i in range(6)]==[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 to save -39 bytes!
-2 bytes by removing parentheses.
New contributor
1
136 bytes
– Jo King
18 hours ago
@JoKing Wow, thanks!
– cobaltp
17 hours ago
add a comment |
up vote
2
down vote
up vote
2
down vote
Python 3, 175 136 134 bytes
def f(t):r=[ord(x[0])//.6%12+'b #'.index(x[1:]or' ')-1for x in t];return[12*(r[i+1]<r[i])+r[i+1]-r[i]for i in range(6)]==[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 to save -39 bytes!
-2 bytes by removing parentheses.
New contributor
Python 3, 175 136 134 bytes
def f(t):r=[ord(x[0])//.6%12+'b #'.index(x[1:]or' ')-1for x in t];return[12*(r[i+1]<r[i])+r[i+1]-r[i]for i in range(6)]==[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 to save -39 bytes!
-2 bytes by removing parentheses.
New contributor
edited 11 hours ago
New contributor
answered 18 hours ago
cobaltp
1416
1416
New contributor
New contributor
1
136 bytes
– Jo King
18 hours ago
@JoKing Wow, thanks!
– cobaltp
17 hours ago
add a comment |
1
136 bytes
– Jo King
18 hours ago
@JoKing Wow, thanks!
– cobaltp
17 hours ago
1
1
136 bytes
– Jo King
18 hours ago
136 bytes
– Jo King
18 hours ago
@JoKing Wow, thanks!
– cobaltp
17 hours ago
@JoKing Wow, thanks!
– cobaltp
17 hours ago
add a comment |
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")
New contributor
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
23 hours ago
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
23 hours ago
Ah ... I'm too used to Python returning the final expression as the process value. Thanks for the pointers and hints.
– Prune
23 hours ago
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
22 hours ago
@JoKing, you're perfectly welcome to edit this answer or post your own; commenting with a link separates the improvements by one level.
– Prune
9 hours ago
add a comment |
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")
New contributor
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
23 hours ago
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
23 hours ago
Ah ... I'm too used to Python returning the final expression as the process value. Thanks for the pointers and hints.
– Prune
23 hours ago
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
22 hours ago
@JoKing, you're perfectly welcome to edit this answer or post your own; commenting with a link separates the improvements by one level.
– Prune
9 hours ago
add a comment |
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")
New contributor
[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")
New contributor
edited 23 hours ago
New contributor
answered yesterday
Prune
1114
1114
New contributor
New contributor
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
23 hours ago
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
23 hours ago
Ah ... I'm too used to Python returning the final expression as the process value. Thanks for the pointers and hints.
– Prune
23 hours ago
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
22 hours ago
@JoKing, you're perfectly welcome to edit this answer or post your own; commenting with a link separates the improvements by one level.
– Prune
9 hours ago
add a comment |
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
23 hours ago
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
23 hours ago
Ah ... I'm too used to Python returning the final expression as the process value. Thanks for the pointers and hints.
– Prune
23 hours ago
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
22 hours ago
@JoKing, you're perfectly welcome to edit this answer or post your own; commenting with a link separates the improvements by one level.
– Prune
9 hours ago
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
23 hours ago
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
23 hours ago
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
23 hours ago
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
23 hours ago
Ah ... I'm too used to Python returning the final expression as the process value. Thanks for the pointers and hints.
– Prune
23 hours ago
Ah ... I'm too used to Python returning the final expression as the process value. Thanks for the pointers and hints.
– Prune
23 hours ago
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
22 hours ago
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
22 hours ago
@JoKing, you're perfectly welcome to edit this answer or post your own; commenting with a link separates the improvements by one level.
– Prune
9 hours ago
@JoKing, you're perfectly welcome to edit this answer or post your own; commenting with a link separates the improvements by one level.
– Prune
9 hours ago
add a comment |
up vote
1
down vote
Ruby, 109 bytes
->s(0..11).any?s.map(w="Cef;DXg<E=Fhi>G j8A d9B:")[(w.index(""<<n.sum%107)/2-t)%12]*''=='CfDX<=h'
Try it online!
add a comment |
up vote
1
down vote
Ruby, 109 bytes
->s(0..11).any?s.map(w="Cef;DXg<E=Fhi>G j8A d9B:")[(w.index(""<<n.sum%107)/2-t)%12]*''=='CfDX<=h'
Try it online!
add a comment |
up vote
1
down vote
up vote
1
down vote
Ruby, 109 bytes
->s(0..11).any?s.map(w="Cef;DXg<E=Fhi>G j8A d9B:")[(w.index(""<<n.sum%107)/2-t)%12]*''=='CfDX<=h'
Try it online!
Ruby, 109 bytes
->s(0..11).any?s.map(w="Cef;DXg<E=Fhi>G j8A d9B:")[(w.index(""<<n.sum%107)/2-t)%12]*''=='CfDX<=h'
Try it online!
answered 17 hours ago
G B
7,4261327
7,4261327
add a comment |
add a comment |
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
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
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
So,
E#
is equal toF
, andCb
equal toB
?– Abigail
yesterday
1
and Cx (or C##) = D
– SaggingRufus
yesterday
1
Btw, Pentatonic scales do not have one of each letter :v
– Luis felipe De jesus Munoz
yesterday
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
yesterday
1
I'm going to have to upvote this because @Neil downvoted it thank you very much
– David Conrad
7 hours ago