# ==============================================================================
"""MULDIV : table of GCD/LCM (Greatest Common Divisor/Least Common Multiple)"""
# ==============================================================================
__author__  = "Christophe Schlick modified by Philippe Blasi"
__version__ = "1.0" # use 'grid' function from ezCLI to format table
__date__    = "2022-11-12"
__usage__   = """
User input : <n> (where n:int > 0)
App output: table of GCD/LCM from 1 to n"""
# ==============================================================================
from ezCLI import *
# ------------------------------------------------------------------------------
def gcd(p:int, q:int) -> int:
  """return Greatest Common Divisor between numbers 'p' and 'q'"""
  while q != 0:
    # p, q = q, p%q
    old_p = p
    p = q
    q = old_p % q
  return p
# ------------------------------------------------------------------------------
def lcm(p:int, q:int) -> int:
  """return Least Common Multiple between numbers 'p' and 'q'"""
  return (p*q)//gcd(p,q)
# ------------------------------------------------------------------------------
def cell(row:int, col:int) -> int:
  """return either the GCD or the LCM according to cell position (row,col)"""
  # on veut les numéro de colonne sur la première ligne
  if row == 1:
    return col
  
  # où se trouve la cellule (row,col) par rapport à la diagonale
  # - au dessus ou sur la diagoale : col >= row ==> on renvoie gdc
  # - en dessous : col < row ==> on renvoie le lcm
  if col >= row:
    return gcd(row,col)
  else:
    return lcm(row,col)
# ------------------------------------------------------------------------------
def muldiv(n:int) -> str:
  """return a grid containing the GCD/LCM table from 1 to n"""
  table = [[ cell(row,col) for col in range(1, n+1)] for row in range(1, n+1)]; #inspect()
  return grid(table) # use the 'grid' function to format 'table' as a grid
# ------------------------------------------------------------------------------
def parser(command:str) -> str:
  """parse 'command' as integer 'n' before calling 'muldiv(n)'"""
  n = parse(command); #inspect()
  assert type(n) is int and n > 0, "<n> must be a strictly positive integer"
  return muldiv(n)
# ==============================================================================
if __name__ == "__main__":
  userloop(parser, "Enter value for <n>")
# ==============================================================================
