# ==============================================================================
"""BINO : compute the binomial coefficient C(n,p)"""
# ==============================================================================
__author__  = "Christophe Schlick modified by Philippe Blasi"
__version__ = "2.0" # import factorial function from previous example
__date__    = "2022-11-12"
__usage__   = """
User input : <n>,<p> (where n:int >= 0, p:int >= 0)
App output : binomial coefficient C(n,p)"""
# ==============================================================================
from ezCLI import *
# ------------------------------------------------------------------------------
def facto(n:int,m:int=0) -> int:
  """return n! (iterative implementation)"""
  # fait le calcul à partir de m+1 au lieu de 1
  result = 1
  for i in range(m+1,n+1):
    result *= i   # result = result * i
  return result
# ------------------------------------------------------------------------------
def bino(n:int, p:int) -> int:
  """compute the binomial coefficient C(n,p) using standard factorial"""
  # en fonction des valeurs de p et n-p, on applique la simplification
  if p > n-p:
    return facto(n,p)//facto(n-p)
  else:
    return facto(n,n-p)//facto(p)
# ------------------------------------------------------------------------------
def parser(command:str) -> str:
  """parse 'command' as 'n,p' before calling 'bino(n,p)'"""
  arguments = parse(command) ; #inspect()
  assert type(arguments) is tuple and len(arguments) == 2, "exactly two values are required"
  (n, p) = arguments; #inspect()
  assert type(n) is int and n >= 0, "<n> must be a positive integer"
  assert type(p) is int and p >= 0, "<n> must be a positive integer"
  return f"bino({n},{p}) = {bino(n,p)}"
# ==============================================================================
if __name__ == '__main__':
  userloop(parser, "Enter <n>,<p>")
# ==============================================================================
