What is the first 12-digit sequence in the duodecimal expansion of pi that contains each digit exactly once?
I found the first instance of 12 unique digits in a row to begin at the 1974th digit after the decimal point:
... 87A63104529B ...
Python has a library to obtain many digits of pi (for base 10).
The code for this is:
from mpmath import mp
mp.dps = N (where N is the number of digits, including the initial 3 but not counting the decimal point).
then
str(mp.pi) represents a string variable containing '3.1415...'
Algorithm to convert digits after the decimal point to base 12:
* start with the base 10 version in list (or array) form
* multiply that by 12 and whatever spills over to the left of the decimal point becomes the next digit in base 12
* repeat with only the part after the decimal point.
But there is a problem with accuracy in the last 7.3 percent of the digits, since base 12 needs fewer digits by a factor of log(12,10) = approx. 1.079. So if you want n accurate digits, calculate n*1.08 or so digits and then just use the first n. I computed n*1.1 digits in base 12 and kept the first n.
I used some functions I wrote in the past related to addition and multiplication of large numbers.
Disclaimer: The accuracy is subject to Python's library (probably not much risk of an error), my conversion to base 12, and several programs.
First 2000 digits of pi in base 12 after the "decimal" point:
184809493B918664573A6211BB151551A05729290A7809A492
742140A60A55256A0661A03753A3AA54805646880181A36830
83272BBBA0A370B12265529A828903B4B256B8403759A71626
B8A54687621849B849A8225616B442796A31737B229B239148
9853943B8763725616447236B027A421AA17A38B52A18A838B
01514A51144A23315A3082B3659717955B491A052B34828773
A479787BA72988B537A395311B8428B2022B856AA41982B591
8509B2335680635710402042591A264A474590BB443425A223
624904A501794A972855B3537431A522AB6758A36104279922
32B041691B230B32A633855B88468330174B2094A917B311B9
4AB9959B496B08260A78B62136A72636A199A848861409165A
60B45309369AB885434386057A7896164B6376B975505B0595
B0588A1BB538B036A559647593B9655069B0630542A176057B
82242B5B646722497B73A6A4296A65145642B7382573B318B0
30696962302A60416346A811470188A197B61AA34A37B67474
3105481B95225BB75242A53217923A841AB1202848B33B025A
227A49A3B705491B570BA77AA107430A258482A7915431B899
A39590AB8A956619B8186409537A8A3B365B1BA9333219085B
6A416A8AA1744B134A5999050A5168B4A9576B984527BB71A0
9198B89205BB6B867780151096416691280929B2869516A479
7274239850409306B7025916BB19BA295BB8969189110382AB
74921A5540B495547320310968302159B1801797AAA51AA31B
6B5A1A4991581116A9B1A0ABB7236181790459911617753291
08567797889720521A90A9881461B271B51BA1726484198982
085A8690280A75630984963333411A0BB47BA86B28356210A7
67A15A44544840807222B780952519547848BA618A80326851
57B9AB7555035A850874107995AA11B3583491557B1A4730B2
48897647546B474936726ABA763118101486B915B541B98575
6212191A03A2AA2B910A2041931A9855219B0A2BB516323642
73337A8497164575146B8A9873826A891214B30A191B5111B2
8AB6B63621A43BA574AA473760617070867324B38BA628696A
115A9069779683112403BAA69336650745A253829A3820925A
50480196268868A040387A1836649B86B1554120716B445939
B31242691B45968903BA845320628A5495805429135A942682
22BBB03B8B5470B76757B2A8B58850474015662875746914B6
2B61491A8395B30517021A77356221826A3862B7268A99B7A4
816282290420A9156864B55737492A28B9781507B401AA166A
932612476192099A964B88949806AA898896AA94411A06649B
28A89359A576657721A9344219B61B542B9761099019978527
04954930959A2737885763987A63104529B2AB579A7A012B47
-----------------------------
def type_parser(n):
""" input n which can be an integer, a string, a list of integers
or a list of strings of integers;
returns a list of integers """
if type(n) == int:
ans = [int(x) for x in str(n)]
if type(n) == str:
ans = [int(x) for x in n]
elif type(n) == list:
if type(n[0]) == int:
ans = n[:]
elif type(n[0]) == str:
ans = [int(x) for x in n]
return un_bloat(ans)
def un_bloat(l): # l is the lowercase letter L
""" l is a list of integers some of which are more than one digit
need to be just single digit entries in the list
so this function moves all the carries to the left
outputting a list of single digit integers """
rev_l = l[::-1]
rev_l.append(0)
for i, val in enumerate(rev_l[:-1]):
rev_l[i+1] += rev_l[i]//10
rev_l[i] = rev_l[i] % 10
size_of_last_entry = len(str(rev_l[-1]))
while size_of_last_entry > 1:
rev_l.append(0)
rev_l[-1] += rev_l[-2]//10
rev_l[-2] = rev_l[-2] % 10
size_of_last_entry -= 1
return rev_l[::-1]
def digit_multiply(n,i):
""" n is a list of integers and i is a single digit """
n = type_parser(n)
if i == 0:
ans = [0 for x in n]
elif i == 1:
ans = n[:]
else:
bloat_ans = [i*x for x in n]
return un_bloat(bloat_ans)
return ans
def add2lists(a,b):
""" a and b are lists of integers, output a list of integers
representing their sum """
if len(a) > len(b):
ans = a[:]
shorter = b[:]
else:
ans = b[:]
shorter = a[:]
diff = len(ans) - len(shorter)
for i in range(diff):
shorter.insert(0,0)
for i,val in enumerate(shorter):
ans[i] += val
return un_bloat(ans)
def strip_left(aList):
if aList[0] != 0:
return aList
else:
del aList[0]
return strip_left(aList)
return
def large_multiply(n,m):
top = type_parser(n)
bot = type_parser(m)
running_sum = []
for i, val in enumerate(reversed(bot)):
one_line = top[:]
for repeat_number in range(i):
one_line.append(0)
running_sum = add2lists(running_sum,digit_multiply(one_line,val))
return strip_left(un_bloat(running_sum))
def convertToAlpha(aList):
""" convert a list of integers 0 to 11 into a string of duodecimal digits """
alpha = []
for i,v in enumerate(aList):
if v < 10:
alpha.append(str(v))
elif v == 10:
alpha.append('A')
elif v == 11:
alpha.append('B')
else:
print('error making alpha character at index', i)
return ''.join(alpha)
# ****** MAIN PROGRAM ******
big = 2000
bigger = int(big*1.08)
from mpmath import mp
mp.dps = bigger + 1
p10 = list(str(mp.pi)[2:])
p10i = [int(i) for i in p10]
result = []
long = p10i[:] # a copy
for i in range(big):
longer = large_multiply(long,12)
diffsize = len(longer) - len(long)
if diffsize <= 0:
result.append(0)
long = longer
continue
if diffsize == 1:
newdigit = int(longer[0])
result.append( newdigit )
long = longer[1:]
if diffsize == 2:
newdigit = 10 * int(longer[0]) + int(longer[1])
if newdigit > 11:
print(i,'newdigit too big')
result.append( newdigit )
long = longer[2:]
if diffsize > 2:
print(i,'too long')
trunk = result[:big]
found = False
for i,v in enumerate(range(len(trunk))):
if i < 11:
continue
x = trunk[i-11:i+1]
if len(x) == len(set(x)):
foundindex = i-11
found12 = x
print(foundindex,x,'\n')
found = True
print(convertToAlpha(trunk))
if found:
print('solution found at index', foundindex)
print(convertToAlpha(found12))
|
Posted by Larry
on 2023-11-06 13:51:24 |