perl -MMath::BigFloat -nlpl, 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}/;$_=$&
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.+\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.