# Music with pi and e

Because I forgot to celebrate Pi Day (14.3), let's celebrate with $$\\pi\$$, $$\e\$$ (Euler's number) and music!

## Challenge

No, we don't have time to eat a pi-pizza, let's make a program.
What you need is $$\500\$$ digits of $$\\pi\$$, and $$\10\$$ digits of $$\e\$$.

The input is an integer $$\n\$$ between $$\0\$$ and $$\499\$$ inclusive.

Then you should loop through the first $$\n\$$ digits of $$\\pi\$$:

If the digit is:

• $$\0\$$ then the note is C
• $$\1\$$ then the note is D
• $$\2\$$ then the note is E
• $$\3\$$ then the note is F
• $$\4\$$ then the note is G
• $$\5\$$ then the note is A
• $$\6\$$ then the note is B
• $$\7\$$ then the note is C'
• $$\8\$$ then the note is D'
• $$\9\$$ then the note is E'

Next, for each digit in $$\\pi\$$, take a digit from $$\e\$$ based on this mapping:

• If the digit from $$\\pi\$$ is $$\0\$$, take the $$\1\$$st digit from $$\e\$$
• If the digit from $$\\pi\$$ is $$\1\$$, take the $$\2\$$st digit from $$\e\$$
• If the digit from $$\\pi\$$ is $$\2\$$, take the $$\3\$$st digit from $$\e\$$
• etc.

You need only $$\10\$$ digits of $$\e\$$, because the digits in $$\\pi\$$ are between $$\0\$$ and $$\9\$$.

Finally, take the note and the digit from $$\e\$$. Return a tuple (or equivalent) containing:

• the note
• the $$\e\$$ digit divided by $$\4\$$ (representing the beat)

## Test cases

In:10
Out:
('D', 0.25)
('G', 2.0)
('D', 0.25)
('A', 0.25)
("E'", 1.0)
('E', 2.0)
('B', 2.0)
('A', 0.25)
('F', 0.5)
('A', 0.25)
In:5
Out:
('D', 0.25)
('G', 2.0)
('D', 0.25)
('A', 0.25)
("E'", 1.0)



### Help

Here are $$\500\$$ digits of $$\\pi\$$:

3.14159265358979323846264338327950288419716939937510582097494459230781640628620899862803482534211706798214808651328230664709384460955058223172535940812848111745028410270193852110555964462294895493038196442881097566593344612847564823378678316527120190914564856692346034861045432664821339360726024914127372458700660631558817488152092096282925409171536436789259036001133053054882046652138414695194151160943305727036575959195309218611738193261179310511854807446237996274956735188575272489122793818301194912


And $$\10\$$ digits of $$\e\$$:
2.7182818284


Note that '3.' and '2.' don't count in the digits of $$\\pi\$$ and $$\e\$$, and that we are using $$\0\$$ indexing (so the $$\0\$$th digit of $$\\pi\$$ is $$\1\$$ etc.).

## Rules

• This is so the shortest answer wins.
• Optional; After every tuple or list output, there can be a trailing newline.

# Python 2, 526 bytes

def music_maker(n):
i=p=1;x=3*100**n
while x:x=x*i/-~i/4;i+=2;p+=x/i
pi_number=str(p)[:-1] #First 3 lines calculates Calculate Pi
euler='7182818284'
del x,i,p #You don't need those Variables any more. They were ment for calculating
for i in range(n):
current_pi = pi_number[i] #Current Pi
current_e = euler[int(current_pi)] #Current e
number_to_note = {0:"C", 1:"D",2:"E",3:"F",4:"G",5:"A",6:"B",7:"C'",8:"D'",9:"E'"} #Dict number to note
print((number_to_note[int(current_pi)], int(current_e)/4)) #Prints result


Try it online!

