factorial of given number - java

I would like to find the smallest factorial of a given long number. For example, if you enter the number 100, the code should give the factorial 5, since 5! = 1 * 2 * 3 * 4 * 5 = 120 is closer than the factorial 4! = 1 * 2 * 3 * 4 = 24. I have written the code below, but when I enter 100, I only get the factorial 3.
import java.util.Scanner;
class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
long number = scanner.nextLong();
long factorial = 1;
long sum;
do {
sum = number / factorial;
factorial++;
} while (number <= sum);
System.out.println(factorial);
}
}
What am I doing wrong here?

you should calculate the factorial of numbers, untill you find an equal or smaller number than the number you entered, as shown in the following code :
import java.util.Scanner;
class Main {
public Long factorial (int n){
long p = 1L;
for(int i = 1; i<= n ; i++){
p=p*i;
}
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
long number = scanner.nextLong();
long i = 1;
while (factorial(i) < number) {
i++;
}
System.out.println(i);
}

Here is one way. This will return the smallest factorial greater than the number. A record is used to return the information.
record Factorial(long n, long nFact) {}
Integer[] data = {1,2,5,10,200,500,2520,1000, 5040, 720, 2000, 3000, 10_000};
for (long i : data) {
Factorial result = smallestFactorial(i);
System.out.printf("For %-8d the smallest >= %8d is (%d! = %d)%n",
i, i, result.n, result.nFact);
}
prints
For 1 the smallest >= 1 is (2! = 2)
For 2 the smallest >= 2 is (2! = 2)
For 5 the smallest >= 5 is (3! = 6)
For 10 the smallest >= 10 is (4! = 24)
For 200 the smallest >= 200 is (6! = 720)
For 500 the smallest >= 500 is (6! = 720)
For 2520 the smallest >= 2520 is (7! = 5040)
For 1000 the smallest >= 1000 is (7! = 5040)
For 5040 the smallest >= 5040 is (7! = 5040)
For 720 the smallest >= 720 is (6! = 720)
For 2000 the smallest >= 2000 is (7! = 5040)
For 3000 the smallest >= 3000 is (7! = 5040)
For 10000 the smallest >= 10000 is (8! = 40320)
This method calculates the factorial while comparing to the passed argument.
to save time it memoizes the factorials computed
continue calculating factorials until the factorial exceeds the argument.
Then return the information in a record.
public static Factorial smallestFactorial(long n) {
if (n <= 1) {
return new Factorial(2,2);
}
long fact = factorials.floorKey(n);
int k = factorials.get(fact);
while (n > fact) {
fact*=++k;
factorials.putIfAbsent(fact, k);
}
return new Factorial(k, fact);
}
The output formatting is incidental and can of course be changed to suit your requirements.

Related

Highly divisible triangular number

Highly divisible triangular number, my solution
My solution of challenge from Project Euler takes too much time to execute. Although on lower numbers it works fine. Anyone could look up to my code and give me any advice to improve it?
The content of the task is:
The sequence of triangle numbers is generated by adding the natural numbers. So the 7th triangle number would be 1 + 2 + 3 + 4 + 5 + 6 + 7 = 28. The first ten terms would be:
1, 3, 6, 10, 15, 21, 28, 36, 45, 55, ...
Let us list the factors of the first seven triangle numbers:
(1: 1),
(3: 1,3),
(6: 1,2,3,6),
(10: 1,2,5,10),
(15: 1,3,5,15),
(21: 1,3,7,21),
(28: 1,2,4,7,14,28).
We can see that 28 is the first triangle number to have over five divisors.
What is the value of the first triangle number to have over five hundred divisors?
`public static void main(String[] args) {
int sum = 0;
int count = 0;
for (int i = 1; i <= Integer.MAX_VALUE; i++) {
sum += i;
for (int j = 1; j <= sum; j++) {
if (sum % j == 0) {
count++;
}
}
if (count > 500) {
System.out.println(sum);
break;
} else {
count = 0;
}
}
}`
Consider any set of primes (p1, p2, p3. . . pn) that factor a given number. Then the total number of divisors of that number are the products of (e1 + 1, e2 + 1, e3 + 1 ... en+1) where e is the exponent of the corresponding prime factor (i.e. the number of times that prime divides some number N).
There are three pieces to this answer.
The main driver code
the method to find the prime divisors.
and a Primes class that generates successive primes using an iterator.
The Driver
first instantiate the Primes class and initialize the triangleNo
Then continually generate the next triangular number until the returned divisor count meets the requirements.
Primes primes = new Primes();
long triangleNo = 0;
for (long i = 1;; i++) {
triangleNo += i;
int divisors = getDivisorCount(triangleNo, primes);
if (divisors > 500) {
System.out.println("No = " + triangleNo);
System.out.println("Divisors = " + divisors);
System.out.println("Nth Triangle = " + i);
break;
}
}
prints
No = 76576500
Divisors = 576
Nth Triangle = 12375 NOTE: this is the value n in n(n+1)/2.
Finding the prime factors
takes a value to factor and an instance of the Primes class
continues to test each prime for division, counting the number of times the remainder is 0.
a running product totalDivisors is computed.
the loop continues until t is reduced to 1 or the current prime exceeds the square root of the original value.
public static int getDivisorCount(long t, Primes primes) {
primes.reset();
Iterator<Integer> iter = primes;
int totalDivisors = 1;
long sqrtT = (long)Math.sqrt(t);
while (t > 1 && iter.hasNext()) {
int count = 0;
int prime = iter.next();
while (t % prime == 0) {
count++;
t /= prime;
}
totalDivisors *= (count + 1);
if (prime > sqrtT) {
break;
}
}
return totalDivisors;
}
The Primes class
A class to generate primes with a resettable iterator (to preserve computed primes from previous runs the index of an internal list is set to 0.)
an iterator was chosen to avoid generating primes which may not be required to obtain the desired result.
A value to limit the largest prime may be specified or it may run to the default.
Each value is tested by dividing by the previously computed primes.
And either added to the current list or ignored as appropriate.
if more primes are needed, hashNext invoked a generating to increase the number and returns true or false based on the limit.
class Primes implements Iterator<Integer> {
private int lastPrime = 5;
private List<Integer> primes =
new ArrayList<>(List.of(2, 3, 5));
private int index = 0;
private int max = Integer.MAX_VALUE;
public Primes() {
}
public Primes(int max) {
this.max = max;
}
#Override
public boolean hasNext() {
if (index >= primes.size()) {
generate(15); // add some more
}
return primes.get(index) < max;
}
#Override
public Integer next() {
return primes.get(index++);
}
private void generate(int n) {
outer: for (int candidate = lastPrime + 2;;
candidate += 2) {
for (int p : primes) {
if (p < Math.sqrt(candidate)) {
if (candidate % p == 0) {
continue outer;
}
}
}
primes.add(candidate);
lastPrime = candidate;
if (n-- == 0) {
return;
}
}
}
public void reset() {
index = 0;
}
}
Note: It is very likely that this answer can be improved, by employing numerical shortcuts using concepts in the area of number theory or perhaps even basic algebra.

Calculate amicable numbers efficiently to a very high upper limit in java

I have a program that computes amicable pairs of numbers up to a certain limit and prints them out to Stdout. FYI - two numbers are amicable if each is equal to the sum of the proper divisors of the other (for example, 220 and 284).
My program works fine for the first 8 or so pairs, but the problem is when the limit gets to a very high number e.g 5 million it becomes very slow. Is there a way to optimize this so that it computes much faster?
Here is my code
public class Amicable{
private static int num1, num2, limit = 5000000;
public static void main(String[] args){
for(int i = 1; i < limit;i++){
num1= sumOfDivisors(i);
num2 = sumOfDivisors(i)
if(num1 == num2){
System.out.println(num2 + " " + num1);
}
}
}
}
private static int sumOfDivisors(int n){
int sum = 0;
for(int i=1;i<=n/2;i++){
if(n%i==0){
sum =sum+i;
}
}
return sum;
}
}
You should make the innermost loop efficient.
static int sumOfDivisors(int n) {
int sum = 1;
int max = (int) Math.sqrt(n);
if (n > 1 && max * max == n) // in case of n is perfect square number
sum -= max;
for (int i = 2; i <= max; ++i)
if (n % i == 0)
sum += i + n / i;
return sum;
}
If n = 220, it is divisible by 2, so you can add 2 and 110 to the sum at the same time. However, if n is a perfect square number, for example n = 100, it is divisible by 10, but if 10 and 10 are added, they will duplicate, so subtract it in advance.
output for limit =2000000:
220 284
1184 1210
2620 2924
5020 5564
6232 6368
10744 10856
12285 14595
17296 18416
63020 76084
66928 66992
.....
1468324 1749212
1511930 1598470
1669910 2062570
1798875 1870245
It took 7 seconds on my PC.
You could change the statement of "if(i<num1)" to "if(i<num1 || num1<limit)".
This is a more efficient and faster approach.
Inside sumOfDivisors:
Start iteration from 2. (no a big deal) and add 1 during return time with sum as 1 is also a divisor.
Modify loop termination logic, i <= Math.sqrt(n).
For any number ‘num’ all its divisors are always less than and equal to ‘num/2’ and all prime factors are always less than and equal to sqrt(num).
If n%i == 0, then check, both divisors are are equal or not. If equal, take one if not equal then take both one.
private static int sumOfDivisors(int n) {
int sum = 0;
int sqrt = Math.sqrt(n);
for (int i = 2; i <= sqrt; i++) {
if (n % i == 0) {
if(i == (n/i))
sum = sum + i;
else
sum += (i+ n/i);
}
}
return sum+1;
}

