11
\$\begingroup\$

Background:

Pi (π) is a transcendental number, and therefore it has a non-terminating decimal representation. Similar, the representation doesn't terminate if written in any other integer base. But what if we wrote it in base π?

Digits in decimal represent powers of 10, so:

π = 3.14… = (3 * 10^0) + (1 * 10^-1) + (4 * 10^-2) + …

So in base π, the digits would represent powers of π:

π = 10 = (1 * π^1) + (0 * π^0)

In this new base, integers now have non-terminating representations. So 10 in decimal now becomes the following:

10 => 100.01022… = (1 * π^2) + (0 * π^1) + (0 * π^0) + (0 * π^-1) + (1 * π^-2) + …

Note that in base π the digits used are 0,1,2,3 because these are the digits less than π.

Challenge:

Given a non-negative integer x, either:

  1. Output (without halting) its representation in base π. If the number has a finite representation (0, 1, 2, 3), then the program may halt instead of printing infinite zeros.

  2. Take an arbitrarily large integer n, and output the first n digits of x in base π.

Rules:

  • Since a number has multiple possible representations, you must output the one that appears the largest (normalized). Just as 1.0 = 0.9999… in decimal, this problem exists in this base, too. In base π, one is still 1.0, but could also be written as 0.3011…, for example. Similarly, ten is 100.01022…, but could also be written as 30.121… or 23.202….
  • This is code-golf, so fewest bytes wins. Program or function.
  • No built-ins (I'm looking at you, Mathematica)

Results:

0       = 0
1       = 1
2       = 2
3       = 3
4       = 10.220122021121110301000010110010010230011111021101…
5       = 11.220122021121110301000010110010010230011111021101…
6       = 12.220122021121110301000010110010010230011111021101…
7       = 20.202112002100000030020121222100030110023011000212…
8       = 21.202112002100000030020121222100030110023011000212…
9       = 22.202112002100000030020121222100030110023011000212…
10      = 100.01022122221121122001111210201201022120211001112…
42      = 1101.0102020121020101001210220211111200202102010100…
1337    = 1102021.0222210102022212121030030010230102200221212…
9999    = 100120030.02001010222211020202010210021200221221010…

First 10,000 digits of ten in base Pi

Verification:

You can verify any output you want using the Mathematica code here. The first parameter is x, the third is n. If it times out, pick a small n and run it. Then click "Open in Code" to open a new Mathematica worksheet with the program. There's no time limit there.

Convert the resulting output to a number here.

Related:

\$\endgroup\$
  • 4
    \$\begingroup\$ Does "no built-ins" include no built-ins for getting Pi? \$\endgroup\$ – Nit Apr 3 '18 at 20:28
  • 3
    \$\begingroup\$ @Nit No, it means no built-in that completes or trivializes the entire task. Or if such a built-in exists (like the Mathematica one I showed), make sure to include a solution without the built-in which will be used for the answer's actual score. That way, you still get to show people that the built-in exists. \$\endgroup\$ – mbomb007 Apr 3 '18 at 20:32
  • \$\begingroup\$ Can we use a limited-precision π literal? \$\endgroup\$ – Erik the Outgolfer Apr 3 '18 at 20:52
  • \$\begingroup\$ @EriktheOutgolfer No. That will not be sufficient to arrive at correct output. Though I'm not sure how many digits are required for an input of n, I'd guess that Pi must have at least n digits of precision. \$\endgroup\$ – mbomb007 Apr 3 '18 at 21:23
  • 8
    \$\begingroup\$ IMO: Banning base conversion builtins just adds needless complexity. If you feel like it trivializes the challenge, well, maybe the challenge is just that: trivial \$\endgroup\$ – Conor O'Brien Apr 3 '18 at 23:19
1
\$\begingroup\$

Julia 0.6, 81 bytes

f(x,i=log(π,x)÷1)=(y=big(π)^i;d::Int=x÷y;print(i==0?"$d.":"$d");f(x-d*y,i-1))

Prints out digits (and the . which cost me 14 bytes) until it Stack overflows at about 22k digits on TIO. If I'm allowed to pass the input as a BigFloat I can cut 5 bytes. Makes use of the built in arbitrary precision constant π. But its a bit cooler than that, its actually an adaptive precision constant, π*1.0 is a 64 bit floating point number, π*big(1.0) (aka multiplied by an higher precision number) gives π at whatever your precision is set to.

Try it online!

\$\endgroup\$
3
\$\begingroup\$

Python 3, 471 317 310 bytes

7 bytes thanks to caird coinheringaahing.

Surely there are golfs that I missed. Feel free to point them out in the comments.

def h(Q):
	a=0;C=b=4;c=d=s=1;P=o=3
	while P^C:
		a,b,c,d,s,o,P,A,B=b,s*a+o*b,d,s*c+o*d,s+o,o+2,C,0,1
		for I in Q:B*=c;A=A*a+I*B
		C=A>0
	return P
def f(n,p):
	Q=[-n];R=""
	while h([1]+Q)<1:Q=[0]+Q
	Q+=[0]*p
	for I in range(len(Q)):
		i=3;Q[I]+=3
		while h(Q):Q[I]-=1;i-=1
		R+=str(i)
	return R[:-p]+"."+R[-p:]

Try it online!

Ungolfed version:

def poly_eval_pi_pos(poly,a=0,b=4,c=1,d=1,o=3,s=1,prev=9,curr=6):
	while prev != curr:
		a,b,c,d,s,o=b,s*a+o*b,d,s*c+o*d,s+o,o+2
		prev = curr
		res_n, res_d = 0,1
		for I in poly:
			res_d *= c
			res_n = res_n*a + I * res_d
		curr = res_n > 0
	return prev
def to_base_pi(n,precision):
	poly = [-n]
	res = ""
	while not poly_eval_pi_pos([1]+poly):
		poly = [0]+poly
	poly += [0]*precision
	for index in range(len(poly)):
		i = 3
		poly[index] += 3
		while poly_eval_pi_pos(poly):
			poly[index] -= 1
			i -= 1
		res += str(i)
	return res[:-precision]+"."+res[-precision:]

Try it online!

\$\endgroup\$
  • \$\begingroup\$ Do you require Python 3? If 2 can be used, you can use mixed spaces and tabs. \$\endgroup\$ – mbomb007 Apr 6 '18 at 16:58
  • \$\begingroup\$ @mbomb007 "golfs that i missed" do not include switching to an older version just for the sake of golfing :P \$\endgroup\$ – Leaky Nun Apr 6 '18 at 23:51
  • \$\begingroup\$ Then you could also use `i`. \$\endgroup\$ – mbomb007 Apr 7 '18 at 18:18
3
\$\begingroup\$

Ruby -rbigdecimal/math, 111 103 97 bytes

->x,n{q=BigMath::PI n;r=q**m=Math.log(x,q).to_i;n.times{$><<"#{?.if-2==m-=1}%i"%d=x/r;x%=r;r/=q}}

Try it online!

Takes input number as x and desired precision as n. Outputs by printing. Makes use of the built-in BigDecimal library for arbitrary pecision PI value.

\$\endgroup\$
  • \$\begingroup\$ built in is explicitly prohibited \$\endgroup\$ – Leaky Nun Apr 6 '18 at 9:41
  • 1
    \$\begingroup\$ See comments to the task: "- Does "no built-ins" include no built-ins for getting Pi?" "- No, it means no built-in that completes or trivializes the entire task." \$\endgroup\$ – Kirill L. Apr 6 '18 at 10:02
  • \$\begingroup\$ @LeakyNun Kirill is right. Built-ins for Pi are allowed so long as the resulting answer is correct. \$\endgroup\$ – mbomb007 Apr 6 '18 at 14:07
  • \$\begingroup\$ Don't you have to count the bytes of the command line options? I'm not sure how that works \$\endgroup\$ – mbomb007 Apr 7 '18 at 18:17
  • \$\begingroup\$ I'd say, not anymore as per this meta. Something in the lines of "consider this a kind of different language from plain Ruby". \$\endgroup\$ – Kirill L. Apr 8 '18 at 7:03
1
\$\begingroup\$

Python 3 + sympy, 144 bytes

from sympy import*
def f(n,p):
	R="";O=n and int(log(n,pi));r=pi**O
	for _ in range(O+p):R+=str(int(n/r));n%=r;r/=pi
	return R[:O+1]+"."+R[O+1:]

Try it online!

Quite slow, actually.

\$\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.