Last active
April 29, 2019 17:38
-
-
Save tweakimp/deb42116aedc2703beef6d8d6385f6a6 to your computer and use it in GitHub Desktop.
multiplicative persistance
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# 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