patternpythonMinor
Divisor game cheating aid
Viewed 0 times
cheatinggameaiddivisor
Problem
This code outputs the smallest number with more divisors than the input:
```
from operator import mul
from math import sqrt, ceil
def next_prime_factor(n):
if n % 2 == 0:
return 2
for x in range(3, int(ceil(sqrt(n)) + 1), 2):
if n % x == 0:
return x
return int(n)
def factor(n):
factors=[]
number=int(n)
while number > 1:
f=next_prime_factor(number)
factors.append(f)
number /= float(f)
number=int(number)
if number==1:break
return list(factors)
def sundaram(max_n):
numbers = range(3, max_n+1, 2)
half = (max_n)/2
initial = 4
for step in xrange(3, max_n+1, 2):
for i in xrange(initial, half, step):
numbers[i-1] = 0
initial += 2*(step+1)
if initial > half:
x=filter(None, numbers) + [2] if filter(None, numbers) != None else [2]
return sorted(x)
def factor_count(n):
factors=factor(n)
primecounts=[]
primes_list=sundaram(int(sqrt(n)))
primes_list = primes_list if primes_list != None else [2]
for i in primes_list:
primecounts.append(factors.count(i))
return primecounts
def div_exps(pcount):
return [i+1 for i in pcount if i!=0]
def div_count(n):
pcount=factor_count(n)
div_count=reduce(mul,div_exps(pcount),1)
return div_count
def next_num(last_num):
if last_num == 1:
return 2
if last_num in sundaram(last_num+1):
return 4
plist=sundaram(int(sqrt(last_num))+1)
div_count_factors=factor(div_count(last_num))
num=1
for i in enumerate(div_count_factors):
num*=plist[i[0]]**(i[1]-1)
end_num=num
while 1:
if div_count(end_num)<=div_count(last_num):
end_num*=min(div_count_factors)
else:
break
return end_num
ans=next_num(input('Input the last number chosen: '))
print 'The smallest number with more divisors than the inputted n
```
from operator import mul
from math import sqrt, ceil
def next_prime_factor(n):
if n % 2 == 0:
return 2
for x in range(3, int(ceil(sqrt(n)) + 1), 2):
if n % x == 0:
return x
return int(n)
def factor(n):
factors=[]
number=int(n)
while number > 1:
f=next_prime_factor(number)
factors.append(f)
number /= float(f)
number=int(number)
if number==1:break
return list(factors)
def sundaram(max_n):
numbers = range(3, max_n+1, 2)
half = (max_n)/2
initial = 4
for step in xrange(3, max_n+1, 2):
for i in xrange(initial, half, step):
numbers[i-1] = 0
initial += 2*(step+1)
if initial > half:
x=filter(None, numbers) + [2] if filter(None, numbers) != None else [2]
return sorted(x)
def factor_count(n):
factors=factor(n)
primecounts=[]
primes_list=sundaram(int(sqrt(n)))
primes_list = primes_list if primes_list != None else [2]
for i in primes_list:
primecounts.append(factors.count(i))
return primecounts
def div_exps(pcount):
return [i+1 for i in pcount if i!=0]
def div_count(n):
pcount=factor_count(n)
div_count=reduce(mul,div_exps(pcount),1)
return div_count
def next_num(last_num):
if last_num == 1:
return 2
if last_num in sundaram(last_num+1):
return 4
plist=sundaram(int(sqrt(last_num))+1)
div_count_factors=factor(div_count(last_num))
num=1
for i in enumerate(div_count_factors):
num*=plist[i[0]]**(i[1]-1)
end_num=num
while 1:
if div_count(end_num)<=div_count(last_num):
end_num*=min(div_count_factors)
else:
break
return end_num
ans=next_num(input('Input the last number chosen: '))
print 'The smallest number with more divisors than the inputted n
Solution
Style guide
You should code your Python to follow PEP (Python Enhancement Proposal) documents, and in particular, PEP8.
PEP8
Comparing your code to PEP8's standards shows quite a few violations.
Whitespace and naming
You have double indentation here:
You should avoid names like this:
Their purpose is a little confusing. Try to use more descriptive names that better describe what they are.
You should name your variables like
Unnecessary logic
You're defining a variable right before returning it, just return it directly.
You can use the list comprehension notation instead:
When you have a block that looks like this:
When the block terminates in the
So, you can simplify that above block down:
The code after the
You should code your Python to follow PEP (Python Enhancement Proposal) documents, and in particular, PEP8.
PEP8
Comparing your code to PEP8's standards shows quite a few violations.
- You should have whitespace between your binary operators.
factors=[]
number=int(n)- Two blank lines after a declaration
from operator import mul
from math import sqrt, ceil
def next_prime_factor(n):- Comparison to
None: instead of!= Noneit should beis not None
x=filter(None, numbers) + [2] if filter(None, numbers) != None else [2]- Line too long: PEP8 has a maximum character count of 79 characters per line, this line has 82:
print 'The smallest number with more divisors than the inputted number is',ans,'.'while 1should be denoted aswhile Trueinstead:
while 1:Whitespace and naming
You have double indentation here:
while number > 1:
f=next_prime_factor(number)
factors.append(f)
number /= float(f)
number=int(number)
if number==1:breakYou should avoid names like this:
numbers = range(3, max_n+1, 2)
half = (max_n)/2Their purpose is a little confusing. Try to use more descriptive names that better describe what they are.
You should name your variables like
snake_case:primecountsUnnecessary logic
div_count=reduce(mul,div_exps(pcount),1)
return div_countYou're defining a variable right before returning it, just return it directly.
for i in primes_list:
primecounts.append(factors.count(i))
return vYou can use the list comprehension notation instead:
primecounts = [factors.count(i) for i in primes_list]if div_count(end_num)<=div_count(last_num):
end_num*=min(div_count_factors)
else:
breakWhen you have a block that looks like this:
if condition == true/false:
doSomething()
else:
endBlock #return, break, continueWhen the block terminates in the
else loop, you can reverse the conditions and reduce a layer of logic:if condition != true/false:
endBlock
doSomething()So, you can simplify that above block down:
if div_count(end_num) > div_count(last_num):
break
end_num *= min(div_count_factors)The code after the
if is not needed: filter always returns a list, which is empty, if no elements remain. This results in identical behavior to the current code.x=filter(None, numbers) + [2] if filter(None, numbers) != None else [2]Code Snippets
factors=[]
number=int(n)from operator import mul
from math import sqrt, ceil
def next_prime_factor(n):x=filter(None, numbers) + [2] if filter(None, numbers) != None else [2]print 'The smallest number with more divisors than the inputted number is',ans,'.'while number > 1:
f=next_prime_factor(number)
factors.append(f)
number /= float(f)
number=int(number)
if number==1:breakContext
StackExchange Code Review Q#124425, answer score: 7
Revisions (0)
No revisions yet.