euler project 23 - can't find the mistake in my code [Java]

After a week that I spent stuck on this problem I can't find where is my mistake.
the problem is:
A perfect number is a number for which the sum of its proper divisors is exactly equal to the number. For example, the sum of the proper divisors of 28 would be 1 + 2 + 4 + 7 + 14 = 28, which means that 28 is a perfect number.
A number n is called deficient if the sum of its proper divisors is less than n and it is called abundant if this sum exceeds n.
As 12 is the smallest abundant number, 1 + 2 + 3 + 4 + 6 = 16, the smallest number that can be written as the sum of two abundant numbers is 24. By mathematical analysis, it can be shown that all integers greater than 28123 can be written as the sum of two abundant numbers. However, this upper limit cannot be reduced any further by analysis even though it is known that the greatest number that cannot be expressed as the sum of two abundant numbers is less than this limit.
Find the sum of all the positive integers which cannot be written as the sum of two abundant numbers.
so my code is:
package eulerProject;
import java.util.*;
import java.math.BigInteger;
public class e23 {
public static void main(String[] args) {
ArrayList<Integer> list = new ArrayList<>();
BigInteger sum = BigInteger.ZERO;
for (int i = 1; i <= 28123; i++) {
if (!check(i))
list.add(i);
}
System.out.println(list);
for (int i = 0; i < list.size(); i++)
sum = sum.add(BigInteger.valueOf(list.get(i)));
System.out.println(sum);
}
public static boolean check(long z) {
long y = 0;
for (long i = 1; i <= z / 2; i++) {
if (abundant(i)) {
y = z - i;
if (abundant(y)) {
return true;
}
y = 0;
}
}
return false;
}
public static long sum(long x) {
long sum = 0;
for (int i = 1; i < (Math.sqrt(x)); i++) {
if (x % i == 0) {
if (x / i == i) {
sum += i;
} else {
sum = sum + i + (x / i);
}
}
}
sum = sum - x;
return sum;
}
public static boolean abundant(long x) {
if (sum(x) > x)
return true;
return false;
}
}
I'll just explain the methods:
"sum" - sums all the proper divisors of a number.
(like number = 12 , so it sum: 1+2+3+4+6.)
"abundant" - just checks if the number is abundant or not by compairing the sum of his divisors and the number itself.
"check" - generating two numbers which their sum is the number we checking - and checking if the both numbers are abundant. if they are so returns true.
and the main just generating numbers until the max limit, adding to list and then I sum the list.
my answer is: 4190404.
the correct answer is: 4179871.
where is the mistake?
Your sum method doesn't get the correct sum for perfect squares because your loop stops before the square root. For example, if you called sum(16), the loop would run up to i = 3 and stop, so 4 would not contribute to the sum.
Solution:
(I also fixed some inefficiencies.)
public static long sum(long x){
long sum = 1;
int sqrt = (int)Math.sqrt(x);
for (int i = 2; i <= sqrt; i++) {
if (x % i == 0) {
sum += i + (x/i);
}
}
//checks if perfect square and subtracts out extra square root.
if(sqrt * sqrt == x) sum -= sqrt;
return sum;
}

