Skip to content

Instantly share code, notes, and snippets.

@tweakimp
Last active April 29, 2019 17:38
Show Gist options
  • Save tweakimp/deb42116aedc2703beef6d8d6385f6a6 to your computer and use it in GitHub Desktop.
Save tweakimp/deb42116aedc2703beef6d8d6385f6a6 to your computer and use it in GitHub Desktop.
multiplicative persistance
# time everything precisely
from time import perf_counter_ns
from multiprocessing import Pool
from functools import partial
def persistance(n, minimum=10, sequence=False):
if sequence:
print(f"Started with {n}")
depth = persinstence_rec(n, sequence=sequence)
# only print numbers with a persistance greater than 10
if depth >= minimum:
print(f"Found {n} with persistence of {depth}")
else:
# uncomment if you want to print every depth
# print(f"Found {n} with persistence of {depth}")
pass
def persinstence_rec(n, depth=0, sequence=False):
# convert number to int at the start, we generate it as a string
if depth == 0:
n = int(n)
# number is single digit, we are done
if n < 10:
return depth
# convert it to string to be able to loop over the digits
number_as_string = str(n)
result = 1
for x in number_as_string:
result *= int(x)
# print current result if we want to see each step
if sequence:
print(result)
return persinstence_rec(result, depth=depth + 1, sequence=sequence)
def create_testset(n, with_fives=False):
# create the set of numbers we want to check
# the numbers we need to check will start with (blank), 2,3, 34 or 4
# if you had 24, you could just use an 8 to get a smaller number
# same with 23
# then followed by sixes, sevens, eights and nines
# zeros would lead to a persistance of 1
# ones dont make a difference in persistance but make the number bigger
# so we dont use ones.
# for the 'with_fives' setting we can remove all equal numbers because that would lead to a 0
start_time = perf_counter_ns()
if with_fives:
# remove even numbers in testset with fives
testset = {
f"{start}" + f"{five}" + f"{seven}" + f"{nine}"
for start in ["", "3"]
for five in ["5" * x for x in range(1, n)] # <- always have one 5
for seven in ["7" * x for x in range(n)]
for nine in ["9" * x for x in range(n)]
}
else:
testset = {
f"{start}" + f"{six}" + f"{seven}" + f"{eight}" + f"{nine}"
for start in ["", "2", "3", "34", "4"]
for six in ["6" * x for x in range(n)]
for seven in ["7" * x for x in range(n)]
for eight in ["8" * x for x in range(n)]
for nine in ["9" * x for x in range(n)]
}
# remove 'empty' number
testset.discard("")
total_time = (perf_counter_ns() - start_time) / 1000000000
print(f"testset created in {total_time} sec")
return testset
def find_numbers(n, minimum=0, with_fives=False):
# get partial function for pool.map
partial_persistance = partial(persistance, minimum=minimum)
# create testset with up to n sevens, eights, and/or nines
numbers = create_testset(n, with_fives)
# check how many numbers we have in the testset
amount = len(numbers)
print("numbers: length", amount)
# get the longest number
maxlen = max(len(s) for s in numbers)
print("numbers: longest string", maxlen)
# start timer
gen = (x for x in numbers)
print("start search")
start_time = perf_counter_ns()
# calculate the persistance of each number
# i have a quadcore, so i choose 4 processes
with Pool(processes=4) as pool:
pool.map(partial_persistance, gen)
# for number in numbers:
# partial_persistance(number)
total_time = (perf_counter_ns() - start_time) / 1000000000
# print(f"complete in {round(total_time,3)} sec ({round(amount/total_time,3)} checked numbers per sec)")
print(f"complete in {round(total_time,3)} sec")
if __name__ == "__main__":
# check single numbers and print they persistance with sequence=True
# persistance(277777788888899, sequence=True)
# persistance(27777899, sequence=True)
# check all numbers we create in testset with up to n fives, sixes, sevens, eights and/or nines
# use 'with_fives=True' to create numbers with fives
# print only if persistance higher than 'minimum'
# find_numbers(100, minimum=5, with_fives=True) # takes ~35 sec
find_numbers(30, minimum=10)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment