Sum of Powers of two Integers using only For-Loops - java

The question here would be to get the sum of powers (m^0 + m^1 + m^2 + m^3.... + m^n) using only FOR loops. Meaning, not using any other loops as well as Math.pow();
Is it even possible? So far, I am only able to work around getting m^n, but not the rest.
public static void main(String[] args){
Scanner scn = new Scanner(System.in);
int total = 1;
System.out.print("Enter value of m: ");
int m = scn.nextInt();
System.out.print("Enter value of n: ");
int n = scn.nextInt();
for (int i = 1; i <= n; i++){
total * m;
}
System.out.print(total);
}
Let's say m =8; and n = 4;
i gives me '1,2,3,4' which is what I need, but I am unable to power m ^ i.
Would be nice if someone could guide me into how it could be done, can't seem to progress onwards as I have limited knowledge in Java.
Thanks in advance!

You might want to rewrite it like this :
m^0 + m^1 + m^2 + m^3.... + m^n = 1 + m * (1 + m * (1 + m * (.... ) ) )
And you do it in a single for loop.
This should do the job (see explanations in comments):
public long count(long m, int pow) {
long result = 1;
for(int i = 0;i<pow; i++) {
result*=m +1;
}
return result;
}

You can nest loops. Use one to compute the powers and another to sum them.

You can do below:
int mul = 1;
total = 1;
for(int i=1;i<=n;i++) {
mul *= m;
total += mul;
}
System.out.println(total);

You can use a single loop which is O(N) instead of nested loops which is O(N^2)
long total = 1, power = m
for (int i = 1; i <= n; i++){
total += power;
power *= m;
}
System.out.print(total);

You can also use the formula for geometric series:
Sum[i = k..k+n](a^i) = (a^k - a^(k+n+1)) / (1 - a)
= a^k * (1 - a^(n+1)) / (1 - a)
With this, the implementation can be done in a single for loop (or 2 simple for loop): either with O(n) simple looping, or with O(log n) exponentiation by squaring.
However, the drawback is that the data type must be able to hold at least (1 - a^(n+1)), while summing up normally only requires the result to fit in the data type.

This is the solution :
for(int i=0;i<n;i++){
temp=1;
for(int j=0;j<=i;j++){
temp *= m;
}
total += temp;
}
System.out.println(total+1);

You can easily calculate powers using your own pow function, something like:
private static long power(int a, int b) {
if (b < 0) {
throw new UnsupportedOperationException("Negative powers not supported.");
}
if (b == 0) {
return 1;
}
if (b == 1) {
return a;
}
return a * power(a, b - 1);
}
Then simply loop over all the values and add them up:
long out = 0;
for (int i = 0; i <= n; ++i) {
out += power(m, i);
}
System.out.println(out);
I would add that this is a classic dynamic programming problem as m^n is m * m^(n-1). I would therefore add caching of previously calculated powers so that you don't have to recalculate.
private static Map<Integer, Long> powers;
public static void main(String args[]) {
int m = 4;
int n = 4;
powers = new HashMap<>();
long out = 0;
for (int i = 0; i <= n; ++i) {
out += power(m, i);
}
System.out.println(out);
System.out.println(powers);
}
private static long power(int a, int b) {
if (b < 0) {
throw new UnsupportedOperationException("Negative powers not supported.");
}
if (b == 0) {
return 1;
}
if (b == 1) {
return a;
}
Long power = powers.get(b);
if (power == null) {
power = a * power(a, b - 1);
powers.put(b, power);
}
return power;
}
This caches calculated values so that you only calculate the next multiple each time.

Related

I tryed to do stairCase problem with n stairs and 1or2or3 steps at a time But my solution is working fine until 13 after that not, its giving less

