This task is simple: Write a program or function that outputs the list of all musical notes (using English note names) from A♭ to G♯.
All notes without a name consisting of a single letter (i.e. black notes on a musical keyboard) should have their name printed twice, once as the sharp of a note, once as the flat of one. Sharp or flat notes that can be described with a single letter, like B♯ (C) or F♭ (E) should not be outputted.
Here is an example of the output:
Ab, A, A#, Bb, B, C, C#, Db, D, D#, Eb, E, F, F#, Gb, G, G#
Specifications
The program or function must not take any input.
The notes may be printed in any order, and in any list output permitted by our standard I/O rules
The sharp and flat Unicode symbols (♯/♭) may be substituted with
band#As always, Standard loopholes are forbidden.
As this is code-golf, the smallest program, in bytes, wins.
31 Answers 31
Malbolge, (削除) 482 (削除ここまで) (削除) 370 (削除ここまで) 353 bytes
R1: Removed commas inbetween (as not required by the challenge)
R2: Shave off a few bytes
('<;_#!=6Z|{8xUwvt,PrqonKmk)"FhCUTdb?`+<;:[Z7YtVU2T|/g-O+i(gJrHc#EC~B{@zZxw:tt'r5Qo"!l/K-hUfe?bP``_Lo~[}|X2VCTR3Q+N`_^9+7Hji3ffdAc~w|u;]\wpon4VUSSQ.PONcb(JI^]#DCYX|@?>=<:u9NMRKo32MFj.C,Ae)>'<%:^"!~5:3WxwwuRts0q(Lnml)"Fhgfe"y?a`_zyxq7YXWlUj0RgfkjMb(JI^c\[Z~BAV?T=Rv987Mq44310FEi-,G@)>b&%#"8=6Z{{yyw/Sut1*)('Km$k(!Efe{zyx>`uz]r8ZXnm3TTih.PkNchg`&HFF[DY}Az
CP-1610 assembly (Intellivision), 31 DECLEs1 = 39 bytes
A routine taking an output pointer in R4 and writing the notes there, separated with spaces. In the example code, we write directly to the screen.
Hex dump (routine only)
275 001 2BD 03C 048 1DB 2B8 012 044 2A9 2BA 108 078 201 003 262
261 263 2FA 008 37A 140 225 00B 089 22C 011 2B7 018 210 000
Full source
ROMW 10 ; use 10-bit ROM width
ORG 4800ドル ; map this program at 4800ドル
;; ------------------------------------------------------------- ;;
;; test code ;;
;; ------------------------------------------------------------- ;;
4800 SDBD ; set up an interrupt service routine
4801 MVII #isr, R0 ; to do some minimal STIC initialization
4804 MVO R0, 100ドル
4806 SWAP R0
4807 MVO R0, 101ドル
4809 EIS ; enable interrupts
480A MVII #200,ドル R4 ; R4 = backtab pointer
480C CALL notes ; invoke our routine
480F DECR R7 ; loop forever
;; ------------------------------------------------------------- ;;
;; ISR ;;
;; ------------------------------------------------------------- ;;
isr PROC
4810 MVO R0, 0020ドル ; enable display
4812 CLRR R0
4813 MVO R0, 0030ドル ; no horizontal delay
4815 MVO R0, 0031ドル ; no vertical delay
4817 MVO R0, 0032ドル ; no border extension
4819 MVII #$D, R0
481B MVO R0, 0028ドル ; light-blue background
481D MVO R0, 002ドルC ; light-blue border
481F JR R5 ; return from ISR
ENDP
;; ------------------------------------------------------------- ;;
;; routine ;;
;; ------------------------------------------------------------- ;;
notes PROC
4820 PSHR R5 ; save return address
4821 SDBD ; R5 = pointer to @@chr
4822 MVII #@@chr, R5
4825 CLRR R3 ; R3 = 0 (space)
4826 MVII #12,ドル R0 ; R0 = bitmask = 12ドル
4828 SWAP R0, 2 ; extend it to 1212ドル
4829 @@loop MVI@ R5, R1 ; R1 = next symbol
482A MVII #('A'-32)*8, R2 ; R2 = 'A' character
482C @@note SARC R0 ; right shift the bitmask
482D BC @@next ; skip this note if the carry is set
482F MVO@ R2, R4 ; append the note
4830 MVO@ R1, R4 ; append the symbol
4831 MVO@ R3, R4 ; append a space
4832 @@next ADDI #8, R2 ; advance to the next note
4834 CMPI #('H'-32)*8, R2 ; is it now a 'H'?
4836 BLT @@note ; if not, process the inner loop
4838 TSTR R1 ; was the symbol a space?
4839 BNEQ @@loop ; if not, process the outer loop
483B PULR R7 ; return
483C @@chr DECLE ('#'-32)*8 ; '#'
483D DECLE ('b'-32)*8 ; 'b'
483E DECLE 0 ; space
ENDP
Output
screenshot from jzIntv
1. A CP-1610 opcode is encoded with a 10-bit value, known as a 'DECLE'. This routine is 31 DECLEs long, starting at 4820ドル and ending at 483ドルE (included).
Python 3, 50 bytes
print(*map(''.join,zip(3*'ADGBCEF',7*' '+5*'#b')))
Python 2: 48 bytes
This code can be adjusted as to include B# and Cb, at the cost of no additional bytes. This can be achieved by replacing 5 with 6.
Additionally, it is (finally) shorter than just outputting the plain string:
Python 3, 51 bytes
exit('Ab A A# Bb B C C# Db D D# Eb E F F# Gb G G#')
Python 2: 50 bytes
-
2\$\begingroup\$ This is a very creative solution \$\endgroup\$TheOnlyMrCat– TheOnlyMrCat2019年08月15日 07:46:23 +00:00Commented Aug 15, 2019 at 7:46
05AB1E, (削除) 16 (削除ここまで) (削除) 15 (削除ここまで) 13 bytes
Au...b ×ばつbûÏ
-2 bytes thanks to @maxb.
Outputs as a list, where the single-char notes are with a trailing space.
Explanation:
Au # Push the lowercase alphabet, and uppercase it
...b # # Push string "b #"
â # Take the cartesian product of both strings to create all possible pairs:
# ["Ab","A ","A#","Bb","B ","B#",...,"Zb","Z ","Z#"]
×ばつ # Push compressed integer 1999
b # Convert it to a binary string "11111001111"
û # Palindromize it to "111110011111110011111"
Ï # Only leave the notes in the list at the truthy values (1), (the trailing
# items beyond the length of this binary string are also discarded)
# (after which the result is output implicitly)
See this 05AB1E tip of mine (section How to compress large integers?) to understand why ×ばつ is 1999.
×ばつ could alternatively be 4·< (1000, double, decrease by 1) for the same byte-count.
-
3\$\begingroup\$ Is the
7£really necessary? Seems to run fine without it. \$\endgroup\$maxb– maxb2019年08月15日 12:38:14 +00:00Commented Aug 15, 2019 at 12:38
Perl 6, 41 bytes
{S:g/[E|B]\#...//}o{'A'..'G'X~'b #'.comb}
Simple cross product of the notes and the sharps/flats, followed by removing the extra invalid notes. This is an anonymous code block that produces the string:
Ab A A# Bb B C C# Db D D# Eb E F F# Gb G G#
Jelly, 18?* 20 bytes
ØAḣ7μp)b#Żs6ḣ4ドルẎḊ;W€
A monadic Link returning a list of lists of characters.
* If a mixed list of (a) lists of characters and (b) characters is acceptable remove the trailing W€ for 18.
How?
ØAḣ7μp)b#Żs6ḣ4ドルẎḊ;W€ - Link: no argument
ØA - list of characters [A-Z]
ḣ7 - head to 7 "ABCDEFG"
μ - new monadic link (call that X)
)b# - list of characters "b#"
p - Cartesian product ["Ab","A#","Bb","B#","Cb","C#","Db","D#","Eb","E#","Fb","F#","Gb","G#"]
Ż - prepend a zero [0,"Ab","A#","Bb","B#","Cb","C#","Db","D#","Eb","E#","Fb","F#","Gb","G#"]
s6 - split into sixes [[0,"Ab","A#","Bb","B#","Cb"],["C#","Db","D#","Eb","E#","Fb"],["F#","Gb","G#"]]
ḣ4ドル - head each to 4 [[0,"Ab","A#","Bb"],["C#","Db","D#","Eb"],["F#","Gb","G#"]]
Ẏ - tighten [0,"Ab","A#","Bb","C#","Db","D#","Eb","F#","Gb","G#"]
Ḋ - dequeue ["Ab","A#","Bb","C#","Db","D#","Eb","F#","Gb","G#"]
W€ - wrap each (of X) ["A","B","C","D","E","F","G"]
; - concatenate ["Ab","A#","Bb","C#","Db","D#","Eb","F#","Gb","G#","A","B","C","D","E","F","G"]
-
\$\begingroup\$ @mirabilos this is 20 bytes of source code, the Unicode characters each represent a byte of the source code - see the code page linked by the word
bytesin the header. \$\endgroup\$Jonathan Allan– Jonathan Allan2019年08月15日 18:20:25 +00:00Commented Aug 15, 2019 at 18:20
Retina 0.8.2, 33 bytes
ABCDEFG
.
$&b $& $&#
[BE]#...
Try it online! Explanation:
ABCDEFG
Insert the base note names.
.
$&b $& $&#
Expand each note to include flat and sharp versions.
[BE]#...
Delete B#, E# and also the notes following them (Cb and Eb).
R, 50 bytes
cat("Ab,A,A#,Bb,B,C,C#,Db,D,D#,Eb,E,F,F#,Gb,G,G#")
Boring answer.
R, 60 bytes
cat(outer(LETTERS[1:7],c("#","","b"),paste0)[-c(2,5,17,20)])
-
1\$\begingroup\$ I think the list of examples of redundant notes isn't meant to be exhaustive--the example output also omits
CbandE#. \$\endgroup\$Unrelated String– Unrelated String2019年08月14日 22:09:11 +00:00Commented Aug 14, 2019 at 22:09
Charcoal, 21 bytes
Φ⪪⭆...α7⭆b #+ιλ2§↨⊖⊘φ2κ
Try it online! Link is to verbose version of code. Explanation:
α Predefined variable uppercase alphabet
... 7 First 7 letters i.e. `ABCEDFG`
⭆ Map over characters and join
b # Literal string `b #`
⭆ Map over characters and join
+ιλ Concatenate outer and inner characters
⪪ 2 Split back into substrings of length 2
Φ Filter where nonzero
φ Predefined variable 1000
⊘ Halved i.e. 500
⊖ Decremented i.e 499
↨ 2 Converted to base 2 i.e. [1, 1, 1, 1, 1, 0, 0, 1, 1]
§ κ Cyclically indexed by outer index
Implicitly print matching values on separate lines
Japt, (削除) 23 (削除ここまで) 22 bytes
;B ̄7
ï"b #" fÏÄ %9%8<6
;B Alphabet
̄7 First seven characters ("ABCDEFG")
Assign to U
ï"b #" Cartesian product with "b #" ("Ab,A ,A#,Bb,B ,B#,Cb,C ,C#,Db,D ,D#,Eb,E ,E#,Fb,F ,F#,Gb,G ,G#")
f Filter:
ÏÄ Is index + 1
%9%8 Mod 9 Mod 8
<6 Less than 6
End filter ("Ab,A ,A#,Bb,B ,C ,C#,Db,D ,D#,Eb,E ,F ,F#,Gb,G ,G#")
-
\$\begingroup\$ Your code contains
<6but it's<5in the explanation. \$\endgroup\$TheOnlyMrCat– TheOnlyMrCat2019年08月16日 21:11:52 +00:00Commented Aug 16, 2019 at 21:11 -
\$\begingroup\$ @TheOnlyMrCat Edited \$\endgroup\$Gymhgy– Gymhgy2019年08月16日 22:35:59 +00:00Commented Aug 16, 2019 at 22:35
dzaima/APL REPL, (削除) 38 (削除ここまで) (削除) 28 (削除ここまで) 25 bytes
(⊤2056111)⌿,' b#'∘.,⍨7↑⎕A
-
\$\begingroup\$ I think that you can remove the
⎕←. \$\endgroup\$Erik the Outgolfer– Erik the Outgolfer2019年08月14日 23:22:36 +00:00Commented Aug 14, 2019 at 23:22 -
\$\begingroup\$ @EriktheOutgolfer hmm yeah, if I switch to REPL \$\endgroup\$dzaima– dzaima2019年08月14日 23:23:28 +00:00Commented Aug 14, 2019 at 23:23
-
\$\begingroup\$ Oh right, I forgot to count the
{}LOL. \$\endgroup\$Erik the Outgolfer– Erik the Outgolfer2019年08月14日 23:25:16 +00:00Commented Aug 14, 2019 at 23:25
PHP, 65 bytes
Makes the list with a loop. Items are separated by _ with a trailing separator.
for(;$l=ABCDEFG[$i++];)echo$l._.[$a="$l#_",$a.$b=$l.b_,$b][$i%3];
PHP, 43 bytes
PHP outputs anything as is, when not inside <?php and ?> tags.
Ab,A,A#,Bb,B,C,C#,Db,D,D#,Eb,E,F,F#,Gb,G,G#
Commodore C64/TheC64 Mini (probably other Commodore 8-bit BASIC variants) - 52 tokenized BASIC bytes
0?"{CTRL+N}Ab A A# Bb B C C# Db D D# Eb E F F# Gb GG#
Pressing the CTRL key plus N on the C64 keyboard goes into 'business mode' on the character set for upper/lower case characters. We may print this out in a string in one byte / token; and as we have 40 columns, the space from G to G# is not required.
We do not need to close the string in this case as it is not a multi-statemented line with a : separator.
How this looks on a Commodore C64 (and compatibles) screen is shown below.
Ruby, 43 bytes
p (2..18).map{|i|"FCGDAEB"[i%7]+"b #"[i/7]}
With the range 0..20 this would print an array containing all the flats, all the naturals and all the sharps. The undesired ones Fb Cb E# B# are omitted by using the range 2..18
The notes are printed out ordered according to https://en.wikipedia.org/wiki/Circle_of_fifths , or in other words ascending by 7 semitones (a frequency ratio of almost exactly 1.5) each time.
This leads to the note letter order given, in which each note is five degrees inclusive (known as a "fifth") above the previous one. For example F->C is FGABC
-
\$\begingroup\$ I like that you ascend by fifths. Nice. \$\endgroup\$Wayne Conrad– Wayne Conrad2019年08月17日 01:18:00 +00:00Commented Aug 17, 2019 at 1:18
Zsh, 36 bytes
<<<${${(F):-{A..G}{b,,#}}//[BE]#???}
An uglier solution, but it saves two characters. (F) joins a list on newlines, and //[BE]#??? removes the parts of the string we need.
Zsh, 38 bytes
<<<${${:-{A..G}{b,,#}}:#([BE]#|[CF]b)}
I always enjoy it when Zsh beats Perl (hopefully I don't speak too soon...).
<<<${${:-{A..G}{b,,#}}:#([BE]#|[CF]b)}
${:- } # empty-fallback, basically an anonymous parameter expansion
{A..G}{b,,#} # Cross product range A-G with b,(nothing),#
${ :# } # Remove matching elements
([BE]#|[CF]b) # B#, E#, Cb, Fb
<<< # Print to stdout
Lost, 105 bytes
v<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>
>%?"Ab A A# Bb B C C# Db D D# Eb E F F# Gb G G9円"-+@
Outputs with #b and space delimiter.
Try it online or verify that it's deterministic.
Explanation:
Explanation of the language in general:
Lost is a 2D path-walking language. Most 2D path-walking languages start at the top-left position and travel towards the right by default. Lost is unique however, in that both the start position AND starting direction it travels in is completely random. So making the program deterministic, meaning it will have the same output regardless of where it starts or travels, can be quite tricky.
A Lost program of 2 rows and 5 characters per row can have 40 possible program flows. It can start on any one of the 10 characters in the program, and it can start traveling up/north, down/south, left/west, or right/east.
In Lost you therefore want to lead everything to a starting position, so it'll follow the designed path you want it to. In addition, you'll usually have to clean the stack when it starts somewhere in the middle.
Explanation of the program:
All arrows, including the reflect \ in the string, will lead the path towards the leading > on the second line. From there the program flow is as follows:
>: travel in an east/right direction%: Put the safety 'off'. In a Lost program, an@will terminate the program, but only when the safety is 'off'. When the program starts, the safety is always 'on' by default, otherwise a program flow starting at the exit character@would immediately terminate without doing anything. The%will turn this safety 'off', so when we now encounter an@the program will terminate (if the safety is still 'on', the@will be a no-op instead).?: Clean the top value on the stack. In some program flows it's highly likely we have a partial string on the stack, so we use this to wipe the stack clean of that potential string.": Start a string, which means it will push the integer code-points of the characters used.Ab A A# Bb B C C# Db D D# Eb E F F# Gb G G9円: Push the code-points for these characters, being65 98 32 65 32 65 35 32 66 98 32 66 32 67 32 67 35 32 68 98 32 68 32 68 35 32 69 98 32 69 32 70 32 70 35 32 71 98 32 71 32 71 92 57respectively": We're done pushing code-points of this string-+: Subtract the top two values from one another: (92-57=)35@: Terminate the program if the safety is 'off' (which it is at this point). After which all the values on the stack will be output implicitly. Using the-Aprogram argument flag, these code-points will be output as characters instead.
Minor note: The top part could also have been v<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< instead. Lost will wrap around to the other side when moving in a direction. So using v<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>> could be a slightly shorter path, and since it's the same byte-count anyway, why not use it. :)
Brachylog, 36 bytes
"#b"ẹ,Ẹ↺;Ṇh7t↔{∋mc}f⟨h5ct14⟩⟨h12ct5⟩
I'm currently in the process of brute-forcing the powerset index that would let me get rid of ⟨h5ct14⟩⟨h12ct5⟩ (and by extension ↺, since the output doesn't need to be in the same order as the example output), but it's taking quite a while... maybe I should put a minute aside to actually work out what order sublists are generated in, and compute the index that way...
Pyth, (削除) 23 (削除ここまで) 21 bytes
s<R7c.>*<r1G7"b #"2 9
s<R7c.>*<r1G7"b #"2 9 Implicit: G=lowercase alphabet
r1G Convert G to upper case
< 7 First 7 characters
* "b #" Cartesian product with "b #"
.> 2 Rotate the above 2 places to the right
c 9 Chop into pieces of length 9
<R7 Trim each to length 7
s Flatten, implicit print
Edit: Partial rewrite to save 2 bytes, previous version: s%2c*<r1G7"b #"xLG"fhoq Try it online!
T-SQL, 124 bytes
SELECT value+a
FROM STRING_SPLIT('A-B-C-D-E-F-G','-')
,(VALUES('b'),(''),('#'))b(a)
WHERE value+a NOT IN ('B#','E#','Cb','Fb')
Line breaks are for display purposes only.
Longer but much more interesting than the trivial version (50 bytes):
PRINT'Ab,A,A#,Bb,B,C,C#,Db,D,D#,Eb,E,F,F#,Gb,G,G#'
Z80Golf, (削除) 31 (削除ここまで) 29 bytes
00000000: 9d5b dc6d df7f 0603 3e40 d13c cb3a 3008 .[.m....>@.<.:0.
00000010: fff5 7b2f ffaf fff1 20f1 10ec 76 ..{/.... ...v
Explanation:
Z80Golf is just a simple fantasy machine based on the Z80 8-bit CPU. The program is loaded at memory location 0x0000, and the rest of the memory is filled with zeroes. Output is done by calling 0x8000, which will output the value of register A as a character.
The program starts with the data that will be processed, 6 bytes in total. Each pair of bytes specifies a note suffix, and a bitmask controlling which of the letters can be combined with this note. To save bytes, the suffix character is inverted (xor 0xff) -- this allows the data to be executed as instructions with little side effects, making it possible to remove a jump that skips this data:
; GFEDCBA
db 0xff^'b', 0b01011011 ; Ab Bb Db Eb Gb
db 0xff^'#', 0b01101101 ; A# C# D# F# G#
db 0xff^' ', 0b01111111 ; A B C D E F G
skip_data:
This is how the CPU decodes this:
sbc a, l ; a subtraction with carry on registers we don't care about
ld e, e ; put the E register back into itself. This instruction is useless
; but still exists to make the encoding regular.
call c, 0xdf6d ; if the carry flag is set, call a function. The carry flag isn't set
; because of the initial register values (all zeroes) when the sbc above
; was executed
ld a, a ; as above, put A back into itself.
This data is read two bytes at a time into the DE register pair. The stack pointer is used to point to the next element. It starts out at 0, and because the Z80 uses a full, descending stack, any pops will read the next data pair -- all stack operations are 16-bit.
The outer loop is implemented with a decrementing counter in the B register, for which the Z80 provides special support in the form of the djnz instruction:
ld b, 3
process_pair:
...
djnz process_pair
halt
The current letter is held in the A register. Because the increment fits well at the start of the loop, we load one less than the actual start value of A:
process_pair:
ld a, 'A'-1
pop de ; D = bitmask, E = suffix character
process_note:
inc a
srl d ; put the current bitmask bit in the carry flag
; also sets the zero flag if this is the last note in the pair
jr nc, skip
; Print the note. Note that we need to preserve the zero flag to check it in the
; loop condition later.
rst 38ドル ; Short encoding of call 0038ドル.
; Because the program is so short, the memory in the 0038..8000 range
; is filled with zeroes, which happens to be the encoding for a no-op.
; The execution will therefore fall-through to the character-print hook.
push af ; Save the letter on the stack (which will be just to the left of the
; unprocessed data) to free up A for printing other characters.
; (only 16-bit register pairs can be saved, so we also push the flags)
ld a, e
cpl ; Undo the inversion used to make the execution fall-through the data.
; Done again each iteration because it takes less bytes to operate
; on the A register.
rst 38ドル ; Print the suffix.
xor a ; Standard assembly practice of setting a register to zero by XORing it
; with itself. Saves a byte over a simple `ld a, 0`.
rst 38ドル ; Print a null byte as a separator.
pop af ; Restore the current letter from the stack.
skip:
jr nz, process_note ; If the zero flag (last changed at the srl d) is not set,
; loop once again
djnz process_pair
halt
APL (Dyalog Unicode), 45 bytes
2↓(, ̈⎕A)⎕R', &'⊢'AbAA#BbBCC#DbDD#EbEFF#GbGG#'
Simple ⎕Replace operation, prepending , to each element in the string that matches each letter in the ⎕Alphabet, then dropping the first 2 characters, which are ,.
Brainfuck, 214 Bytes
>>>>++++++++[<++++<++++<++++++++++++<++++++++>>>>-]<<+++<++<+.>.>>.<<<.>>>.<<<.>>.>.<<<+.>.>>.<<<.>>>.<<<+.>>>.<<<.>>.>.<<<+.>.>>.<<<.>>>.<<<.>>.>.<<<+.>.>>.<<<.>>>.<<<+.>>>.<<<.>>.>.<<<+.>.>>.<<<.>>>.<<<.>>.>.<<<+
JavaScript (Node.js), 84 bytes
_=>[...'ABCDEFG'].map((n,i)=>`${i%3!=2?n+'b,':''}${n}${i%3!=1?`,${n}#`:''}`).join`,`
Just returning the string (as shown below) would be shorter by 36 bytes, but where's the fun in that?
_=>'Ab,A,A#,Bb,B,C,C#,Db,D,D#,Eb,E,F,F#,Gb,G,G#'
Bash 5, 42 bytes
x=`echo {A..G}{b,,#}`;echo ${x//[BE]#???/}
Output:
Ab A A# Bb B C C# Db D D# Eb E F F# Gb G G#
"C "instead of"C"? \$\endgroup\$