
/*: Count number of bits in a number */
CountBits(value) :=
[
  Local(nbits);
  nbits:=0;
  Check(value>=0,"CountBits: Error: argument " : (ToString()Write(value))
    : ", should be a positive integer");
  While(value != 0)
  [
    nbits++;
    value := value >> 1;
  ];
  If(
  	IsZero(nbits),
	1,
	nbits
  );
];

/// Return integer part of the logarithm of x in given base. Use only integer arithmetic.
10 # IntLog(_x, _base) _ (base<=1) <-- Undefined;
/// Use variable steps to speed up operation for large numbers x
20 # IntLog(_x, _base) <--
[
	Local(result, step, old'step, factor, old'factor);
	result := 0;
	old'step := step := 1;
	old'factor := factor := base;
	// first loop: increase step
	While (x >= factor)
	[
		old'factor := factor;
		factor := factor*factor;
		old'step := step;
		step := step*2;
	];
	If(x >= base,
	  [
		step := old'step;
		result := step;
		x := Div(x, old'factor);
	  ],
	  step := 0
	);
	// second loop: decrease step
	While (step > 0 And x != 1)
	[
		step := Div(step,2);	// for each step size down to 1, divide by factor if x is up to it
		factor := base^step;
		If(
			x >= factor,
			[
				x:=Div(x, factor);
				result := result + step;
			]
		);
	];
	result;
];

/// obtain next number that has good chances of being prime (not divisible by 2,3)
1# NextPseudoPrime(i_IsInteger)_(i<=1) <-- 2;
2# NextPseudoPrime(2) <-- 3;
2# NextPseudoPrime(3) <-- 5;
// this works only for odd i>=5
3# NextPseudoPrime(i_IsOdd) <--
[
	// this sequence generates numbers not divisible by 2 or 3
	i := If(
		Mod(-i,3)=0,
		i + 2,
		i + 2*Mod(-i, 3)
	);
/* commented out because it slows things down without a real advantage
	// now check if divisible by 5
	If(
		Mod(i,5)=0,
		NextPseudoPrime(i),
		i
	);
*/
];
// this works only for even i>=4
4# NextPseudoPrime(i_IsEven) <-- NextPseudoPrime(i-1);

/// obtain the real next prime number -- use primality testing
1# NextPrime(_i) <--
[
	Until(IsPrime(i)) i := NextPseudoPrime(i);
	i;
];

/* Returns whether n is a prime */

/* Fast pseudoprime testing: if n is a prime, then 24 divides (n^2-1) */
5 # IsPrime(n_IsPositiveInteger)_(n > 4 And Mod(n^2-1,24)!=0) <-- False;

/* Determine if a number is prime, using Rabin-Miller primality
   testing. Code submitted by Christian Obrecht
 */
10 # IsPrime(n_IsPositiveInteger) <-- RabinMiller(n);

/* Returns whether n is a prime^m. */
10 # IsPrimePower(n_IsPrime) <-- True;
10 # IsPrimePower(0) <-- False;
10 # IsPrimePower(1) <-- False;
20 # IsPrimePower(n_IsPositiveInteger) <-- (GetPrimePower(n)[2] > 1);

/// Check whether n is a power of some prime integer and return that integer and the power.
/// This routine uses only integer arithmetic.
/// Returns {p, s} where p is a prime and n=p^s.
/// If no powers found, returns {n, 1}. Primality testing of n is not done.
20 # GetPrimePower(n_IsPositiveInteger) <--
[
	Local(s, factors, new'factors);
	// first, separate any small prime factors
	factors := TrialFactorize(n, 257);	// "factors" = {n1, {p1,s1},{p2,s2},...} or just {n} if no factors found
	If(
		Length(factors) > 1,	// factorized into something
		// now we return {n, 1} either if we haven't completely factorized, or if we factorized into more than one prime factor; otherwise we return the information about prime factors
		If(
			factors[1] = 1 And Length(factors) = 2,	// factors = {1, {p, s}}, so we have a prime power n=p^s
			factors[2],
			{n, 1}
		),
		// not factorizable into small prime factors -- use main algorithm
		[
			factors := CheckIntPower(n, 257);	// now factors = {p, s} with n=p^s
			If(
				factors[2] > 1,	// factorized into something
				// now need to check whether p is a prime or a prime power and recalculate "s"
				If(
					IsPrime(factors[1]),
					factors,	// ok, prime power, return information
					[	// not prime, need to check if it's a prime power
						new'factors := GetPrimePower(factors[1]);	// recursive call; now new'factors = {p1, s1} where n = (p1^s1)^s; we need to check that s1>1
						If(
							new'factors[2] > 1,
							{new'factors[1], new'factors[2]*factors[2]},	// recalculate and return prime power information
							{n, 1}	// not a prime power
						);
					]
				),
				// not factorizable -- return {n, 1}
				{n, 1}
			);
		]
	);
];

/// Check whether n is a power of some integer, assuming that it has no prime factors <= limit.
/// This routine uses only integer arithmetic.
/// Returns {p, s} where s is the smallest prime integer such that n=p^s. (p is not necessarily a prime!)
/// If no powers found, returns {n, 1}. Primality testing of n is not done.
CheckIntPower(n, limit) :=
[
	Local(s0, s, root);
	If(limit<=1, limit:=2);	// guard against too low value of limit
	// compute the bound on power s
	s0 := IntLog(n, limit);
	// loop: check whether n^(1/s) is integer for all prime s up to s0
	root := 0;
	s := 0;
	While(root = 0 And NextPseudoPrime(s)<=s0)	// root=0 while no root is found
	[
		s := NextPseudoPrime(s);
		root := IntNthRoot(n, s);
		If(
			root^s = n,	// found root
			True,
			root := 0
		);
	];
	// return result
	If(
		root=0,
		{n, 1},
		{root, s}
	);
];

/// Compute integer part of s-th root of (positive) integer n. Use only integer arithmetic.
IntNthRoot(_n, s_IsInteger) <--
[
	Local(x1, x2, x'new, y1);
	// initial guess should always undershoot
	//	x1:= 2 ^ Div(IntLog(n, 2), s); 	// this is worse than we can make it
	x1 := IntLog(n,2);
	// select initial interval using (the number of bits in n) mod s
	// note that if the answer is 1, the initial guess must also be 1 (not 0)
	x2 := Div(x1, s);	// save these values for the next If()
	x1 := Mod(x1, s)/s;	// this is kept as a fraction
	// now assign the initial interval, x1 <= root <= x2
	{x1, x2} := If(
		x1 >= 263/290,	// > Ln(15/8)/Ln(2)
		Div({15,16}*2^x2, 8),
		If(
		x1 >= 373/462,	// > Ln(7/4)/Ln(2)
		Div({7,8}*2^x2, 4),
		If(
		x1 >= 179/306,	// > Ln(3/2)/Ln(2)
		Div({6,7}*2^x2, 4),
		If(
		x1 >= 113/351,	// > Ln(5/4)/Ln(2)
		Div({5,6}*2^x2, 4),
		Div({4,5}*2^x2, 4)	// between x1 and (5/4)*x1
	))));
	// check whether x2 is the root
	y1 := x2^s;
	If(
		y1=n,
		x1 := x2,
		// x2 is not a root, so continue as before with x1
		y1 := x1^s	// henceforth, y1 is always x1^s
	);
	// Newton iteration combined with bisection
	While(y1 < n)
	[
//	Echo({x1, x2});
		x'new := Div(x1*((s-1)*y1+(s+1)*n), (s+1)*y1+(s-1)*n) + 1;	// add 1 because the floating-point value undershoots
		If(
			x'new < Div(x1+x2, 2),
			// x'new did not reach the midpoint, need to check progress
			If(
				Div(x1+x2, 2)^s <= n,
				// Newton's iteration is not making good progress, so leave x2 in place and update x1 by bisection
				x'new := Div(x1+x2, 2),
				// Newton's iteration knows what it is doing. Update x2 by bisection
				x2 := Div(x1+x2, 2)
			)
			// else, x'new reached the midpoint, good progress, continue
		);
		x1 := x'new;
		y1 := x1^s;
	];
	If(y1=n, x1, x1-1);	// subtract 1 if we overshot
];

CatalanNumber(_n) <-- 
[	
	Check( IsPositiveInteger(n), "CatalanNumber: Error: argument must be positive" );
	Bin(2*n,n)/(n+1);
];


