Code Golf Asked on October 27, 2021
Because I forgot to celebrate Pi Day (14.3), let’s celebrate with $pi$, $e$ (Euler’s number) and music!
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:
C
D
E
F
G
A
B
C'
D'
E'
Next, for each digit in $pi$, take a digit from $e$ based on this mapping:
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:
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)
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.).
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
Print[C[D,E,F,G,A,B,"C'","D'","E'"][[#]]|R[E,10,2+#][[1,-1]]/4]&/@#&@@R[Pi,10,#,-1]&
R=RealDigits
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.
Answered by att on October 27, 2021
-Mbignum=bpi
, say+(C..G,A..E)[$_],"'"x($_>6),$",((exp 1)=~/./g)[$_+3]/4for(substr bpi<>+1,2)=~/./g
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
Answered by Xcali on October 27, 2021
$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}/;$_=$&
$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.
Answered by Abigail on October 27, 2021
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
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
Answered by Kevin Cruijssen on October 27, 2021
P×φψ¤≕Pi→→≔EKDN→Iιθ⎚Eθ⁺⁺⁺§…α⁷⁺²ι×'›ι⁶ ∕I§⪫74ײ1828ι⁴
Try it online! Link is to verbose version of code. Actually works up to n=998
. Explanation:
P×φψ¤≕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.
→→≔EKDN→Iιθ
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.
Eθ⁺⁺⁺
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...
∕I§⪫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
.
Answered by Neil on October 27, 2021
LεAuS7£ÀÀD3£''««žsyè©èžt¦®è4/‚
Outputs as a list of pairs in the ["string-note", beat-decimal]
format.
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)
Answered by Kevin Cruijssen on October 27, 2021
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)}
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)timesfrac{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=3cdot10^{503}$. We instead start with $x=3cdot100^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)
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()
Answered by Arnauld on October 27, 2021
Get help from others!
Recent Answers
Recent Questions
© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP