22
\$\begingroup\$

There are 88 keys on a standard piano and 95 printable ascii characters (hex codes 20 through 7E):

 !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~

('character' refers to any printable-ASCII character from here on)

In this JSFiddle I've taken advantage of that and made a simple syntax that generates piano tunes using AudioSynth. (If anyone can direct me to a linkable set of real piano note sounds I'll be grateful.)

Each character in the input string besides () 01+- corresponds to one piano key:

 CHARACTER:  !   "   #   $   %   &   '   *   ,   .   /   2   3   4   5   6   7   8   9   :   ;   <   =   >   ?   @   A   B   C   D   E   F   G   H   I   J   K   L   M   N   O   P   Q   R   S   T   U   V   W   X   Y   Z   [   \   ]   ^   _   `   a   b   c   d   e   f   g   h   i   j   k   l   m   n   o   p   q   r   s   t   u   v   w   x   y   z   {   |   }   ~
KEY NUMBER:  1   2   3   4   5   6   7   8   9  10  11  12  13  14  15  16  17  18  19  20  21  22  23  24  25  26  27  28  29  30  31  32  33  34  35  36  37  38  39  40  41  42  43  44  45  46  47  48  49  50  51  52  53  54  55  56  57  58  59  60  61  62  63  64  65  66  67  68  69  70  71  72  73  74  75  76  77  78  79  80  81  82  83  84  85  86  87  88
      NOTE:  A  A#   B   C  C#   D  D#   E   F  F#   G  G#   A  A#   B   C  C#   D  D#   E   F  F#   G  G#   A  A#   B   C  C#   D  D#   E   F  F#   G  G#   A  A#   B   C  C#   D  D#   E   F  F#   G  G#   A  A#   B   C  C#   D  D#   E   F  F#   G  G#   A  A#   B   C  C#   D  D#   E   F  F#   G  G#   A  A#   B   C  C#   D  D#   E   F  F#   G  G#   A  A#   B   C
    OCTAVE:  0   0   0   1   1   1   1   1   1   1   1   1   1   1   1   2   2   2   2   2   2   2   2   2   2   2   2   3   3   3   3   3   3   3   3   3   3   3   3   4   4   4   4   4   4   4   4   4   4   4   4   5   5   5   5   5   5   5   5   5   5   5   5   6   6   6   6   6   6   6   6   6   6   6   6   7   7   7   7   7   7   7   7   7   7   7   7   8

So RPNPRRR plays the first 7 notes of Mary Had a Little Lamb using the preset timing parameters you can see in the JSFiddle.

Space () represents a musical rest that lasts for one note interval. So RPNPRRR PPP RUU plays the first 13 notes of Mary Had a Little Lamb with rests in their proper places.

If any character besides ()01 is prefixed by a sequence of 0's and 1's (regex [01]+), that sequence is read as a binary number b, and the character is replaced with b copies of itself. So 101A11 10+1-0B01C becomes AAAAA ++-C because 101 = 5, 11 = 3, etc. (A sequence of 0's and 1's at the end of the string has no effect.)

Matched parentheses (()) serve two purposes:

  1. If their content does not end with a sequence of 0's and 1's, all the notes are played at the same time as a chord (which otherwise is no different than a note). So (NQU) is a C minor chord on octave 4.
    If duplicate notes are present their sound is also duplicated. So (NN) and (NNN) sound different.
  2. If their content does end with a sequence of 0's and 1's, that sequence is read as a binary number b, and the parentheses and their content are replaced with b copies of the content. So (NQU11) becomes 9 individual notes: NQUNQUNQU.

Parentheses Details:

  • Nesting replicating parentheses (purpose 2) is fine: (N(QU10)11)(NQUQU11)NQUQUNQUQUNQUQU.
  • Nesting non-replicating parentheses (purpose 1) is fine but has no effect: (A((+)C)) is the same as (A+C).
  • You can also combine both: ((N(QU10))11)(NQUQU)(NQUQU)(NQUQU).
  • A sequence of 0's and 1's before non-replicating parentheses repeats them in the same way individual characters are repeated. So 10(NQU) becomes (NQU)(NQU).
  • A sequence of 0's and 1's before replicating parentheses has no effect.
  • ( must always have a matching ), but not vice-versa: e.g. N) is valid.

Plus (+) and minus (-) respectively increase and decrease the the duration of notes or the time interval between notes, depending on their context:

  • When inside non-replicating parentheses, they immediately increase or decrease the note duration variable by some preset number of milliseconds (see JSFiddle). So (++)N will play N at a longer duration than normal.
  • When outside non-replicating parentheses, they increase or decrease the interval between the start of the next note and the note after it (and each subsequent interval) by some preset number of milliseconds. So in ++NP the interval between the N and P is longer than usual.

