Skip to content

Unify primality checking #6228

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Jul 11, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion DIRECTORY.md
Original file line number Diff line number Diff line change
Expand Up @@ -444,7 +444,6 @@
* [Scoring Functions](machine_learning/scoring_functions.py)
* [Sequential Minimum Optimization](machine_learning/sequential_minimum_optimization.py)
* [Similarity Search](machine_learning/similarity_search.py)
* [Support Vector Machines](machine_learning/support_vector_machines.py)
* [Word Frequency Functions](machine_learning/word_frequency_functions.py)

## Maths
Expand Down Expand Up @@ -910,6 +909,7 @@

## Scheduling
* [First Come First Served](scheduling/first_come_first_served.py)
* [Highest Response Ratio Next](scheduling/highest_response_ratio_next.py)
* [Multi Level Feedback Queue](scheduling/multi_level_feedback_queue.py)
* [Non Preemptive Shortest Job First](scheduling/non_preemptive_shortest_job_first.py)
* [Round Robin](scheduling/round_robin.py)
Expand Down Expand Up @@ -1016,6 +1016,7 @@
* [Reverse Words](strings/reverse_words.py)
* [Split](strings/split.py)
* [Upper](strings/upper.py)
* [Wave](strings/wave.py)
* [Wildcard Pattern Matching](strings/wildcard_pattern_matching.py)
* [Word Occurrence](strings/word_occurrence.py)
* [Word Patterns](strings/word_patterns.py)
Expand Down
4 changes: 2 additions & 2 deletions data_structures/hashing/double_hash.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
from .hash_table import HashTable
from .number_theory.prime_numbers import check_prime, next_prime
from .number_theory.prime_numbers import is_prime, next_prime


class DoubleHash(HashTable):
Expand All @@ -15,7 +15,7 @@ def __hash_function_2(self, value, data):

next_prime_gt = (
next_prime(value % self.size_table)
if not check_prime(value % self.size_table)
if not is_prime(value % self.size_table)
else value % self.size_table
) # gt = bigger than
return next_prime_gt - (data % next_prime_gt)
Expand Down
50 changes: 40 additions & 10 deletions data_structures/hashing/number_theory/prime_numbers.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,25 +3,55 @@
module to operations with prime numbers
"""

import math

def check_prime(number):
"""
it's not the best solution

def is_prime(number: int) -> bool:
"""Checks to see if a number is a prime in O(sqrt(n)).

A number is prime if it has exactly two factors: 1 and itself.

>>> is_prime(0)
False
>>> is_prime(1)
False
>>> is_prime(2)
True
>>> is_prime(3)
True
>>> is_prime(27)
False
>>> is_prime(87)
False
>>> is_prime(563)
True
>>> is_prime(2999)
True
>>> is_prime(67483)
False
"""
special_non_primes = [0, 1, 2]
if number in special_non_primes[:2]:
return 2
elif number == special_non_primes[-1]:
return 3

return all(number % i for i in range(2, number))
# precondition
assert isinstance(number, int) and (
number >= 0
), "'number' must been an int and positive"

if 1 < number < 4:
# 2 and 3 are primes
return True
elif number < 2 or not number % 2:
# Negatives, 0, 1 and all even numbers are not primes
return False

odd_numbers = range(3, int(math.sqrt(number) + 1), 2)
return not any(not number % i for i in odd_numbers)


def next_prime(value, factor=1, **kwargs):
value = factor * value
first_value_val = value

while not check_prime(value):
while not is_prime(value):
value += 1 if not ("desc" in kwargs.keys() and kwargs["desc"] is True) else -1

if value == first_value_val:
Expand Down
61 changes: 33 additions & 28 deletions maths/prime_check.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,31 +4,36 @@
import unittest


def prime_check(number: int) -> bool:
def is_prime(number: int) -> bool:
"""Checks to see if a number is a prime in O(sqrt(n)).

A number is prime if it has exactly two factors: 1 and itself.

>>> prime_check(0)
>>> is_prime(0)
False
>>> prime_check(1)
>>> is_prime(1)
False
>>> prime_check(2)
>>> is_prime(2)
True
>>> prime_check(3)
>>> is_prime(3)
True
>>> prime_check(27)
>>> is_prime(27)
False
>>> prime_check(87)
>>> is_prime(87)
False
>>> prime_check(563)
>>> is_prime(563)
True
>>> prime_check(2999)
>>> is_prime(2999)
True
>>> prime_check(67483)
>>> is_prime(67483)
False
"""

# precondition
assert isinstance(number, int) and (
number >= 0
), "'number' must been an int and positive"