• Here's a dict:{0:"C", 1:"D",2:"E",3:"F",4:"G",5:"A",6:"B",7:"C'",8:"D'",9:"E'"} Commented Jul 9, 2020 at 10:42
• Great, it looks ok now, so I've upvoted and deleted my comment. :) Commented Jul 9, 2020 at 10:49
• Need clarification: you say that this is to use 0 based indexing, so an input of 0 would result in 1 note output, but your examples use 1 based indexing (input of 10 yields 10 results), so which is it? Commented Jul 9, 2020 at 22:04
• Will we be able to hear what it looks like? Commented Jul 10, 2020 at 8:02
• @Tanmay for code-golf it's not ogligatory to declare a winner, as there are multiple languages that obviously cannot compete in length (while still pretty interesting to golf), but if you want to accept one, usually it's recommended to wait at least a week. But don't forget to upvote any number of answers you think deserve it! Commented Jul 10, 2020 at 9:24

# JavaScript (Node.js),  150 ... 134  133 bytes

Saved 3 bytes thanks to @KevinCruijssen

Expects a BigInt as input and prints the music to STDOUT. This also works for $$\n>500\$$.

n=>{for(k=p=1n,x=3n*100n**n;x;p+=x/k)x=x*k++/k++/4n;for(;x<n;)console.log('CDEFGABCDE'[d=(p+'')[x++]]+" '"[d/7|0]+'7182818284'[d]/4)}


Try it online!

## How?

### Part 1: compute $$\n\$$ digits of $$\\pi\$$

This is based on the following formula:

$$\pi-3=\sum_{n=1}^{\infty}\frac{3}{4^n}\left(\prod_{k=1}^{n}\frac{2k-1}{2k}\right)\times\frac{1}{2n+1}$$

Instead of using floats -- whose precision is obviously far too limited -- we use a Big Integer $$\x\$$ initialized to $$\3\$$ times a large enough power of $$\10\$$ and process integer divisions until we have $$\x=0\$$.

For 500 digits, we could just use $$\x=3\cdot10^{503}\$$. We instead start with $$\x=3\cdot100^n\$$, which is more than enough to get $$\n\$$ correct digits and easier to golf.

for(                    // loop:
k = p = 1n,           //   start with k = p = 1
x = 3n * 100n ** n;   //   start with x = 3 * 100 ** n
x;                    //   stop when x = 0
p += x / k            //   add x / k to p after each iteration
)                       //
x =                   //   update x to:
x * k++ / k++ / 4n  //     x * k / (k + 1) / 4 (and increment k twice)


### Part 2: convert to music notes

for(; x < n;)           // repeat as many times as requested:
console.log(          //   print:
'CDEFGABCDE'[       //     string of notes
d = (p + '')[x++] //     d = x-th digit of pi, extracted from p
] +                 //
" '"[d / 7 | 0] +   //     append a quote if d is greater than or equal to 7,
//     or a space otherwise
'7182818284'[d]     //     get the d-th digit of e (using Math.E would be longer)
/ 4                 //     and divide it by 4 for the beat
)                     //   end of console.log()

• -3 bytes by removing k=0 and reusing x in the second part, since it's already 0 after the loop in the first part: 134 bytes. Commented Jul 9, 2020 at 14:58

# 05AB1E, 33 30 bytes

LεAuS7£ÀÀD3£''««žsyè©èžt¦®è4/‚


Outputs as a list of pairs in the ["string-note", beat-decimal] format.

Try it online.

Explanation:

