#' Generate all m-permutations of n without repetition
#'
#' @param n total # of elements
#' @param m # of elements to choose
#' @param vals a vector of values to be permuted
#' @param noreverse = 1 to remove reverse-equivalent rows \cr
#' = 2 to check the result
#'
#' @details
#' The recursive algorithm below is used.
#' \preformatted{
#'   res=NULL
#'   for( i in 1:n )\{
#'     res <- rbind(res, cbind(vals[i], Recall(n - 1, m - 1, vals[-i])))
#'   \}
#' }
#'
#' The method of removal of reverse-equivalent rows comes from
#' the answer to stack overflow question: \cr
#' "How to remove reverse rows in a permutation matrix?" \cr
#' by obchardon at Sep 15, 2020 at 7:46 \cr
#' https://stackoverflow.com/questions/63896177/how-to-remove-reverse-rows
#' -in-a-permutation-matrix
#'
#'
#'
#' @return
#' A matrix of the size P(n,m) x m.
#'
#' @examples
#' n <- 5
#' for( m in 1:n )
#'  Print( m, perm(n,m), comb(n,m) )
#'  
#'  Print( perm(3,3), perm(3,3,,1) )
#'
#' @export
#'

perm <- function(n, m, vals=1:n, noreverse=0 ) {
 # permutations
 # Shin-ichi Mayekawa
 # 20220621
 # noreverse: 20231216
 # examples added: 20240415
 #

 if (m == 1) return( matrix(vals, n, 1) )
 else if (n == 1) return( matrix(vals, 1, m) )
 else{
  res=NULL
  for( i in 1:n ){
   res=rbind(res, cbind(vals[i], Recall(n - 1, m - 1, vals[-i])))
  }

  if( noreverse == 1 ){
   loc=which( res[,1] < res[,m] )
   res=res[loc,]
  }
  else if( noreverse == 2 ){
   res0=res
   loc=which( res[,1] < res[,m] )
   res=res[loc,]

   # reverse-equivalent part
   res2=res0[-loc,]
   # reverse the order
   res2=t(apply(res2,1,rev))
   # sort
   res2=res2[do.call(order,as.data.frame(res2)),]
   if( any(res-res2 != 0) ){
     cat("\nerror1:(perm) Removal of reverse-equivalent rows failed!!\n")
     stop()
   }
  }
  return( res )
 }

} # end of perm


