sábado, 14 de mayo de 2016

Otra forma de factorizar un número

Inspirado por:
http://criticasfaciles.blogspot.com/2015/03/ensenar-restar-de-forma-manipulativa.html

'''
  The method used to get two factors of a number is based on geometry properties.
  Any multiplication of integers x*y can be seen as a grid of squares (in a graph paper) x rows and y columns.
  If the multiplication is not exactly the desired number, there will be a number of squares, that I imagine
  as another not complete column, as rest.
  This method start forming a grid with the integer square root^2 + rest
  if rest==0: we have what we want
  if rest!=0, we remove rows and convert them in columns until we have a perfect rectangle.

Graphical example:   21 is our desired number  -> integer square root(21) = 4

   OOOORR         OOOOOR
   OOOOR      ->  OOOOO
   OOOOR          OOOOO
   OOOOR          OOOOO

   -> Remove the last row and convert it into more columns

   OOOOORX
   OOOOOXX     -> 7*3
   OOOOOXX

  An advantage of this algorithm is that the job can be divided between several processors (or machines),
  dividing the different combinations of initial row and column sizes.

  This method has an invariant: rows * columns + rest == desired number

  This method is mathematics, can not be patented or copyrighted.
  This implementation is released under the GNU GPL v3 or greater.

@package factorizar
'''


def improved_i_sqrt(n):
    """
    http://stackoverflow.com/questions/15390807/integer-square-root-in-python
    """

def factorize(number):
    horizontal = vertical = improved_i_sqrt(number)
    if horizontal * vertical == number:
        return horizontal, vertical
    rest = number - (horizontal * vertical)
    while rest != 0:
        rest, vertical = rest + horizontal, vertical -1
        # faster than  while resto - vertical >= 0: horizontal += 1, resto -= vertical
        c = rest - vertical
        if 0 <= c:
            if c < vertical:
                rest, horizontal = rest - vertical, horizontal + 1
            else:
                horizontal, rest = horizontal + rest // vertical, c % vertical
    return (horizontal, vertical, number)


Copyleft Ender. El presente artículo no tiene finalidad informativa, de creación de opinión pública o de entretenimiento. Tiene como finalidad principal, la enseñanza y la divulgación de experiencias, proyectos, pensamientos y conocimientos del autor. Se permite la copia textual, la traducción y la distribución de este artículo entero en cualquier medio, a condición de que este aviso sea conservado. Se permite la cita. El autor no reclamará ninguna cantidad por el ejercicio de las dos autorizaciones anteriores. No autorizo a ninguna Entidad de Derechos de Autor a reclamar cantidad alguna en mi nombre por el ejercicio de los dos derechos anteriores.

No hay comentarios:

Publicar un comentario