L                # Push a list in the range [1, (implicit) input]
ε               # Map each integer to:
Au             #  Push the uppercase alphabet
S            #  Convert it to a list of characters
7£          #  Only leave the first 7: ["A","B","C","D","E","F","G"]
ÀÀ        #  Rotate it twice towards the left: ["C","D","E","F","G","A","B"]
D       #  Duplicate it
3£     #  Only leave the first 3 character of this copy: ["C","D","E"]
''«  #  Append a "'" to each: ["C'","D'","E'"]
« #  Merge the two lists together:
#   ["C","D","E","F","G","A","B","C'","D'","E'"]
žs             #  Push an infinite list of pi-digits: [3,1,4,1,5,...]
yè           #  Index the current integer into it (0-based, so leading 3 is skipped)
©          #  Store it in variable ® (without popping)
è         #  Index this pi-digit into the notes string-list
žt             #  Push an infinite list of e-digits: [2,7,1,8,2,...]
¦            #  Remove the leading 2
®           #  Push the pi-digit from variable ®
è          #  Index it into the infinite list of decimal e-digits
4/        #  Divide it by 4
‚              #  Pair the pi-note and e-digit/4 together
# (after which the resulting list of pairs is output implicitly)


# Wolfram Language (Mathematica), 97 bytes