The duration of notes and the time interval between them cannot drop below 0.

Challenge

I intentionally chose () 01+- to be the 7 special characters because they can be innocuously placed in many contexts in lots of programming languages.

Your task is to write a quine in 512 bytes or less that produces the best sounding tune when the code itself is used as the input string in the JSFiddle.

You may choose any initial values (non-negative integers) for the 4 interval/duration parameters, but your tune must not last more than 10 minutes. You should also tell us if your tune sounds best in a particular instrument.

Rules

  • Only tabs, newlines, and printable-ASCII are allowed in your code. All non-printable ASCII is ignored by the tune creator.
  • Output may go to a file or stdout or the closest alternative (e.g. JS alert). There is no input.
  • No reading of source code. It must be a true quine.
  • The removal of any 3 contiguous source characters must make the program no longer function as a quine. This is to ensure people don't write a good song in a string then have a tiny quine portion to output it.
    • So if your program was MYCODE then MYC, MYE, MDE, and ODE should all not be quines (they may error or output something else).

This is a popularity-contest, the highest voted answer wins.

Update: Relaxed last rule.

\$\endgroup\$
  • 3
    \$\begingroup\$ You can play Mary Had a Little Lamb on a phone keypad, too: 3212333 222 399 (try it, it comes out perfectly.) \$\endgroup\$ – Level River St Sep 3 '14 at 11:00
  • \$\begingroup\$ There are plenty of free soundfonts for piano. Also, nice JSFiddle! \$\endgroup\$ – qwr Sep 4 '14 at 1:33
  • \$\begingroup\$ I've never seen the last rule in any challenge before, quite effective as intended, I think. \$\endgroup\$ – justhalf Sep 4 '14 at 1:55
  • \$\begingroup\$ @qwr Do you know of any sets of all 88 keys that can be directly linked in this fashion? I looked a bit but couldn't find any. \$\endgroup\$ – Calvin's Hobbies Sep 4 '14 at 1:58
6
\$\begingroup\$

C

I decided I liked the low rumbling noise generated by the string /**/ which is not-so-coincidentally the way to open and close a comment in C. The only other interesting bit here is that 34 for a " is replaced by 35-1(Ending in a 1 intentionally) to avoid god-awful chords. I also tried to make the ending sound dramatic. I really did. I intend to edit this later to make it sound a bit better.

/**/char*p= "/**/char*p= %c%s%c; int main(){printf(p,34,p,35-1);p++;/**/}/**/";
int main(){printf(p,34,p,35-1);p++;/**/}/**/

To my understanding of the rules, the commented sections still pass the final rule because their removal results in a failed quine.

\$\endgroup\$
  • 3
    \$\begingroup\$ "I intend to edit this later to make it sound a bit better." It's been almost a year. I'm starting to think you won't be editing this later to make it sound better. :P \$\endgroup\$ – Alex A. Aug 24 '15 at 2:29
  • \$\begingroup\$ @AlexA. Over a year now! \$\endgroup\$ – wizzwizz4 Oct 23 '15 at 15:58
5
\$\begingroup\$

J

Yeah, I think you can guess how this is going to go.

It's hard to get anything cool done in J without parens, and since you can rarely end them with 0s and 1s, most things sound like someone sitting on the high and low halves of the keyboard at the same time. I tried my best, I'll have you know.

Here's a funky baseline for piano, I think. I really don't know the first thing about composition, I just grabbed a quine and twiddled the numbers around a bit.

