public static long fallingPower(int n, int k)
However, in the related operation of falling power that is useful in many combinatorial formulas and denoted syntactically by underlining the exponent, each term that gets multiplied into the product is always one less than the previous term. For example, the falling power 83 would be computed as 8 * 7 * 6 = 336. Similarly, the falling power 105 would equal 10 * 9 * 8 * 7 * 6 = 30240. Nothing important changes if the base n is negative. For example, the falling power (-4)5 is computed the exact same way as -4 * -5 * -6 * -7 * -8 = -6720.
This method should compute and return the falling power nk where n can be any integer, and k can be any nonnegative integer. (Analogous to ordinary powers, n0 = 1 for any n.) The automated tester is designed so that your method does not need to worry about potential integer overflow as long as you perform computations using long type of 64-bit integers.
public static long fallingPower(int n, int k)
long result = n;
for (int i = n; i < k; i--) {
result = result * n;
}
return result;
}
Is my method right?
It should be:
public static long fallingPower(int n, int k){
long result = n;
for (int i = 0; i < k; i++) {
n=n-1;
result = result * n;
}
return result;
}
You are supposed to multiply k times, starting with n and decrementing each factor by one. Your code currently doesn't really make any sense. I would do it like this:
public static long fallingPower(int n, int k)
long result = n;
for (int i = 1; i < k; i++) {
result = result * (n-i);
}
return result;
}
k is required to be non-negative, so you need to handle that in the method too, for example with an exception:
public static long fallingPower(int n, int k)
if(k < 0) {
throw new IllegalArgumentException("Negative exponent");
}
long result = n;
for (int i = 1; i < k; i++) {
result = result * (n-i);
}
return result;
}
public static long fallingPower(int n, uint k){
long result = 1;
for(; k > 0; k--, n--){
result *= n;
}
return result;
}
This is more of the programming logic, not your method, if I am not wrong. I do not have error handling. I started going backward just like you, assuming the least integer permutation of zero is equal to 1 and at least we need to return 1.
You can start from k number before the n and multiply thereafter until you reach n.
public static long fallingPower(int n, int k)
{
long result = 1;
for (int i = 1 ; i <= k ; i++) {
result = result * n;
n = n-1;
}
return result;
}
Related
In the following (naive) implementation of a pow(x, n) method, ignoring completely any optimized approach, I find the following problem:
public double pow(double x, int n) {
boolean negative = n < 0;
long power = Math.abs(n);
double ans = 1.0;
for(long i = 0; i < power; i++) {
ans = ans * x;
}
return negative ? 1.0/ans: ans;
}
Here I have made the assumption that for the case of negative exponent I simply calculate the x^n and then return 1/(x^n) since e.g. 2^(-3) = 1/(2^3)
Problem:
The code fails in the following case:
pow(2.00000, -2147483648)
The output is 1.00000 while the expected correct result is 0.00000
If I change the code as follows:
public double pow(double x, int n) {
long power = n;
if(power < 0) {
x = 1 / x;
power = -power;
}
double ans = 1.0;
for(long i = 0; i < power; i++) {
ans = ans * x;
}
return ans;
}
The result is correct!
So what is the difference between doing the approaches? I was expecting them to be equivalent but they are not
Math.abs(n) is still an int, and only afterwards it is assigned to a long, Therefore, the absolute value of -2147483648 was -2147483648 again (this is noted in the documentation of Math.abs(int)). With the negative bound, the loop performed no iterations.
Math.abs((long)n) would work around that issue.
This is my code for the Codewars problem (Java) yet I cannot make it work. I'm pretty sure I've made a stupid mistake somewhere because of my lack of experience (coding for 4 months)
public static int zeros(int n) {
int f = 1;
int zerocount = 0;
for(int i = 2 ; i <= n; i++){
f *= i;
}
String factorial = String.valueOf(f);
String split [] = factorial.split("");
for(int i = 0; i < split.length; i++){
String m = split[i];
if(m.equals( "0")){
zerocount ++;
}
else {
zerocount = 0;
}
}
return zerocount;
}
}
In fact, you do not need to calculate the factorial because it will rapidly explode into a huge number that will overflow even a long. What you want to do is count the number of fives and twos by which each number between 2 and n can be divided.
static int powersoffive(int n) {
int p=0;
while (n % 5 == 0) {
p++;
n /= 5;
}
return p;
}
static int countzeros(int n) {
int fives = 0;
for (int i = 1; i <= n; i++)
fives += powersoffive(i);
return fives;
}
Note: Lajos Arpad's solution is superior.
As pointed out by other users your solution will probably not be accepted because of the exploding factorial you are calculating.
About the code you wrote there are two mistakes you have made:
You are calculating the factorial in the wrong way. You should start with i = 2 in the loop
for(int i = 2; i <= n; i++){
f *= i;
}
Also in Java you cannot compare strings using ==. This is not valid
if(m == "0")
You should compare them like this
if(m.equals("0"))
Anyway this is how I would have resolved the problem
public static int zeros(int n) {
int zerocount = 0;
for (int i = 5; n / i > 0; i *= 5) {
zerocount += n / i;
}
return zerocount;
}
A zero in a base-10 representation of a number is a 2*5. In order to determine the number of trailing zeroes you will need to determine how many times can you divide your number with ten, or, in other words, the minimum of the sum of 2 and 5 factors. Due to the fact that 5 is bigger than 2 and we go sequentially, the number of fives will be the number of trailing zeroes.
A naive approach would be to round down n/5, but that will only give you the number of items divisible with 5. However, for example, 25 is divisible by 5 twice. The same can be said about 50. 125 can be divided by 5 three times, no less.
So, the algorithm would look like this:
int items = 0;
int power = 5;
while (power < n) {
items += (int) (n / power);
power *= 5;
}
Here small numbers are in use in relative terms, but it's only a proof of concept.
You do need to use brute force here and you integers will overflow anyway.
With multiplication trailing zero appears only as the result of 2*5.
Now imagine the factorial represented by a product of it's prime factors.
Notice that for every 5 (five) we will always have 2 (two).
So to calculate the number of zeroes we need to calculate the number of fives.
That can be implemented by continuously dividing N by five and totaling results
In Java code that will be something like this:
static int calculate(int n)
{
int result = 0;
while (n > 0 ) {
n /= 5;
result += n;
}
return result;
}
I need a function which can calculate the mathematical combination of (n, k) for a card game.
My current attempt is to use a function based on usual Factorial method :
static long Factorial(long n)
{
return n < 2 ? 1 : n * Factorial(n - 1);
}
static long Combinatory(long n , long k )
{
return Factorial(n) / (Factorial(k) * Factorial(n - k));
}
It's working very well but the matter is when I use some range of number (n value max is 52 and k value max is 4), it keeps me returning a wrong value. E.g :
long comb = Combinatory(52, 2) ; // return 1 which should be actually 1326
I know that it's because I overflow the long when I make Factorial(52) but the range result I need is not as big as it seems.
Is there any way to get over this issue ?
Instead of using the default combinatory formula n! / (k! x (n - k)!), use the recursive property of the combinatory function.
(n, k) = (n - 1, k) + (n - 1, k - 1)
Knowing that : (n, 0) = 1 and (n, n) = 1.
-> It will make you avoid using factorial and overflowing your long.
Here is sample of implementation you can do :
static long Combinatory(long n, long k)
{
if (k == 0 || n == k )
return 1;
return Combinatory(n - 1, k) + Combinatory(n - 1, k - 1);
}
EDIT : With a faster iterative algorithm
static long Combinatory(long n, long k)
{
if (n - k < k)
k = n - k;
long res = 1;
for (int i = 1; i <= k; ++i)
{
res = (res * (n - i + 1)) / i;
}
return res;
}
In C# you can use BigInteger (I think there's a Java equivalent).
e.g.:
static long Combinatory(long n, long k)
{
return (long)(Factorial(new BigInteger(n)) / (Factorial(new BigInteger(k)) * Factorial(new BigInteger(n - k))));
}
static BigInteger Factorial(BigInteger n)
{
return n < 2 ? 1 : n * Factorial(n - 1);
}
You need to add a reference to System.Numerics to use BigInteger.
If this is not for a homework assignment, there is an efficient implementation in Apache's commons-math package
http://commons.apache.org/proper/commons-math/apidocs/org/apache/commons/math3/util/ArithmeticUtils.html#binomialCoefficientDouble%28int,%20int%29
If it is for a homework assignment, start avoiding factorial in your implementation.
Use the property that (n, k) = (n, n-k) to rewrite your choose using the highest value for k.
Then note that you can reduce n!/k!(n-k)! to n * n-1 * n-2 .... * k / (n-k) * (n-k-1) ... * 1 means that you are multiplying every number from [k, n] inclusive, then dividing by every number [1,n-k] inclusive.
// From memory, please verify correctness independently before trusting its use.
//
public long choose(n, k) {
long kPrime = Math.max(k, n-k);
long returnValue = 1;
for(i = kPrime; i <= n; i++) {
returnValue *= i;
}
for(i = 2; i <= n - kPrime; i++) {
returnValue /= i;
}
return returnValue;
}
Please double check the maths, but this is a basic idea you could go down to get a reasonably efficient implementation that will work for numbers up to a poker deck.
The recursive formula is also known as Pascal's triangle, and IMO it's the easiest way to calculate combinatorials. If you're only going to need C(52,k) (for 0<=k<=52) I think it would be best to fill a table with them at program start. The following C code fills a table using this method:
static int64_t* pascals_triangle( int N)
{
int n,k;
int64_t* C = calloc( N+1, sizeof *C);
for( n=0; n<=N; ++n)
{ C[n] = 1;
for( k=n-1; k>0; --k)
{ C[k] += C[k-1];
}
}
return C;
}
After calling this with N=52, for example returns, C[k] will hold C(52,k) for k=0..52
This is a problem from CodeSprint3
https://cs3.interviewstreet.com/challenges/dashboard/#problem/50877a587c389
Basically the problem is to calculate the number of possible combinations,nCr for given n and r.Also, 1 <= n <= 1000000000 and 0 <= r <= n.
Output all answers modulo 142857.
Since 6C4=6!/4! 2!
=6*5/2!
=6*5/2*1
I thought overflow could be avoided using division at every step.That is
to start with value of n (n is 6 in this case).
Decrement n and multiply it with previous value (so this becomes 6*5)
Perform division with denominator and then decrement it ( 6*5 /2 and denominator 2 becomes 1)
Repeat the steps until n is less than the of maximum of 2 denominators and in same number of iterations the divisor (Minimum of denominators will become 1)
int count(int n,int r)
{int maxDen=r>(n-r)?r:n-r; //larger number in the denominator
int minDen=n-maxDen; //the smaller number in denominator
double num=1;
for(int j=n;j>maxDen;j--)
{num=j*num; //for C(6,4) example num=6*5 and so on
// System.out.println("num "+num +" minDen "+minDen);
num=num/minDen; //divide num 6*5 in this case by 2
minDen--;
}
num=num%142875; //output the result modulo 142875
return (int) num;
}
But perhaps due to loss precision as more divisions are performed,it gives wrong values but then it still gives correct output for some values.As it stands correct for 22 17 but not for 24 17.
(22 17) = 26334 //gives Correct value
(24 17)= 60353 //wrong value correct value is 60390
(25,17)=81450 //wrong value correct value is 81576
(16 15)= 16 //gives correct value
(87 28)= 54384 //wrong value correct value is 141525
I tried to use num as a BigDecimal and as a consequence i had to replace everything with a BigDecimal to perform the operations.The output then was the same for the inputs which gave correct results in above code.But for inputs which gave wrong results,the program throws an exception
Exception in thread "main" **java.lang.ArithmeticException: Non-terminating decimal expansion; no exact representable decimal result.**
at java.math.BigDecimal.divide(Unknown Source)
at Combination.NcRcount2.count(NcRcount2.java:16)
at Combination.NcRcount2.main(NcRcount2.java:37)
Line 16 is num=num.divide(minDen); //in replacement to earlier used num/minDen,both num and minDen are BigDecimal in this case
Even though if the number does not have an exact decimal representation,given the arbitrary precision of BigDecimal the error in results would have been minimized if it didn't threw an exception.
** If the result of division on floats or doubles does not have an exact decimal representation then why isn't an exception thrown?**
I verified the results using BigDecimal with the dynamic programming approach as
C(n,r)=C(n-1,r-1)+C(n-1,r)
This works correctly in all cases as it appears to me but there must be a better way
BigDecimal Comb (int n, int k)
{ if(k>n-k)
k=n-k;
BigDecimal B[][]=new BigDecimal[n+1] [k+1];
for (int i = 0; i <= n; i++)
{ int min;
if(i>=k)
min=k;
else
min=i;
for (int j = 0; j <= min; j++)
{ if (j == 0 || j == i)
B[i][j] =new BigDecimal(1);
else{
if(j>i-j)
B[i][j]=B[i][i-j];
else
B[i][j] = B[i - 1][j - 1].add(B[i - 1] [j]);
}
}
}
BigDecimal div=new BigDecimal(142857);
return B[n][k].remainder(div);
}
Please suggest me a better way to do this without using BigDecimal
public class Solution {
public static void main(String arg[]) {
Scanner s = new Scanner(System.in);
List<BigInteger> ar = new ArrayList<BigInteger>();
int tot = Integer.parseInt(s.nextLine());
BigInteger max = BigInteger.ZERO;
for (int i = 0; i < tot; i++) {
String str[] = s.nextLine().split(" ");
Long n1 = Long.parseLong(str[0]);
Long r1 = Long.parseLong(str[1]);
Long nr1 = n1 - r1;
BigInteger n = BigInteger.valueOf(n1);
BigInteger r = BigInteger.valueOf(r1);
BigInteger nr = BigInteger.valueOf(nr1);
ar.add(n);
ar.add(r);
ar.add(nr);
if (n.compareTo(max)==1) {
max=n;
}
if (r.compareTo(max)==1) {
max=r;
}
if (nr.compareTo(max)==1) {
max=nr;
}
}
HashMap<BigInteger,BigInteger> m=new HashMap<BigInteger,BigInteger>();
m.put(BigInteger.ZERO, BigInteger.ONE);
BigInteger fact=BigInteger.ONE;
for(BigInteger i=BigInteger.ONE;i.compareTo(max.add(BigInteger.ONE))==-1;i=i.add(BigInteger.ONE)){
fact=fact.multiply(i);
if(ar.contains(i)){
m.put(i, fact);
}
}
for(int i=0;i<ar.size();i=i+3){
BigInteger n=m.get(ar.get(i));
BigInteger r=m.get(ar.get(i+1));
BigInteger nr=m.get(ar.get(i+2));
BigInteger rem=r.multiply(nr);
BigInteger act=n.divide(rem);
BigInteger res=act.remainder(BigInteger.valueOf(142857));
System.out.println(res);
}
}
}
I think this code might will help you .
Rather straightforward implementation:
public long combinations(int n, int k) {
BigInteger factorialN = factorial(n);
BigInteger factorialK = factorial(k);
BigInteger factorialNMinusK = factorial(n - k);
return factorialN.divide(factorialK.multiply(factorialNMinusK)).longValue();;
}
private BigInteger factorial(int n) {
BigInteger ret = BigInteger.ONE;
for (int i = 1; i <= n; ++i) ret = ret.multiply(BigInteger.valueOf(i));
return ret;
}
The part of your question about an exception with BigDecimal code isn't clear to me so I won't comment on that.
Regarding a sequence of multiplies and divides to compute nCr, wikipedia shows a formula that's easy to implement. Your first section of code in the question might be equivalent to it, as may be the bit of python code just below. It computes up to 61C30 using 64-bit integer arithmetic; 62C31 requires another bit or two.
def D(n, k):
c, j, k = 1, n, min(k,n-k)
for i in range(1,k+1):
c, j = c*j/i, j-1
return c
The reason that this order of computation works, with all divisions being exact divisions, is that nC(j+1) = nCj * (n-j)/(j+1) as is easily verified from nCj = n!/j!(n-j)! and some algebra. That is, you can compute nCr for large n and r completely in integer arithmetic without needing any decimal places.
Suppose K=142857.
Note that reduction of intermediate terms modulo K will cause problems and may be infeasible. If the numerator is reduced mod K, some divisions won't be exact in ordinary arithmetic. If K were prime, the extended GCD algorithm could be used to find inverses mod K for all numbers. But K=3*9*11*13*37 and inverses mod K will not exist for numbers that are multiples of 3, 11, 13, or 37, as a consequence of Bézout's lemma and some modular algebra.
You should not divide.
Draw Pascal triangle in memory. This will require only additions and will easily allow to apply modular arithmetic.
Also, this will last not longer than with divisions, because you can not avoid of calculating factorials.
package tests.StackOverflow;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class q13241166 {
public static void main(String[] args) throws IOException {
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
String s;
String[] ss;
int[] n;
int[] r;
int T;
/*
System.out.println("Input T:");
s = in.readLine();
T = Integer.parseInt(s);
if( T < 1 || T > 100000) {
throw new IllegalArgumentException();
}
*/
T = 9;
/*
n = new int[T];
r = new int[T];
System.out.println("Input n r pairs:");
for(int i=0; i<T; ++i) {
s = in.readLine();
ss = s.split("\\s+");
n[i] = Integer.parseInt(ss[0]);
if( n[i] < 1 || n[i] > 1000000000) {
throw new IllegalArgumentException();
}
r[i] = Integer.parseInt(ss[1]);
if( r[i] < 0 || r[i] > n[i]) {
throw new IllegalArgumentException();
}
}
*/
n = new int[] {2, 4, 5, 10, 22, 24, 25, 16, 87};
r = new int[] {1, 0, 2, 3, 17, 17, 17, 15, 28};
int modulobase = 142857;
int[] answers_old, answers = null;
System.out.println("Output");
for(int i=0; i<T; ++i) {
for( int nn=0; nn<=n[i]; ++nn) {
answers_old = answers;
answers = new int[nn+1];
for( int rr=0; rr<=nn; ++rr) {
if( rr == 0 || rr == nn ) {
answers[rr] = 1;
}
else {
answers[rr] = answers_old[rr-1] + answers_old[rr];
}
answers[rr] %= modulobase;
}
}
System.out.println(answers[r[i]]);
}
}
}
Output follows:
Output
2
1
10
120
26334
60390
81576
16
141525
I tried the following challenge:
Given the first few factorials:
1! = 1
2! = 2 x 1 = 2
3! = 3 x 2 x 1 = 6
4! = 4 x 3 x 2 x 1 = 24
What is the sum of the first 15 factorials, NOT INCLUDING 0!?
My solution in Java is the following:
public class Factorial
{
public static void main(String[] args)
{
int sum = 0;
int multi = 1;
for (int i=1;i<=15;i++)
{
multi = multi*i;
sum = multi+sum;
}
System.out.print(sum);
}
}
I verified the solutions for the first 7 factorials but will it work for the first 15?
It will not work for the first 15 factorials because of integer overflow. The correct answer is 1401602636313, which exceeds Java's int bound of 2147483647. You could either use a long which has a bound of 9223372036854775807 or a BigInteger.
No, its not working for 15. Use long. Also, you could move the print statement inside the loop, to check from where it starts failing. I guess in this case it's 13.
That
public static void printFactorials (int max) {
long fac = 1;
long sum = 0;
for (int i = 1; i <= max; fac *= ++i) {
System.out.println(String.format("Factorial(%2d)=%d", i, fac));
sum += fac;
}
System.out.println(String.format("Sum of Factorials(1 to %2d)=%d", max, sum));
}
gives you
Factorial( 1)=1
Factorial( 2)=2
Factorial( 3)=6
Factorial( 4)=24
Factorial( 5)=120
Factorial( 6)=720
Factorial( 7)=5040
Factorial( 8)=40320
Factorial( 9)=362880
Factorial(10)=3628800
Factorial(11)=39916800
Factorial(12)=479001600
Factorial(13)=6227020800
Factorial(14)=87178291200
Factorial(15)=1307674368000
Sum of Factorials(1 to 15)=1401602636313
long starts to fail at 21, next step is BigInteger
public static void printRlyBigFactorials (int max) {
BigInteger fac = BigInteger.ONE;
BigInteger sum = BigInteger.ZERO;
for (int i = 1; i <= max; ++i) {
fac = fac.multiply(BigInteger.valueOf(i));
sum = sum.add(fac);
System.out.println(String.format("Factorial(%2d)=%d", i, fac));
}
System.out.println(String.format("Sum of Factorials(1 to %2d)=%d", max, sum));
}
That will work almost indefinitely and can give you fancy results like:
Sum of Factorials(1 to 500)=
1222581999810786173488382263893486121736784649845260488587055662127413631697
9142090995417259894466676137016242713788312106218384177808117660024733369428
7060019503701220190523381023699528466605036804597249531428694859689049295904
5138704466475196055082304091214424335155644013903958356823605973150159110295
5787828433482529258832635575855564789877227459384652114477297831606218655683
9245588828671235437927278554210732477499719243692398907465554636521289870187
5799458234466791378320221140358905721655475503366304295011345436395868843079
5463780536087239619245051615759218253091986494512882003123090598805090122753
7135918455294416676103707115038417384516670399033063650562275830354903359872
0775172343137459008549361297203752431405977559950082400276439557196120290170
5516606073135650288107937474531851451830365876392678959480905477335825506233
3795849463603798966643420966668878072957663827751761832039623225350606860709
6479320263132522604054741925038640750661849690108363701190203548476572823422
7743271977187818002695582046473911765828511673121820261887951566200568565033
40092247479478684738621107994804323593105039052556442336528920420940313