Digging around in the depths of your temp folder, you find some compositions for the piano. Unfortunately, these compositions were written with note names and durations only, and you only have access to a text terminal. Therefore, your task is to write a program to display the compositions as ASCII art.
Input
Your program should accept two strings as input. The first string will represent the notes of the top staff (with the treble clef), while the second string will represent the notes of the bottom staff.
The notes will be passed in scientific pitch notation. The top staff's notes will always be between C4
and C6
inclusive. The bottom staff's notes will always be between C2
and C4
inclusive.
Each note will come with a duration, which will be one of: 1
, 2
, 4
, 8
. These represent a whole note (semibreve), a half note (minim), a quarter note (crotchet), and an eighth note (quaver) respectively.
Notes of any other duration will never appear in the input.
How the note and duration is separated, and how each note is separated from other notes in the input is up to your discretion. The following is a sample input for the top staff:
E4/4 A4/8 C#5/8 E5/2
Here, the notes are separated by a space, and the duration is separated from the note with a forward slash. These delimeters are not fixed, and you may choose to change them or omit them altogether.
You may assume there is at least one note in each staff. There are no rests in the input.
Output
Your program is to output the score as ASCII art, conforming to the following descriptions.
The clefs should be the first thing at the left of your output (the distance between the two staves should not be changed):
^
| |
------|/----
/
-----/|-----
/ |
---/--__----
| / \
---\-\|-|---
\ | /
------|-----
|
\_/
----___-----
/ \ |
---\---|----
| |
-------/----
/
-----/------
------------
A note's stem (the vertical line next to the circle) should point upwards if the note is below the middle line of a staff. It should point downwards if the note is above the middle line of a staff. If the note is on the middle line, then the stem may point in either direction. (The only exception to this is for the bonus, and occurs when connecting eighth notes, described later). The stem should begin on the line above/below the circle, and be 6
lines tall.
All types of notes except whole notes have stems. The flag of an eighth note is represented by two forward slashes on different lines (see example notes below).
A filled in note head (for quarter and eighth notes) is represented by (@)
. An empty note head (for half and whole notes) is represented by ( )
.
Accidentals (sharps, flats, naturals) should be placed as shown in the example notes, with exactly one character between the right side of the accidental and the left side of the note head.
Ledger lines should be used when necessary, and should be 7
characters in length, centered around the note head.
Each note should be 12
characters wide.
Example notes:
|_
|_| ( )
| |------
|
------------ ---------|-- ------------ ------------ ------------
|
------------ ---------|-- ---|-------- ------------ ------------
(@) _|_|_ | |_
-----|------ _|_|_-( )--- ---|/-(@)--- ------------ ---------|\-
| | | | | \
-----|------ ------------ -----|------ ------------ ---------|--
| | |
-----|------ ------------ -----|------ ------------ ---------|--
| | / |
|/ --(@)--
quarter note half note eighth note whole note eighth note
sharped flatted natural
After the 12-character note, leave 2 * 12 - 12 = 12
characters blank (either or
-
depending on the line) if the note is a quarter note. If the note is a half note, leave 4 * 12 - 12 = 36
characters blank. If the note is a whole note, leave 8 * 12 - 12 = 84
characters blank. Do not add extra characters for eighth notes.
At the end of each measure (96 characters after either the clef or bar line), output a bar line. This is done by going down every character between the uppermost and bottom-most lines (inclusive), and replacing with
|
and -
with +
. (See example output at bottom of question).
At the end of the piece, output the music end by outputting 3 bar lines in a row, but with a space between the first and second. That is:
+-++
| ||
+-++
| ||
. ..
. ..
Note that sharps, flats, and naturals last until the end of the measure. The natural sign should only be used to cancel out a sharp or flat used earlier in the same measure.
For the purpose of this task, sharps, flats, and naturals only affect a note in one octave, and in one clef (a sharp on A5 does not cause A4 to be sharped, and a flat on C4 in the top staff does not cause C4 in the bottom staff to be flatted).
Information for the bonus only
The bonus involves properly connecting eighth notes.
When there are two consecutive eighth notes, aligned to the quarter note beat (in other words, the number of characters before the first eighth note is a multiple of 24), the two eighth notes are to be connected.
Let note A be the note farthest from the middle of the staff. If both notes are the same distance from the middle, either note may be note A. Let the other note be note B.
The direction of both stems should be the direction of the stem of note A.
The stem of one of the notes should be 6
lines tall (as is the case for stems in general), and the stem of the other note should be extended to the end of the stem of the other note.
The stems should be connected with _
.
Example connected eighth notes:
___________
| |
| |
| |
| | --(@)--
| | | |
------------------------ ---|_----|-----------|-- -----|------------------
|/ (@) | | |_
------------------------ ---------------------|-- -----|--------|_|-(@)---
(@) _|_|_ | | ||
-----|------_|_|_-(@)--- ---------------------|-- -----|-----------|------
| | | | | | |
-----|-----------|------ ---------------------|-- -----|-----------|------
| | | | |
-----|-----------|------ ------------------(@)--- -----|___________|------
| |
|___________|
Example input and output
Input:
A#4/4 G#4/4 F#4/2 A#4/4 G#4/4 F#4/2 F#4/8 F#4/8 F#4/8 F#4/8 G#4/8 G#4/8 G#4/8 G#4/8 A#4/4 G#4/4 F#4/2
A#3/4 G#3/4 F#3/2 A#3/4 G#3/4 F#3/2 F#3/2 G#3/2 F#3/4 E#3/4 F#3/2
Output:
^
| | | | |
------|/-------------|-----------------------|--------------------------------------------------------------+---------|-----------------------|--------------------------------------------------------------+----------___________-------------___________------------|\----------|\----------|\----------|\-+---------|-----------------------|--------------------------------------------------------------+-++
/ | | | | | | | | | | | | | \ | \ | \ | \| | | | | ||
-----/|--------------|-----------------------|-----------------------|--------------------------------------+---------|-----------------------|-----------------------|--------------------------------------+---------|-----------|-----------|-----------|-----------|-----------|-----------|-----------|--+---------|-----------------------|-----------------------|--------------------------------------+-++
/ | | | | | | | | | | | | | | | | | | | | | | ||
---/--__----_|_|_----|-----------------------|-----------------------|--------------------------------------+_|_|_----|-----------------------|-----------------------|--------------------------------------+---------|-----------|-----------|-----------|-----------|-----------|-----------|-----------|--+_|_|_----|-----------------------|-----------------------|--------------------------------------+-++
| / \ _|_|_ (@) _|_|_ | | |_|_|_ (@) _|_|_ | | | | | | | _|_|_ | | | | |_|_|_ (@) _|_|_ | | | ||
---\-\|-|----|-|--------------------_|_|_-(@)---------------_|_|_----|--------------------------------------+-|-|--------------------_|_|_-(@)---------------_|_|_----|--------------------------------------+_|_|_----|-----------|-----------|-----------|--_|_|_-(@)---------(@)---------(@)---------(@)---+-|-|--------------------_|_|_-(@)---------------_|_|_----|--------------------------------------+-++
\ | / | | _|_|_ ( ) | | | _|_|_ ( ) |_|_|_ (@) (@) (@) (@) | | | | | _|_|_ ( ) | ||
------|------------------------------------------------------|-|--------------------------------------------+-------------------------------------------------|-|--------------------------------------------+-|-|--------------------------------------------------------------------------------------------+-------------------------------------------------|-|--------------------------------------------+-++
| | | | | ||
\_/ | | | | ||
| | | | ||
| | | | ||
| | | | ||
| | | | ||
_|_|_ |_|_|_ | | | ||
----___-----_|_|_-(@)---------------_|_|_-------------------------------------------------------------------+_|_|_-(@)---------------_|_|_-------------------------------------------------------------------+------------------------------------------------_|_|_-------------------------------------------+------------------------------------------------------------------------------------------------+-++
/ \ | | | | _|_|_ (@) _|_|_ | | | | _|_|_ (@) _|_|_ |_|_|_ _|_|_ ( ) |_|_|_ | ||
---\---|---------|-------------------|-|-|------------------_|_|_-( )---------------------------------------+-----|-------------------|-|-|------------------_|_|_-( )---------------------------------------+_|_|_-( )----------------------------------------|-|-|------------------------------------------+_|_|_ (@)---------------_|_|_-------------------------( )---------------------------------------+-++
| | | | | | | | | | | | | | | | | | | | | | _|_|_ (@) | | ||
-------/---------|-----------------------|-----------------------|------------------------------------------+-----|-----------------------|-----------------------|------------------------------------------+-----|-----------------------------------------------|------------------------------------------+-----|-------------------|-|-|-----------------------|------------------------------------------+-++
/ | | | | | | | | | | | | | | | ||
-----/-----------|-----------------------|-----------------------|------------------------------------------+-----|-----------------------|-----------------------|------------------------------------------+-----|-----------------------------------------------|------------------------------------------+-----|-----------------------|-----------------------|------------------------------------------+-++
| | | | | | | | | | | | | ||
-----------------------------------------------------------------|------------------------------------------+-----------------------------------------------------|------------------------------------------+-----|------------------------------------------------------------------------------------------+-----|-----------------------|-----------------------|------------------------------------------+-++
|
For the sake of demonstration, in the third measure, the F#
eighth notes are connected, whereas the G#
eighth notes are not. Your program should either connect the eighth notes whenever applicable (for the bonus), or leave them all disconnected.
Other information
- Any amount of trailing whitespace/lines is acceptable.
- There should be no extra whitespace before the clefs, nor whitespace between notes. Any number of blank lines may be emitted before/after the output.
- The bonus for connecting eighth notes is 0.75 * number of bytes of source code.
- This is code-golf, so shortest code wins.