public class StairCase {
public static int Solution(int n) {
int sum, count = 0;
//Funtion to calculate stair case and use factorial because a solution can have many ways.
for (int i = 0; i <= n; i++) {
for (int j = 0; j <= n; j++) {
for (int k = 0; k <= n; k++) {
sum = i + (j * 2) + (k * 3);
if (sum == n) {
count = count + (fact.fact1(i + j + k) / (fact.fact1(i) * fact.fact1(j) * fact.fact1(k)));
}
}
}
/*logic behind this funtion is that like we have to find no of arrangement abbbccde can we written so we write (8!/(3!*2!))
so after getting like ijk= 1,2,3 I rearranged them in that man ways
(i+j+k)!/i!*j!k! !=factorial/
}
return count;
}
public static void doTestPass() {
boolean result = true;
result = result && (Solution(3) == 4);
result = result && (Solution(4) == 7);
result = result && (Solution(11) == 504);
result = result && (Solution(12) == 927);
result = result && (Solution(13) == 1705);
//working fine till 13 not after that
System.out.println(Solution(14));
System.out.println(Solution(20));
System.out.println(Solution(21));
//14--3127 20--68603 21--94351(orignal ans-- 3136,121415,223317)
if (result) {
System.out.println("All Test Cases Passed");
} else {
System.out.println("Test Case Failed");
}
}
public static void main(String[] Args) {
doTestPass();
}
public class fact
{
static int fact1(int n)
{
//this funtion is to create factorial
int res = 1;
for (int i = 2; i <= n; i++)
{
res = res * i;
}
return res;
}
}
}
The problem has to do with using primitive integers for your factorial method and overflowing the integer limit of 2,147,483,647.
Take a look at trial runs of your factorial code below:
fact1(12) outputs 479001600 which is correct for 12!
fact1(13) outputs 1932053504 which is not 13! which should be 6227020800
This means when you execute fact.fact1(i) in your code, it will be outputting the wrong answer for any value greater than 12. This would require you to rework the data structure you use to hold these big numbers to BigInteger.
The reworked fact method would look like this:
BigInteger fact1(int n) {
// this funtion is to create factorial
BigInteger res = BigInteger.ONE;
for (int i = 2; i <= n; i++) {
res = res.multiply(BigInteger.valueOf(i));
}
return res;
}
With the output of fact1(13) being the correct value of 6227020800 now.
You will need to rework the other aspects of your code now with BigInteger, but you should understand now what your issue was.

How to find the sum of factorial of all numbers in a series?

I want to create a program to find the sum of factorial of all numbers in a series till 20.
I have to find 's' in s = 1 + (1*2) + (1*2*3) + ...(1*2*3...20).
I tried a program but it is not working. I am using BlueJ IDE.
int a =1;
int s = 0;
for(int i = 1; i <= 10; i++)
{
while (i >0)
{
a = a * i;
i--;
}
s = s+a;
}
System.out.println(s);
The compiler does not show any error message but when I run the program the JVM(Java Virtual Machine) keeps loading and the output screen does not show up.
You can try this one :
public class Main
{
public static void main (String[]args)
{
int fact = 1;
int sum = 0;
int i, j = 1;
for (i = 1; i <= 20; i++)
{
for (j = 1; j <= i; j++)
{
fact = fact * j;
}
sum += fact;
System.out.println ("sum = " + sum);
fact = 1;
}
}
}
Always give proper variable name and Try to avoid to use same variable at different places i.e you have use variable i in outer and inner loop which is not good habit.
You should be using a different loop variable name in your inner loop, and you also need to use a long to store your sum. In fact, I would first write a method to multiply up to a number in the series. Like,
static long multiplyTo(int n) {
long r = 1L;
for (int i = 2; i <= n; i++) {
r *= i;
}
return r;
}
Then you can invoke that and calculate your sum with a simple loop. Like,
long sum = 0L;
for (int i = 1; i <= 20; i++) {
sum += multiplyTo(i);
}
System.out.println(sum);
I get
2561327494111820313
Using streams:
long s = LongStream.rangeClosed(1, 20)
.map(upper -> LongStream.rangeClosed(1, upper)
.reduce(1, (a, b) -> a * b))
.sum();
System.out.println(s);
Prints 2561327494111820313
I did the same program using Scanner Class
import java.util.*;
class Sum_Factorial
{
public static void main()
{
Scanner in = new Scanner(System.in);
int i; //Denotes Integer
int n; //Denotes Number
int f=1; //Denotes Factorial
int s=0; //Denotes Sum
System.out.println("Enter the value of N : ");
n=in.nextInt();
for(i=1; i<=n; i++)
{
f=f*i;
s=s+f;
}
System.out.println("Sum of the factorial numbers is "+s);
}
}

Count number of Divisors for all the numbers till N

I need to count all the divisors for every number in the range 1 to n. I have written down below an implementation for, given an integer num, it counts the number of divisors of num. Its complexity is O(sqrt(n)). So over all complexity comes out to be O(n * sqrt(n)). Can it be reduced? If YES, then can you give an algorithm for that?
CODE :
public static int countDivisors(int num)
{
int limit = (int)Math.sqrt(num);
int count = 2;
for(int i = 2 ; i <= limit ; i++)
{
if(num % i == 0)
{
count++;
if(num / i != i)
{
count++;
}
}
}
return count;
}
PS:
This function will be called n times.
You can improve upon the naive approach using kind of a generalized Sieve of Eratosthenes. Instead of just marking the number as composite also store its first divisor that you found (I do this in the function computeDivs below).
class Main
{
// using Sieve of Eratosthenes to factorize all numbers
public static int[] computeDivs(int size) {
int[] divs = new int[size + 1];
for (int i = 0; i < size + 1; ++i) {
divs[i] = 1;
}
int o = (int)Math.sqrt((double)size);
for (int i = 2; i <= size; i += 2) {
divs[i] = 2;
}
for (int i = 3; i <= size; i += 2) {
if (divs[i] != 1) {
continue;
}
divs[i] = i;
if (i <= o) {
for (int j = i * i; j < size; j += 2 * i) {
divs[j] = i;
}
}
}
return divs;
}
// Counting the divisors using the standard fomula
public static int countDivisors(int x, int[] divs) {
int result = 1;
int currentDivisor = divs[x];
int currentCount = 1;
while (currentDivisor != 1) {
x /= currentDivisor;
int newDivisor = divs[x];
if (newDivisor != currentDivisor) {
result *= currentCount + 1;
currentDivisor = newDivisor;
currentCount = 1;
} else {
currentCount++;
}
}
if (x != 1) {
result *= currentCount + 1;
}
return result;
}
public static int countAllDivisors(int upTo) {
int[] divs = computeDivs(upTo + 1);
int result = 0;
for (int i = 1; i <= upTo; ++i) {
result += countDivisors(i, divs);
}
return result;
}
public static void main (String[] args) throws java.lang.Exception {
System.out.println(countAllDivisors(15));
}
}
You can also see the code executed on ideone here.
In short I use the sieve to compute the biggest prime factor for each number. Using this I can compute the factor decomposition of every number very efficiently (and I use this in countDivisors).
It is hard to compute the complexity of the sieve but a standard estimate is O(n * log(n)). Also I am pretty confident it is not possible to improve on that complexity.
You can do much better than O(n.sqrt(n)) by using simple iteration. The code is in C++, but you can easily get the idea.
#include <iostream>
#include <vector>
using namespace std;
void CountDivisors(int n) {
vector<int> cnts(n + 1, 1);
for (int i = 2; i <= n; ++i) {
for (int j = i; j <= n; j += i) {
cnts[j]++;
}
}
for (int i = 1; i <= n; ++i) {
cout << cnts[i] << " \n"[i == n];
}
}
int main() {
CountDivisors(100);
return 0;
}
Running time is n/1 + n/2 + n/3 + n/4 + ... + n/n which can be approximated by O(nH(n)), where H(n) is the harmonic series. I think the value is not bigger than O(nlog(n)).
Using iteration is OK for relatively small numbers. As soon as the number of divisors is getting bigger (over 100-200), the iteration is going to take a significant amount of time.
A better approach would be to count the number of divisors with help of prime factorization of the number.
So, express the number with prime factorization like this:
public static List<Integer> primeFactorizationOfTheNumber(long number) {
List<Integer> primes = new ArrayList<>();
var remainder = number;
var prime = 2;
while (remainder != 1) {
if (remainder % prime == 0) {
primes.add(prime);
remainder = remainder / prime;
} else {
prime++;
}
}
return primes;
}
Next, given the prime factorization, express it in the exponent form, get exponents and add 1 to each of them. Next, multiply resulting numbers. The result will be the count of divisors of a number. More on this here.
private long numberOfDivisorsForNumber(long number) {
var exponentsOfPrimeFactorization = primeFactorizationOfTheNumber(number)
.stream()
.collect(Collectors.groupingBy(Integer::intValue, Collectors.counting()))
.values();
return exponentsOfPrimeFactorization.stream().map(n -> n + 1).reduce(1L, Math::multiplyExact);
}
This algorithm works very fast. For me, it finds a number with 500 divisors within less than a second.

Java IF Statement (Algorithm efficiency improvement)

I used method a that counts the amount of possible choices for getting like number 10 with numbers that are from 0 to 6. Problem is that it just takes too much time when x is like 50 or something. I just need some tips what I should do to make this faster.
Code
public static int count(int x) {
if (x < 0) {
return 0;
}
if (x == 0) {
return 1;
}
int result = 0;
for (int i = 1; i <= 6; i++) {
result += count(x - i);
}
return result;
}
This is a variation on Fibonacci except it is the sum of the last six values instead.
You can use a plain loop which will be faster than memorisation (the first time)
public static long count(int x) {
long a=0, b=0, c=0, d=0, e=0, f=1;
while(x-- > 0) {
long sum = a + b + c + d + e + f;
a = b; b = c; c = d; d = e; e = f;
f = sum;
}
return f;
}
If you call this repeatedly you may as well store all the values in the int range which is likely to be less than 30 the first time and retrieve these values after that.

Interesting Program behaviour for Project Euler p21

I have got a solution for problem 21 in python and it gives the right answer. I tried out someone else's java code and I get the same answer for a value of 10000 and 100000 but when 1000000 is tried, the solution returned by my code differs from two other solutions returned by java code even though all three solutions returned are same for tested values of 10000 and 1000000 and 50000. Anyone got any ideas?
My Python code
def amicable_pairs(n):
"""returns sum of all amicable pairs under n. See project euler for
definition of an amicable pair"""
div_sum = [0]*n
amicable_pairs_set = [0]*n
for i in range(1, n):
for j in range(i*2, n, i):
div_sum[j] += i
#for i in range(1, n):
# div_sum[i] = sum([j + i/j for j in range(2, int(math.sqrt(i)) + 1) if i % j == 0 and i != i/j])
# div_sum[i] = div_sum[i] + 1
#print div_sum
for j in range(n):
if div_sum[j] < n and div_sum[div_sum[j]] == j and div_sum[j] != j:
amicable_pairs_set[j] = j
amicable_pairs_set[div_sum[j]] = div_sum[j]
return sum(amicable_pairs_set)
Java code 1:
public class AmicableNumbers {
public static void main(String[] args) {
long strTime = System.currentTimeMillis();
int sum_ami = 0;
for (int j = 1; j < 1000000; j++) {
int ad = sum_devisors(j);
if (((sum_devisors(ad)) == j) && (j != ad)) {
sum_ami += j;
}
}
System.out.println(sum_ami);
long endTime = System.currentTimeMillis();
System.out.println("time is " + (endTime - strTime) + " ms");
}
public static int sum_devisors(int number) {
if ((number == 1) || (number == 2)) {
return 1;
}
int sum = 0;
int k = (int) Math.sqrt(number);
for (int i = 2; i < k; i++) {
if (number % i == 0) {
sum += i;
sum += (number / i);
}
}
if (k * k == number) {
sum += k;
}
return (sum + 1);// every number divided by 1
}
}
Java code 2:
import java.util.Scanner;
public class AmicableNumbers {
/**
* #author Pavan Koppolu
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
//scan the input
System.out.println("Enter a number, to find out sum of amicable numbers: ");
Scanner scan=new Scanner(System.in);
int input=scan.nextInt();
long before=System.currentTimeMillis();
// getting the result
long result=sumOfAllAmicableNumbersUptoGivenNumber(input);
long after=System.currentTimeMillis();
// prints the result on the console
System.out.println("Sum of all amicable numbers below "+input+" : "+result+" Elasped Time : "+(after-before)+" ms");
}
/*
* calculate the sum of the amicable numbers upto the given number
*/
private static long sumOfAllAmicableNumbersUptoGivenNumber(int input)
{
long sum=0,factorsSum=0,sumOfFactors=0;
for(long j=2;j<input;j++)
{
factorsSum=getFactorsSum(j);
if(j!=factorsSum)
{
sumOfFactors=getFactorsSum(factorsSum);
if(j==sumOfFactors)
sum+=j;
}
else
continue;
}
return sum;
}
/*
* find out the sum of the factors
*/
private static long getFactorsSum(long j)
{
long sum=1;
for(int k=2;k<=Math.sqrt(j);k++)
{
if(j%k==0)
sum+=k+j/k;
}
return sum;
}
}
In fact the solutions returned by all three above differ from each other for an input of 1000000
The point is that there are amicable pairs where one partner is less than 1 million and the other is larger than 1 million, namely
(947835,1125765), (998104,1043096)
The Python code doesn't count them,
for j in range(n):
if div_sum[j] < n and div_sum[div_sum[j]] == j and div_sum[j] != j:
but the Java code counts the smaller members of these pairs. That explains the output of the second Java code, since
25275024 + 947835 + 998104 == 27220963
The output of the first Java code is smaller because it omits the amicable pair
(356408, 399592)
The reason is that
356408 = 596*598
but in the code there is
int k = (int) Math.sqrt(number);
for (int i = 2; i < k; i++) {
thus the divisor sum is miscalculated for all numbers divisible by floor(sqrt(n)) that are not squares (Note that the second Java code miscalculates the divisor sum for all squares).

Categories

Resources