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 π.


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 π.


  • 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)


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


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.


  • 4
    \$\begingroup\$ Does "no built-ins" include no built-ins for getting Pi? \$\endgroup\$
    – Etheryte
    Commented Apr 3, 2018 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
    Commented Apr 3, 2018 at 20:32
  • \$\begingroup\$ Can we use a limited-precision π literal? \$\endgroup\$ Commented Apr 3, 2018 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
    Commented Apr 3, 2018 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\$ Commented Apr 3, 2018 at 23:19

4 Answers 4


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):
	while P^C:
		for I in Q:B*=c;A=A*a+I*B
	return P
def f(n,p):
	while h([1]+Q)<1:Q=[0]+Q
	for I in range(len(Q)):
		while h(Q):Q[I]-=1;i-=1
	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:
		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!

  • \$\begingroup\$ Do you require Python 3? If 2 can be used, you can use mixed spaces and tabs. \$\endgroup\$
    – mbomb007
    Commented Apr 6, 2018 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
    Commented Apr 6, 2018 at 23:51
  • \$\begingroup\$ Then you could also use `i`. \$\endgroup\$
    – mbomb007
    Commented Apr 7, 2018 at 18:18

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.

  • \$\begingroup\$ built in is explicitly prohibited \$\endgroup\$
    – Leaky Nun
    Commented Apr 6, 2018 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.
    Commented Apr 6, 2018 at 10:02
  • \$\begingroup\$ @LeakyNun Kirill is right. Built-ins for Pi are allowed so long as the resulting answer is correct. \$\endgroup\$
    – mbomb007
    Commented Apr 6, 2018 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
    Commented Apr 7, 2018 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.
    Commented Apr 8, 2018 at 7:03

Julia 0.6, 81 bytes


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!


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.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.