Commit b024e0c2 authored by Taddeus Kroes's avatar Taddeus Kroes

Added some utility functions to find (prime) dividers of a number.

parent 3f28fa21
...@@ -135,6 +135,47 @@ def divides(m, n): ...@@ -135,6 +135,47 @@ def divides(m, n):
return not divmod(n, m)[1] return not divmod(n, m)[1]
def dividers(n):
"""
Find all integers that divide n, except for 1.
"""
def m_dividers(m):
result, rest = divmod(n, m)
if not rest:
return [m, result] if m != result else [m]
below_sqrt = filter(None, map(m_dividers, xrange(2, int(n ** .5) + 1)))
div = reduce(lambda a, b: a + b, below_sqrt, [])
div.sort()
return div
def is_prime(n):
"""
Check if n is a prime.
"""
if n == 2:
return True
if n < 2 or not n & 1:
return False
for i in xrange(3, int(n ** .5) + 1, 2):
if not divmod(n, i)[1]:
return False
return True
def prime_dividers(n):
"""
Find all primes that divide n.
"""
return filter(is_prime, dividers(n))
def is_numeric_node(node): def is_numeric_node(node):
""" """
Check if a node is numeric. Check if a node is numeric.
......
from src.rules import utils from src.rules import utils
from src.rules.utils import least_common_multiple, is_fraction, partition, \ from src.rules.utils import least_common_multiple, is_fraction, partition, \
find_variables, first_sorted_variable, find_variable, substitute, \ find_variables, first_sorted_variable, find_variable, substitute, \
divides, evals_to_numeric divides, dividers, is_prime, prime_dividers, evals_to_numeric
from tests.rulestestcase import tree, RulesTestCase from tests.rulestestcase import tree, RulesTestCase
...@@ -66,6 +66,32 @@ class TestRulesUtils(RulesTestCase): ...@@ -66,6 +66,32 @@ class TestRulesUtils(RulesTestCase):
self.assertFalse(divides(4, 2)) self.assertFalse(divides(4, 2))
self.assertFalse(divides(2, 3)) self.assertFalse(divides(2, 3))
def test_dividers(self):
self.assertEqual(dividers(1), [])
self.assertEqual(dividers(2), [])
self.assertEqual(dividers(4), [2])
self.assertEqual(dividers(6), [2, 3])
self.assertEqual(dividers(10), [2, 5])
self.assertEqual(dividers(21), [3, 7])
self.assertEqual(dividers(20), [2, 4, 5, 10])
self.assertEqual(dividers(1000000), [2, 4, 5, 8, 10, 16, 20, 25, 32,
40, 50, 64, 80, 100, 125, 160, 200, 250, 320, 400, 500, 625, 800,
1000, 1250, 1600, 2000, 2500, 3125, 4000, 5000, 6250, 8000, 10000,
12500, 15625, 20000, 25000, 31250, 40000, 50000, 62500, 100000,
125000, 200000, 250000, 500000])
def test_is_prime(self):
self.assertFalse(is_prime(1))
self.assertTrue(is_prime(2))
self.assertTrue(is_prime(3))
self.assertFalse(is_prime(6))
self.assertTrue(is_prime(19))
self.assertTrue(is_prime(43))
def test_prime_dividers(self):
self.assertEqual(prime_dividers(6), [2, 3])
self.assertEqual(prime_dividers(20), [2, 5])
def test_evals_to_numeric(self): def test_evals_to_numeric(self):
self.assertTrue(evals_to_numeric(tree('1'))) self.assertTrue(evals_to_numeric(tree('1')))
self.assertFalse(evals_to_numeric(tree('a'))) self.assertFalse(evals_to_numeric(tree('a')))
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment