text: '''THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND
  NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR ANYONE
  DISTRIBUTING THE SOFTWARE BE LIABLE FOR ANY DAMAGES OR OTHER LIABILITY,
  WHETHER IN CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  SOFTWARE.'''
  
  # Bitcoin Cash (BCH)   qpz32c4lg7x7lnk9jg6qg7s4uavdce89myax5v5nuk
  # Ether (ETH) -        0x843d3DEC2A4705BD4f45F674F641cE2D0022c9FB
  # Litecoin (LTC) -     Lfk5y4F7KZa9oRxpazETwjQnHszEPvqPvu
  # Bitcoin (BTC) -      34L8qWiQyKr8k4TnHDacfjbaSqQASbBtTd
  
  # contact :- github@jamessawyer.co.uk
  
  
  
  # -*- coding: utf-8 -*-
  """
  Created on Thu Oct  5 16:44:23 2017
  
  @author: Christian Bender
  
  This python library contains some useful functions to deal with
  prime numbers and whole numbers.
  
  Overview:
  
  isPrime(number)
  sieveEr(N)
  getPrimeNumbers(N)
  primeFactorization(number)
  greatestPrimeFactor(number)
  smallestPrimeFactor(number)
  getPrime(n)
  getPrimesBetween(pNumber1, pNumber2)
  
  ----
  
  isEven(number)
  isOdd(number)
  gcd(number1, number2)  // greatest common divisor
  kgV(number1, number2)  // least common multiple
  getDivisors(number)    // all divisors of 'number' inclusive 1, number
  isPerfectNumber(number)
  
  NEW-FUNCTIONS
  
  simplifyFraction(numerator, denominator)
  factorial (n) // n!
  fib (n) // calculate the n-th fibonacci term.
  
  -----
  
  goldbach(number)  // Goldbach's assumption
  
  """
  
  from math import sqrt
  
  
  def isPrime(number):
      """
          input: positive integer 'number'
          returns true if 'number' is prime otherwise false.
      """
  
      # precondition
      assert isinstance(number, int) and (
          number >= 0
      ), "'number' must been an int and positive"
  
      status = True
  
      # 0 and 1 are none primes.
      if number <= 1:
          status = False
  
      for divisor in range(2, int(round(sqrt(number))) + 1):
  
          # if 'number' divisible by 'divisor' then sets 'status'
          # of false and break up the loop.
          if number % divisor == 0:
              status = False
              break
  
      # precondition
      assert isinstance(status, bool), "'status' must been from type bool"
  
      return status
  
  
  # ------------------------------------------
  
  
  def sieveEr(N):
      """
          input: positive integer 'N' > 2
          returns a list of prime numbers from 2 up to N.
  
          This function implements the algorithm called
          sieve of erathostenes.
  
      """
  
      # precondition
      assert isinstance(N, int) and (N > 2), "'N' must been an int and > 2"
  
      # beginList: conatins all natural numbers from 2 upt to N
      beginList = [x for x in range(2, N + 1)]
  
      ans = []  # this list will be returns.
  
      # actual sieve of erathostenes
      for i in range(len(beginList)):
  
          for j in range(i + 1, len(beginList)):
  
              if (beginList[i] != 0) and (beginList[j] % beginList[i] == 0):
                  beginList[j] = 0
  
      # filters actual prime numbers.
      ans = [x for x in beginList if x != 0]
  
      # precondition
      assert isinstance(ans, list), "'ans' must been from type list"
  
      return ans
  
  
  # --------------------------------
  
  
  def getPrimeNumbers(N):
      """
          input: positive integer 'N' > 2
          returns a list of prime numbers from 2 up to N (inclusive)
          This function is more efficient as function 'sieveEr(...)'
      """
  
      # precondition
      assert isinstance(N, int) and (N > 2), "'N' must been an int and > 2"
  
      ans = []
  
      # iterates over all numbers between 2 up to N+1
      # if a number is prime then appends to list 'ans'
      for number in range(2, N + 1):
  
          if isPrime(number):
  
              ans.append(number)
  
      # precondition
      assert isinstance(ans, list), "'ans' must been from type list"
  
      return ans
  
  
  # -----------------------------------------
  
  
  def primeFactorization(number):
      """
          input: positive integer 'number'
          returns a list of the prime number factors of 'number'
      """
  
      # precondition
      assert isinstance(
          number, int) and number >= 0, "'number' must been an int and >= 0"
  
      ans = []  # this list will be returns of the function.
  
      # potential prime number factors.
  
      factor = 2
  
      quotient = number
  
      if number == 0 or number == 1:
  
          ans.append(number)
  
      # if 'number' not prime then builds the prime factorization of 'number'
      elif not isPrime(number):
  
          while quotient != 1:
  
              if isPrime(factor) and (quotient % factor == 0):
                  ans.append(factor)
                  quotient /= factor
              else:
                  factor += 1
  
      else:
          ans.append(number)
  
      # precondition
      assert isinstance(ans, list), "'ans' must been from type list"
  
      return ans
  
  
  # -----------------------------------------
  
  
  def greatestPrimeFactor(number):
      """
          input: positive integer 'number' >= 0
          returns the greatest prime number factor of 'number'
      """
  
      # precondition
      assert isinstance(number, int) and (
          number >= 0
      ), "'number' bust been an int and >= 0"
  
      ans = 0
  
      # prime factorization of 'number'
      primeFactors = primeFactorization(number)
  
      ans = max(primeFactors)
  
      # precondition
      assert isinstance(ans, int), "'ans' must been from type int"
  
      return ans
  
  
  # ----------------------------------------------
  
  
  def smallestPrimeFactor(number):
      """
          input: integer 'number' >= 0
          returns the smallest prime number factor of 'number'
      """
  
      # precondition
      assert isinstance(number, int) and (
          number >= 0
      ), "'number' bust been an int and >= 0"
  
      ans = 0
  
      # prime factorization of 'number'
      primeFactors = primeFactorization(number)
  
      ans = min(primeFactors)
  
      # precondition
      assert isinstance(ans, int), "'ans' must been from type int"
  
      return ans
  
  
  # ----------------------
  
  
  def isEven(number):
      """
          input: integer 'number'
          returns true if 'number' is even, otherwise false.
      """
  
      # precondition
      assert isinstance(number, int), "'number' must been an int"
      assert isinstance(
          number %
          2 == 0, bool), "compare bust been from type bool"
  
      return number % 2 == 0
  
  
  # ------------------------
  
  
  def isOdd(number):
      """
          input: integer 'number'
          returns true if 'number' is odd, otherwise false.
      """
  
      # precondition
      assert isinstance(number, int), "'number' must been an int"
      assert isinstance(
          number %
          2 != 0, bool), "compare bust been from type bool"
  
      return number % 2 != 0
  
  
  # ------------------------
  
  
  def goldbach(number):
      """
          Goldbach's assumption
          input: a even positive integer 'number' > 2
          returns a list of two prime numbers whose sum is equal to 'number'
      """
  
      # precondition
      assert (
          isinstance(number, int) and (number > 2) and isEven(number)
      ), "'number' must been an int, even and > 2"
  
      ans = []  # this list will returned
  
      # creates a list of prime numbers between 2 up to 'number'
      primeNumbers = getPrimeNumbers(number)
      lenPN = len(primeNumbers)
  
      # run variable for while-loops.
      i = 0
      j = None
  
      # exit variable. for break up the loops
      loop = True
  
      while i < lenPN and loop:
  
          j = i + 1
  
          while j < lenPN and loop:
  
              if primeNumbers[i] + primeNumbers[j] == number:
                  loop = False
                  ans.append(primeNumbers[i])
                  ans.append(primeNumbers[j])
  
              j += 1
  
          i += 1
  
      # precondition
      assert (
          isinstance(ans, list)
          and (len(ans) == 2)
          and (ans[0] + ans[1] == number)
          and isPrime(ans[0])
          and isPrime(ans[1])
      ), "'ans' must contains two primes. And sum of elements must been eq 'number'"
  
      return ans
  
  
  # ----------------------------------------------
  
  
  def gcd(number1, number2):
      """
          Greatest common divisor
          input: two positive integer 'number1' and 'number2'
          returns the greatest common divisor of 'number1' and 'number2'
      """
  
      # precondition
      assert (
          isinstance(number1, int)
          and isinstance(number2, int)
          and (number1 >= 0)
          and (number2 >= 0)
      ), "'number1' and 'number2' must been positive integer."
  
      rest = 0
  
      while number2 != 0:
  
          rest = number1 % number2
          number1 = number2
          number2 = rest
  
      # precondition
      assert isinstance(number1, int) and (
          number1 >= 0
      ), "'number' must been from type int and positive"
  
      return number1
  
  
  # ----------------------------------------------------
  
  
  def kgV(number1, number2):
      """
          Least common multiple
          input: two positive integer 'number1' and 'number2'
          returns the least common multiple of 'number1' and 'number2'
      """
  
      # precondition
      assert (
          isinstance(number1, int)
          and isinstance(number2, int)
          and (number1 >= 1)
          and (number2 >= 1)
      ), "'number1' and 'number2' must been positive integer."
  
      ans = 1  # actual answer that will be return.
  
      # for kgV (x,1)
      if number1 > 1 and number2 > 1:
  
          # builds the prime factorization of 'number1' and 'number2'
          primeFac1 = primeFactorization(number1)
          primeFac2 = primeFactorization(number2)
  
      elif number1 == 1 or number2 == 1:
  
          primeFac1 = []
          primeFac2 = []
          ans = max(number1, number2)
  
      count1 = 0
      count2 = 0
  
      done = []  # captured numbers int both 'primeFac1' and 'primeFac2'
  
      # iterates through primeFac1
      for n in primeFac1:
  
          if n not in done:
  
              if n in primeFac2:
  
                  count1 = primeFac1.count(n)
                  count2 = primeFac2.count(n)
  
                  for i in range(max(count1, count2)):
                      ans *= n
  
              else:
  
                  count1 = primeFac1.count(n)
  
                  for i in range(count1):
                      ans *= n
  
              done.append(n)
  
      # iterates through primeFac2
      for n in primeFac2:
  
          if n not in done:
  
              count2 = primeFac2.count(n)
  
              for i in range(count2):
                  ans *= n
  
              done.append(n)
  
      # precondition
      assert isinstance(ans, int) and (
          ans >= 0
      ), "'ans' must been from type int and positive"
  
      return ans
  
  
  # ----------------------------------
  
  
  def getPrime(n):
      """
          Gets the n-th prime number.
          input: positive integer 'n' >= 0
          returns the n-th prime number, beginning at index 0
      """
  
      # precondition
      assert isinstance(n, int) and (n >= 0), "'number' must been a positive int"
  
      index = 0
      ans = 2  # this variable holds the answer
  
      while index < n:
  
          index += 1
  
          ans += 1  # counts to the next number
  
          # if ans not prime then
          # runs to the next prime number.
          while not isPrime(ans):
              ans += 1
  
      # precondition
      assert isinstance(ans, int) and isPrime(
          ans
      ), "'ans' must been a prime number and from type int"
  
      return ans
  
  
  # ---------------------------------------------------
  
  
  def getPrimesBetween(pNumber1, pNumber2):
      """
          input: prime numbers 'pNumber1' and 'pNumber2'
                  pNumber1 < pNumber2
          returns a list of all prime numbers between 'pNumber1' (exclusiv)
                  and 'pNumber2' (exclusiv)
      """
  
      # precondition
      assert (
          isPrime(pNumber1) and isPrime(pNumber2) and (pNumber1 < pNumber2)
      ), "The arguments must been prime numbers and 'pNumber1' < 'pNumber2'"
  
      number = pNumber1 + 1  # jump to the next number
  
      ans = []  # this list will be returns.
  
      # if number is not prime then
      # fetch the next prime number.
      while not isPrime(number):
          number += 1
  
      while number < pNumber2:
  
          ans.append(number)
  
          number += 1
  
          # fetch the next prime number.
          while not isPrime(number):
              number += 1
  
      # precondition
      assert (isinstance(ans, list) and ans[0] != pNumber1 and ans[len(
          ans) - 1] != pNumber2), "'ans' must been a list without the arguments"
  
      # 'ans' contains not 'pNumber1' and 'pNumber2' !
      return ans
  
  
  # ----------------------------------------------------
  
  
  def getDivisors(n):
      """
          input: positive integer 'n' >= 1
          returns all divisors of n (inclusive 1 and 'n')
      """
  
      # precondition
      assert isinstance(n, int) and (n >= 1), "'n' must been int and >= 1"
  
      ans = []  # will be returned.
  
      for divisor in range(1, n + 1):
  
          if n % divisor == 0:
              ans.append(divisor)
  
      # precondition
      assert ans[0] == 1 and ans[len(ans) -
                                 1] == n, "Error in function getDivisiors(...)"
  
      return ans
  
  
  # ----------------------------------------------------
  
  
  def isPerfectNumber(number):
      """
          input: positive integer 'number' > 1
          returns true if 'number' is a perfect number otherwise false.
      """
  
      # precondition
      assert isinstance(number, int) and (
          number > 1
      ), "'number' must been an int and >= 1"
  
      divisors = getDivisors(number)
  
      # precondition
      assert (
          isinstance(divisors, list)
          and (divisors[0] == 1)
          and (divisors[len(divisors) - 1] == number)
      ), "Error in help-function getDivisiors(...)"
  
      # summed all divisors up to 'number' (exclusive), hence [:-1]
      return sum(divisors[:-1]) == number
  
  
  # ------------------------------------------------------------
  
  
  def simplifyFraction(numerator, denominator):
      """
          input: two integer 'numerator' and 'denominator'
          assumes: 'denominator' != 0
          returns: a tuple with simplify numerator and denominator.
      """
  
      # precondition
      assert (
          isinstance(numerator, int)
          and isinstance(denominator, int)
          and (denominator != 0)
      ), "The arguments must been from type int and 'denominator' != 0"
  
      # build the greatest common divisor of numerator and denominator.
      gcdOfFraction = gcd(abs(numerator), abs(denominator))
  
      # precondition
      assert (
          isinstance(gcdOfFraction, int)
          and (numerator % gcdOfFraction == 0)
          and (denominator % gcdOfFraction == 0)
      ), "Error in function gcd(...,...)"
  
      return (numerator // gcdOfFraction, denominator // gcdOfFraction)
  
  
  # -----------------------------------------------------------------
  
  
  def factorial(n):
      """
          input: positive integer 'n'
          returns the factorial of 'n' (n!)
      """
  
      # precondition
      assert isinstance(n, int) and (n >= 0), "'n' must been a int and >= 0"
  
      ans = 1  # this will be return.
  
      for factor in range(1, n + 1):
          ans *= factor
  
      return ans
  
  
  # -------------------------------------------------------------------
  
  
  def fib(n):
      """
          input: positive integer 'n'
          returns the n-th fibonacci term , indexing by 0
      """
  
      # precondition
      assert isinstance(n, int) and (n >= 0), "'n' must been an int and >= 0"
  
      tmp = 0
      fib1 = 1
      ans = 1  # this will be return
  
      for i in range(n - 1):
  
          tmp = ans
          ans += fib1
          fib1 = tmp
  
      return ans
  