Note: Anders Kaseorg warns me that this could be a duplicate of another previous question. It seems so, and I'm sorry I did not find that question before posting this one. Nonetheless, that question only received one answer and this one is simpler, just in case you all want to try this time. I'll understand if this question ends up being marked as duplicate, though.
The challenge
Given an input like this:
8g 8Df 4cs 2C 1A
Write the shortest program/function that produces an output like this:
/\ -o-
| |
---|-|---------------------------------------------------|-|
|/ | |
---/|--------|\----b-*-----------------------------------|-|
/ | | | | o | |
-|--|--------|------|-----------------|------------------|-|
| (| \ | | | | | |
-|--|--)----*-------|/---------|------|------------------|-|
\ | / | | | |
-----|-------------------------|-------------------------|-|
| |
*_/ #-*-
Rules
The output must consist of a five-line staff beginning with the drawing of a G-clef exactly as shown above, aligned to the left of the staff and leaving a single column after the starting of the staff.
/\
| |
---|-|--
|/
---/|---
/ |
-|--|---
| (| \
-|--|--)
\ | /
-----|--
|
*_/
^
Single column
The notes must begin with a *
or a o
character depending on its type.
There must be exactly eight columns of separation every *
or a o
character:
/\ -o-
| |
---|-|---------------------------------------------------|-|
|/ | |
---/|--------|\----b-*-----------------------------------|-|
/ | | | | o | |
-|--|--------|------|-----------------|------------------|-|
| (| \ | | | | | |
-|--|--)----*-------|/---------|------|------------------|-|
\ | / | | | |
-----|-------------------------|-------------------------|-|
| |
*_/ #-*-
↑ ↑ ↑ ↑ ↑ ↑ ↑
8 columns of separation
The staff must end with the terminator aligned to the right as shown in the example. The left bar of the terminator must be separated 8 columns from the last note.
The input will be a single string containing the notes (at least one, no empty inputs), each one separated by a whitespace (you can consider every note will be a proper one, so no need to check for errors). You can also take the input as an array of strings, with a note per element in the array. For each note, the first character will be the denominator of the note length (1
for a whole note/semibreve, starts with o
; 2
for a half note/minim, starts with o
; 4
for a quarter note/crotchet, starts with *
; and 8
for an eighth note/quaver, starts with *
). The second character will be the note (see next table), and the third, optional character will be f
or F
for flat notes and s
or S
for sharp notes.
--- A (ledger line)
G
-------- F
E
-------- D
C
-------- b
a
-------- g
f
-------- e
d
--- c (ledger line)
Obviously, the input must respect the case for the notes, but you can choose the case of the f
and s
modifiers.
Notes c
and A
must add two -
(ledger lines), one at each side, as they must extend the staff. Notes d
and G
are out of the staff but do not need ledger lines.
Flatten or sharpened notes must add b
or #
two positions at the left of the note.
The stems (if any) must be drawn with 4 vertical bars. Notes from b
and above must draw the stem downwards and at the left side of the note. Notes from a
and below must draw the stem upwards and at the right side of the note. Quavers must add the flag, always rightwards and exactly as shown, and do not need to be beamed if there are several of them in a row.
--------------------------
-----|\----b-*------------
| | |
-----|------|-------------
| | |
----*-------|/---------|--
↑↑ |
----||------↑↑---------|--
|| || |
|| || #-*-
|\ |\ ↑↑
| Stem | Note | Stem
Note Stem Note
As usual, your program/function can directly draw the output or return a string, array of strings, matrix of characters or any other reasonable format.
Useful links
This is code-golf, so may the shortest program/function for each language win!
Bonus: try to write examples with famous melodies and let everyone try to guess which melody it is!