Integers in Base Pi

11

4

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:

mbomb007

Posted 2018-04-03T20:12:48.580

Reputation: 21 944

4Does "no built-ins" include no built-ins for getting Pi? – Nit – 2018-04-03T20:28:36.833

3@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. – mbomb007 – 2018-04-03T20:32:04.707

Can we use a limited-precision π literal? – Erik the Outgolfer – 2018-04-03T20:52:58.367

@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. – mbomb007 – 2018-04-03T21:23:53.367

@mbomb007 Well, outputs wrong only because of floating-point limitations are allowed by default, that's why I asked. – Erik the Outgolfer – 2018-04-03T21:25:55.087

@EriktheOutgolfer I gave a list of 10000 digits of ten in base Pi. If you can't arrive at that output, then your program is not correct. – mbomb007 – 2018-04-03T21:26:47.623

Related – FryAmTheEggman – 2018-04-03T22:11:38.287

8IMO: Banning base conversion builtins just adds needless complexity. If you feel like it trivializes the challenge, well, maybe the challenge is just that: trivial – Conor O'Brien – 2018-04-03T23:19:17.617

Strongly rely on real storage – l4m2 – 2018-04-04T08:48:33.547

I feel like there was a guidance against banning built-ins and instead simply not upvoting answers that were uninteresting. Anyone have a meta-link to that? – Lyndon White – 2018-04-06T09:53:27.043

@LyndonWhite I'm well aware. That's why I said people can post an answer using them, as long as they also post one without. That way they also have to do the work. We all know that people upvote short answers regardless of the recommendations. – mbomb007 – 2018-04-06T14:10:15.393

Answers

1

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!

gggg

Posted 2018-04-03T20:12:48.580

Reputation: 1 715

3

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!

Leaky Nun

Posted 2018-04-03T20:12:48.580

Reputation: 45 011

Do you require Python 3? If 2 can be used, you can use mixed spaces and tabs. – mbomb007 – 2018-04-06T16:58:57.860

@mbomb007 "golfs that i missed" do not include switching to an older version just for the sake of golfing :P – Leaky Nun – 2018-04-06T23:51:36.903

Then you could also use \i``. – mbomb007 – 2018-04-07T18:18:27.863

3

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.

Kirill L.

Posted 2018-04-03T20:12:48.580

Reputation: 6 693

built in is explicitly prohibited – Leaky Nun – 2018-04-06T09:41:58.680

1See 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." – Kirill L. – 2018-04-06T10:02:39.923

@LeakyNun Kirill is right. Built-ins for Pi are allowed so long as the resulting answer is correct. – mbomb007 – 2018-04-06T14:07:36.140

Don't you have to count the bytes of the command line options? I'm not sure how that works – mbomb007 – 2018-04-07T18:17:12.323

I'd say, not anymore as per this meta. Something in the lines of "consider this a kind of different language from plain Ruby".

– Kirill L. – 2018-04-08T07:03:57.077

1

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.

Leaky Nun

Posted 2018-04-03T20:12:48.580

Reputation: 45 011