Print[C[D,E,F,G,A,B,"C'","D'","E'"][[#]]|R[E,10,2+#][[1,-1]]/4]&/@#&@@R[Pi,10,#,-1]&
R=RealDigits


Try it online!

Prints notes as [key] | [duration], with one note per line.

Since Mathematica's number->string functions are so bulky (FromCharacterCode, anyone?), hardcoding the keys' names as symbols seems to be shorter.

# Perl 5-Mbignum=bpi, 86 84 bytes

say+(C..G,A..E)[$_],"'"x($_>6),$",((exp 1)=~/./g)[$_+3]/4for(substr bpi<>+1,2)=~/./g


Try it online!

## How?

for               # loop over
(substr         # a substring of
bpi<>+1,     #   PI to the appropriate number of decimals
2)           #   starting after the second character
=~/./g          # split into characters

say+              # output
(C..G,A..E)[$_], # the note letter "'"x($_>6),       # a ' if it is in the next octave higher
$", # a space ((exp 1) # Euler's number =~/./g) # split into characters [$_+3]            # skipping the first 3 (2.7)
/4                # divided by 4 beats


# Charcoal, 52 bytes

Ｐ×φψ¤≕Pi→→≔ＥＫＤＮ→Ｉιθ⎚Ｅθ⁺⁺⁺§…α⁷⁺²ι×'›ι⁶ ∕Ｉ§⪫74×²1828ι⁴


Try it online! Link is to verbose version of code. Actually works up to n=998. Explanation:

Ｐ×φψ¤≕Pi


Charcoal apparently has a built-in for π, but unfortunately the only way I know how to use it is copied from the Charcoal answer to Bake a slice of Pi which involves using it as a flood fill. Here I just output 1,000 null characters which therefore gives me 998 decimals of π, well above the 499 required by the challenge.

→→≔ＥＫＤＮ→Ｉιθ


Now input the number of decimals required, read them from the canvas, and convert them to integers.

⎚


Clear the canvas ready for the actual output.

Ｅθ⁺⁺⁺


Map over the digits and concatenate...

§…α⁷⁺²ι


... the first 7 letters of the uppercase alphabet, cyclically indexed by 2 more than the digit...

×'›ι⁶


... an ' if the digit is greater than 6...

 

... a space...

∕Ｉ§⪫74×²1828ι⁴


... and the appropriate digit divided by 4, taken from the string 7182818284, constructed by doubling the string 1828 and inserting it into the string 74.

# Python 2, 173164162156150149143 141 bytes

def f(n):
i=p=1;x=3*100**n
while x:x=x*i/-~i/4;i+=2;p+=x/i
while x<n:i=int(p[x]);print"CDEFGAB"[i%7]+"'"[i<8:],1907986849/9**i%9/4.;x+=1


Try it online.

Prints the pairs newline-delimited to STDOUT in the format string-note beat-decimal (space-delimited).

Port of @Arnauld's JavaScript answer, so make sure to upvote him!
-6 bytes thanks to @ovs, which opened up -6 more bytes by switching to Python 2
-1 byte thanks to @Arnauld
-2 bytes thanks to @Tanmay

• You don't need the second colon in the slice without a step and 1907986849//9**d%9/4 is a little shorter than int('7182818284'[d])/4.
– ovs
Commented Jul 9, 2020 at 14:15
• @ovs Thanks! Now that I don't use := as much anymore, it's also shorter in Python 2 with int(p[k]) and regular / instead of //. Commented Jul 9, 2020 at 14:45
• 159 bytes Commented Jul 9, 2020 at 17:02
• @Tanmay Thanks for the -1 byte (and an additional -1 by removing the space between print"). :) But next time please leave a comment with the golfing suggestion instead of editing someone else's answer. Commented Jul 9, 2020 at 18:45
• Guess we were out of sync somehow - did it on my phone. :( Commented Jul 9, 2020 at 21:50

# Vyxal, 29 bytes

ƛkAf7Ẏ2Ǔ:3Ẏ\'vJJn∆iin∆i›∆ė4/"


Port of 05AB1E. If it can't output rationals instead of decimals, add øḋ before ". Then it will be as strings.

## How?

ƛkAf7Ẏ2Ǔ:3Ẏ\'vJJn∆iin∆i›∆ė4/"
ƛ                              # For each item n in the (implicit) inclusive one range of the (implicit) input
kA                            # Push the uppercase alphabet
f                           # Convert to list of characters
7Ẏ                         # Leave only the first seven letters: ["A","B","C","D","E","F","G"]
2Ǔ                       # Rotate left twice: ["C","D","E","F","G","A","B"]
:                      # Duplicate
3Ẏ                    # Leave only the first three letters of the duplicate: ["C","D","E"]
\'vJ                # Append a single quotation mark to each letter: ["C'","D'","E'"]
J               # Join these two lists together: ["C","D","E","F","G","A","B","C'","D'","E'"]
n∆i            # Get the nth (zero-indexed) digit of pi
i           # Index this into the list of notes
n∆i        # Get the nth pi digit again
›       # Increment it
∆ė     # Get the zero-indexed E digit from that
4/   # Divide by four
"  # Pair the pi-note and e-digit/4 together


# perl -MMath::BigFloat -pl, 170 bytes

$n=$_;$p=new Math::BigFloat;$p->accuracy(500);$_=$p->bpi;s/..//;s!.!'('.substr(CDEFGABCDE,$&,1).("'"x($&>6)).', '.((substr 7182818284,$&,1)/4).")\n"!eg;/(.+\n){$n}/;$_=$&


Try it online!

## How does this work?

$n =$_;


This gets the input (which is in $_ due to the -p switch; the -l switch removes the newline). $p = new Math::BigFloat;
$p -> accuracy (500);$_ = $p -> bpi; s/..//;  This gets us the 500 required digits from $$\\pi\$$. First we create a Math::BigFloat object, give it an accuracy of 500 (so, 500 decimals behind the comma). We then query the object to get $$\\pi\$$, which we store in $_. And we then remove the first two characters, to set rid of the leading 3..

s !.!
'(' .    substr (CDEFGABCDE, $&, 1) . ("'" x ($& > 6)) .
', ' . ((substr  7182818284, $&, 1) / 4) . ")\n" !eg  This does the majority of the work. We take each digit of $$\\pi\$$ and replace it with the result of the middle three lines of code above. During the replacement, the digit being replaced is in $&. We start with an opening paren, then we look up the note by using the current digit as in index into a string (substr (CDEFGABCDE, $&, 1). If the digit is greater than 6, we need to add a prime (("'" x ($& > 6))). We then add a comma. Then, to get the beat, we index into the digits of $$\\epsilon\$$, and divide by four (((substr 7182818284, $&, 1) / 4)). Finally, we add an closing paren and a newline. /(.+\n){$n}/;
$_ =$&


This trims the resulting string to the desired length. We're grabbing n times a group of non-newline characters followed by a newline character, and store the result into \$_, which gets printed due to the -p command line switch.