(23 23,~,~i.124+-100){,'(23 23,~,~i.124+-100){,'''

And, just for fun, play this one as EDM. I call it Japhex Twin.

".s=:'''".s=:'',''''''''&,@(,&'''''''')@(#~>:@(=&''''''''))s'

You can confirm the quineiness of these fine snippets of code at tryj.tk.

\$\endgroup\$
  • 1
    \$\begingroup\$ This actually could pass for music. Great! :) \$\endgroup\$ – Emil Sep 24 '14 at 15:48
4
\$\begingroup\$

Musique Concrete with Python

I don't have a lot of time today but I wanted to get an answer in. The genre is an excuse for not sounding like anything. Maybe a sound effect in a video game?

BFIN10=r"print('BFIN10=r\"'+BFIN10+'\"'+'\nexec(BFIN10)')"
exec(BFIN10)
\$\endgroup\$
  • \$\begingroup\$ Actually doesn't sound too bad! \$\endgroup\$ – Claudiu Sep 23 '14 at 20:25
  • \$\begingroup\$ Every Yoko Ono album ever \$\endgroup\$ – William Barbosa Sep 24 '14 at 17:32
4
+300
\$\begingroup\$

C

int(printf)(char*,...); (main)(){char*b=",*",i=(34),*m=("int(printf)(char*,...); (main)(){char*b="),
*z="%s%c%s%c,i=(34),*m=(%c%s%c)%sz=%c%s%c,*B=%c%s%c,*f=(%c%s%c)%s(/*)*/%s/*(*/);}//(+++fim)",*B="(f,
i,m,z),(i,z,m),(m,i),(f,b),(m,i),(m,i),(f,z,m),(m,i),(f,z,b),(m,i),(b,z),(B,i),(38,i),(29,B),(26,i),
(26,i),(B,f),(42,i),(i,m,f),B",*f=(";(printf)");(printf)(/*)*/(f,i,m,z),(i,z,m),(m,i),(f,b),(m,i),(m
,i),(f,z,m),(m,i),(f,z,b),(m,i),(b,z),(B,i),(38,i),(29,B),(26,i),(26,i),(B,f),(42,i),(i,m,f),B/*(*/)
;}//(+++fim)

Broken up with line breaks for presentation purposes only; this is only a quine (and only meets length requirements) if newlines are removed.

The printf declaration was needed to compile (printf). /*(*/ and /*)*/ were used to match parentheses in the code, while a mix of parentheses and the comma operator were used to form chords from the printf parameters.

Edit: Shortened to fit size requirements as well as make the piece go a bit faster.

This sounds best on the piano.

\$\endgroup\$
  • 2
    \$\begingroup\$ I like it! It starts off kind of slow but everything from token 130 onward is powerfully haunting. You used the screechiness to your advantage. \$\endgroup\$ – Calvin's Hobbies Sep 27 '14 at 1:57
  • \$\begingroup\$ This one could pass for Fantasy for Orchestra! :P \$\endgroup\$ – Soham Chowdhury Sep 27 '14 at 7:42
  • 2
    \$\begingroup\$ I liked the old version better but this is still my favorite song here. I'm trying to give you the bounty but for some reason that's not working. See meta: meta.codegolf.stackexchange.com/questions/2263/… \$\endgroup\$ – Calvin's Hobbies Sep 30 '14 at 0:49
3
\$\begingroup\$

Scheme

This may not be particularly melodic (actually it sounds like somebody dropped a dead pig into a baby-grand), but at least it is a short piece of music. It would be difficult to make anything much longer or less dead-flying-pig-like in scheme.

((lambda (x) (list x (list 'quote x))) '(lambda (x) (list x (list 'quote x))))
\$\endgroup\$
  • 1
    \$\begingroup\$ Ow, my ears.... \$\endgroup\$ – Claudiu Sep 23 '14 at 20:24
2
\$\begingroup\$

Für Golfscript

":H;GHGHCFDA;[34]H+2*{-};":H;GHGHCFDA;[34]H+2*{-};

This satisfies the letter of the no-three-consecutive-letter-removal rule, though not the intent, I gather.

\$\endgroup\$
1
\$\begingroup\$

Cobra / Batch

@number float# 2>nul||@echo off
/# 2>nul
for /f "delims=" %%a in (%0) do echo %%a
#/# 2>nul
class P# 2>nul
    def main# 2>nul
        r="# 2>nul"# 2>nul
        s="@number float{3}||@echo off{2}/{3}{2}for /f {1}delims={1} %%a in (%0) do echo %%a{2}#/{3}{2}class P{3}{2}    def main{3}{2}      r={1}{3}{1}{3}{2}       s={1}{0}{1}{3}{2}       Console.write(s,s,34to char,10to char){3}"# 2>nul
        Console.write(s,s,34to char,10to char,r)# 2>nul

Technically not a quine in Batch (it reads it's own source). It is however a quine in Cobra.

It sounds best with the piano mode, somewhat like ghost-level music from a Super Mario World-era video game.

\$\endgroup\$
1
\$\begingroup\$

Pyth

J"+K+N+J+N+\K+N+K+NJ"K"J"+K+N+J+N+\K+N+K+NJ

Best played with the fourth setting (amount + and - change interval) at around 20, rest at defaults. Sounds best on the piano.

\$\endgroup\$
0
\$\begingroup\$

Haskell

(I'm not sure whether the variable name violates the last rule.)

main=putStr$  jjlmjiebab ++ {--} show jjlmjiebab;jjlmjiebab = "main=putStr$  jjlmjiebab ++ {--} show jjlmjiebab;jjlmjiebab = "

Best played on piano with 1000 millisecond note duration and 250 millisecond note interval, with standard + and - values.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.