Music with pi and e
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()
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)
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