Basic Prime Factorization with Exponents in Java

The Problem:
Any positive integer can be expressed as a unique product of prime numbers, also know as its prime factorization. For example:
60 = 2^2 * 3 * 5
Write a program to compute the prime factorization of a positive integer.
Input: A single integer, n, where n ≥ 2.
Output: A string with the format: “p^a * q^b * ...”, where p and q are primes, and a and b are exponents. If an exponent is 1, then it should be omitted.
I've got everything else down, I just need to find a way to put it into “p^a * q^b * ...” form.
Here is my code:
import java.util.Scanner;
public class PrimeFactorization {
public static void main(String[] args) {
// Input: A single integer, n, where n is greater than or equal to 2.
System.out.println("Please input an integer greater than or equal to two!");
System.out.println("This number will be factored.");
Scanner inputNum = new Scanner(System.in);
int toBFactored = inputNum.nextInt();
// If the input does not fit the requirements, ask again for an input.
while (toBFactored < 2) {
System.out.println("Please input an integer greater than or equal to two.");
toBFactored = inputNum.nextInt();
}
// Output: A string with the format: "p^a * q^b * ...", where p and q are
// primes, and a and b are exponents.
// Decide first if a number (testNum) is prime.
int primedecider = 0;
for (int testNum = 2; testNum < toBFactored; testNum ++) {
for (int factor = 2; factor < testNum; factor ++) {
if (testNum % factor != 0 || testNum == 2) {
// Do nothing if prime.
} else {
primedecider += 1;
// Add if composite.
}
}
// If testNum is prime, if primedecider = 0, test if testNum divides
// evenly into toBFactored.
while (primedecider == 0 && toBFactored % testNum == 0 {
System.out.print(testNum + " ");
toBFactored /= testNum;
}
}
System.out.print(toBFactored);
inputNum.close();
}
}
My output for 120 is "2 2 2 3 5". How do I make it into 2^3 * 3 * 5?
If instead of printing the factors with System.out.println,
if you put them in a list,
then these functions will format them in the way you described.
This is of course just one of the many ways of doing this.
private String formatFactors(List<Integer> factors) {
StringBuilder builder = new StringBuilder();
int prev = factors.get(0);
int power = 1;
int factor = prev;
for (int i = 1; i < factors.size(); ++i) {
factor = factors.get(i);
if (factor == prev) {
++power;
} else {
appendFactor(builder, prev, power);
prev = factor;
power = 1;
}
}
appendFactor(builder, factor, power);
return builder.substring(3);
}
private void appendFactor(StringBuilder builder, int factor, int power) {
builder.append(" * ").append(factor);
if (power > 1) {
builder.append("^").append(power);
}
}

Project-Euler -- Problem20

I thought I solved this problem but the program output "0". I don't see any problem. Thank you for helping.
Question :
n! means n × (n − 1) × ... × 3 × 2 × 1
For example, 10! = 10 × 9 × ... × 3 × 2 × 1 = 3628800, and the sum of
the digits in the number 10! is 3 + 6 + 2 + 8 + 8 + 0 + 0 = 27.
Find the sum of the digits in the number 100!
package projecteuler;
public class problem20 {
public static void main(String[] args)
{
int sayi=0;
int carpim=1;
for(int i=100;i>=1;i--)
{
carpim*=i;
}
String carp=""+carpim;
int[] dizi = new int[carp.length()];
String[] dizis=new String[carp.length()];
for(int i=0;i<carp.length();i++)
{
dizis[i]=carp.substring(i);
}
for(int i=0;i<carp.length();i++)
{
dizi[i]=Integer.parseInt(dizis[i]);
sayi+=dizi[i];
}
System.out.println(sayi);
}
}
100! is 93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000
, and that exceeds the valid range of an int (by rather a lot). Try using a BigInteger. To get you started,
BigInteger carpim = BigInteger.ONE;
for (int i = 100; i >= 1; i--) {
carpim = carpim.multiply(BigInteger.valueOf(i));
}
System.out.println(carpim);
The output of which is the number mentioned before.
It appears the number is overflowing. https://ideone.com/UkXQ4e
4611686018427387904
-4611686018427387904
-9223372036854775808
-9223372036854775808
0
0
0
You might want to try a different class for the factorial like BigInteger
In college, I got this example for finding n! using this algorithm. this is based on the fact that n! = n * (n-1)! (for example, 5! = 4 * 3!). Using a recursive algorithm:
function factorial(n)
if (n = 0) return 1
while (n != 0)
return n * [factorial(n-1)]
once you have 100!, its easy to parse it as String and make Integers out of it to get the sum
int sum = 0;
for (Character c : yourBigInteger.toString().toCharArray()) {
sum = sum + Integer.parseInt(c.toString());
}
System.out.println(sum);
public static void descomposicionFactorial(int num) {
BigInteger factorial = BigInteger.ONE;
for (int i = num; i > 0; i--) {
factorial = factorial.multiply(BigInteger.valueOf(i));
}
String aux =factorial.toString();
char cantidad[] = aux.toCharArray();
int suma = 0, numero = 0;
for (int i = 0; i <cantidad.length; i++) {
numero = cantidad[i] - '0';
suma += numero;
}
System.out.println(suma);
}

Categories