if 1 < number < 4:
# 2 and 3 are primes
return True
Expand All @@ -42,35 +47,35 @@ def prime_check(number: int) -> bool:

class Test(unittest.TestCase):
def test_primes(self):
self.assertTrue(prime_check(2))
self.assertTrue(prime_check(3))
self.assertTrue(prime_check(5))
self.assertTrue(prime_check(7))
self.assertTrue(prime_check(11))
self.assertTrue(prime_check(13))
self.assertTrue(prime_check(17))
self.assertTrue(prime_check(19))
self.assertTrue(prime_check(23))
self.assertTrue(prime_check(29))
self.assertTrue(is_prime(2))
self.assertTrue(is_prime(3))
self.assertTrue(is_prime(5))
self.assertTrue(is_prime(7))
self.assertTrue(is_prime(11))
self.assertTrue(is_prime(13))
self.assertTrue(is_prime(17))
self.assertTrue(is_prime(19))
self.assertTrue(is_prime(23))
self.assertTrue(is_prime(29))

def test_not_primes(self):
self.assertFalse(
prime_check(-19),
is_prime(-19),
"Negative numbers are excluded by definition of prime numbers.",
)
self.assertFalse(
prime_check(0),
is_prime(0),
"Zero doesn't have any positive factors, primes must have exactly two.",
)
self.assertFalse(
prime_check(1),
is_prime(1),
"One only has 1 positive factor, primes must have exactly two.",
)
self.assertFalse(prime_check(2 * 2))
self.assertFalse(prime_check(2 * 3))
self.assertFalse(prime_check(3 * 3))
self.assertFalse(prime_check(3 * 5))
self.assertFalse(prime_check(3 * 5 * 7))
self.assertFalse(is_prime(2 * 2))
self.assertFalse(is_prime(2 * 3))
self.assertFalse(is_prime(3 * 3))
self.assertFalse(is_prime(3 * 5))
self.assertFalse(is_prime(3 * 5 * 7))


if __name__ == "__main__":
Expand Down
22 changes: 11 additions & 11 deletions maths/primelib.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@
from math import sqrt


def isPrime(number):
def is_prime(number: int) -> bool:
"""
input: positive integer 'number'
returns true if 'number' is prime otherwise false.
Expand Down Expand Up @@ -129,7 +129,7 @@ def getPrimeNumbers(N):
# if a number is prime then appends to list 'ans'
for number in range(2, N + 1):

if isPrime(number):
if is_prime(number):

ans.append(number)

Expand Down Expand Up @@ -164,11 +164,11 @@ def primeFactorization(number):
ans.append(number)

# if 'number' not prime then builds the prime factorization of 'number'
elif not isPrime(number):
elif not is_prime(number):

while quotient != 1:

if isPrime(factor) and (quotient % factor == 0):
if is_prime(factor) and (quotient % factor == 0):
ans.append(factor)
quotient /= factor
else:
Expand Down Expand Up @@ -317,8 +317,8 @@ def goldbach(number):
isinstance(ans, list)
and (len(ans) == 2)
and (ans[0] + ans[1] == number)
and isPrime(ans[0])
and isPrime(ans[1])
and is_prime(ans[0])
and is_prime(ans[1])
), "'ans' must contains two primes. And sum of elements must been eq 'number'"

return ans
Expand Down Expand Up @@ -462,11 +462,11 @@ def getPrime(n):

# if ans not prime then
# runs to the next prime number.
while not isPrime(ans):
while not is_prime(ans):
ans += 1

# precondition
assert isinstance(ans, int) and isPrime(
assert isinstance(ans, int) and is_prime(
ans
), "'ans' must been a prime number and from type int"

Expand All @@ -486,7 +486,7 @@ def getPrimesBetween(pNumber1, pNumber2):

# precondition
assert (
isPrime(pNumber1) and isPrime(pNumber2) and (pNumber1 < pNumber2)
is_prime(pNumber1) and is_prime(pNumber2) and (pNumber1 < pNumber2)
), "The arguments must been prime numbers and 'pNumber1' < 'pNumber2'"

number = pNumber1 + 1 # jump to the next number
Expand All @@ -495,7 +495,7 @@ def getPrimesBetween(pNumber1, pNumber2):

# if number is not prime then
# fetch the next prime number.
while not isPrime(number):
while not is_prime(number):
number += 1

while number < pNumber2:
Expand All @@ -505,7 +505,7 @@ def getPrimesBetween(pNumber1, pNumber2):
number += 1

# fetch the next prime number.
while not isPrime(number):
while not is_prime(number):
number += 1

# precondition
Expand Down