Number trailing zeros in factorial in java - java

import java.util.Scanner;
import java.io.*;
class factorial {
void fact(int a) {
int i;
int ar[] = new int[10000];
int fact = 1, count = 0;
for (i = 1; i <= a; i++) {
fact = fact * i;
}
String str1 = Integer.toString(fact);
int len = str1.length();
i = 0;
do {
ar[i] = fact % 10;
fact /= 10;
i++;
} while (fact != 0);
for (i = 0; i < len; i++) {
if (ar[i] == 0) {
count = count + 1;
}
}
System.out.println(count);
}
public static void main(String...ab) {
int a;
Scanner input = new Scanner(System.in);
a = input.nextInt();
factorial ob = new factorial();
ob.fact(a);
}
}
This code is work up to a = 10 but after enter number larger then a = 16 it gives wrong answer.
Please help.
As I am not able to post this question if I dont add more info for this question but I assume that the info I provide above is enough to under stand what I want.

Like many of these mathematical puzzles, you are expected to simplify the problem to make it practical. You need to find how many powers of ten in a factorial, not calculate a factorial and then find the number of trailing zeros.
The simplest solution is to count the number of powers of five. The reason you only need to count powers of five is that there is plenty of even numbers in between then to make a 10. For example, 5! has one 0, 10! has 2, 15! has three, 20! has four, and 25! has not five but six as 25 = 5 * 5.
In short you only need calculate the number of powers of five between 1 and N.
// floor(N/5) + floor(N/25) + floor(N/125) + floor(N/625) ...
public static long powersOfTenForFactorial(long n) {
long sum = 0;
while (n >= 5) {
n /= 5;
sum += n;
}
return sum;
}
Note: This will calculate the trailing zeros of Long.MAX_VALUE! in a faction of a second, whereas trying this with BigInteger wouldn't fit, no matter how much memory you had.

Please Note, this is not the mathematical solution as others suggested, this is just a refactoring of what he had initially...
Here I just used BigInteger in place of Int, and simplified your code abit. Your solution is still not optimal. I thought I would just show you what a refactored version of what you posted may look like. Also there was a bug in your initial function. It returned the number of zeros in the whole number instead of just the number of trailing zeros.
import java.math.BigInteger;
import java.util.Scanner;
class factorial {
public static void main(String... ab) {
Scanner input = new Scanner(System.in);
int a = input.nextInt();
fact(a);
}
private static void fact(int a) {
BigInteger fact = BigInteger.ONE;
int i, count = 0;
for (i = 1; i <= a; i++) {
fact = fact.multiply(new BigInteger(Integer.toString(i)));
}
String str1 = fact.toString();
for(int j = str1.length() - 1; j > -1; j--) {
if(Character.digit(str1.charAt(j), 10) != 0) {
System.out.println(count);
break;
} else {
count++;
}
}
}
}

Without using factorial
public class TrailingZero {
public static void main(String[] args) {
// TODO Auto-generated method stub
System.out.println(trailingZeroes(9247));
}
public static int trailingZeroes(int a) {
int countTwo = 0;
int countFive = 0;
for (int i = a; i > 1; i--) {
int local = i;
while (local > 1) {
if (local % 2 != 0) {
break;
}
local = local / 2;
countTwo++;
}
while (local > 1) {
if (local % 5 != 0) {
break;
} else {
local = local / 5;
countFive++;
}
}
}
return Math.min(countTwo, countFive);
}}

Related

how do i get even placed digits from a number in java

I want my program to get all the even digits from a number input. Then multiply those with digits with 2. If the result is a two digit number, add them. At the end i want it to give me the sum of all the even digits.
public class evenplaceadd {
public static void main(String[] args) {
System.out.println(sumOfevenPlace(5566));
}
public static int sumOfevenPlace(int number)
{
int maxDigitLength = 4;
int sum = 0;
for (int i = 0; i < maxDigitLength; i++)
{
if (i % 2 == 0)
{
int digita = number % 10;
int digitb =digita*2;
int digitc;
if(digita < 9)
{
sum = sum + digitb;
}
else if(digitb>9)
{
digitc =(digitb % 10)+ (digitb /10);
sum =sum + digitc;
}
}
else
{
number = number/10;
}
}
return sum;
}
}
Your code seems ok for the most part. There are some minor flaws in the code which I am sure you will be able to figure out after understanding the code provided below. I have changed it up a bit and made it easier to read. Please confirm it is working, and next time please provide the code when asking question. I know you are new to the community, and so am I. Its a learning experience for all of us. All the best in the future :)
public static void int sumOfEvenDigits(int num){
int sum = 0;
int lastDig = 0;
while(num/10 != 0)
{
lastDig = num % 10;
num = num / 10;
if(lastDig % 2 != 0)
{
continue;
}
if(lastDig > 10)
{
sum += lastDig / 10;
sum += lastDig % 10;
}
else
{
sum += lastDig;
}
}
return sum;
}

Prime numbers in a given range with less complexity

I have used below programs to find first n prime numbers (in below program it is from 2 to n). Can we write a program with single for loop? I also tried recursive approach but it is not working for me.
public static void main(String[] args) {
// Prime numbers in a range
int range = 15;
int num = 1;
int count = 0;
boolean prime = true;
while (count < range) {
num = num + 1;
prime = true;
for (int i = 2; i <= num / 2; i++) {
if (num % i == 0) {
prime = false;
break;
}
}
if (prime) {
count++;
System.out.println(num);
}
}
}
i dont think you can reduce it to one loop. But you can improve your code as Luca mentioned it.
public class PrimeFinder {
private final List<Integer> primes;
private final int primeCapacity;
public PrimeFinder(final int primeCapacity) {
if (primeCapacity < 3) {
throw new IllegalArgumentException("Tkat is way to easy.");
}
this.primeCapacity = primeCapacity;
primes = new ArrayList<>(primeCapacity);
primes.add(2);
}
public void find() {
final Index currentNumber = new Index();
while (primes.size() < primeCapacity) {
if (!primes.stream().parallel().anyMatch(prime -> (currentNumber.value % prime) == 0)) {
primes.add(currentNumber.incremet());
} else {
currentNumber.incremet();
}
}
}
public List<Integer> getPrimes() {
return primes;
}
private class Index {
public int value = 3;
public int incremet() {
return value++;
}
}
public static void main(String[] args) {
PrimeFinder primeFinder = new PrimeFinder(100000);
final long start = System.currentTimeMillis();
primeFinder.find();
final long finish = System.currentTimeMillis();
System.out.println("Score after " + (finish - start) + " milis.");
primeFinder.getPrimes().stream().forEach((prime) -> {
System.out.println(prime);
});
}
}
main rule here is simple, if given number isnt clearly divided by any prime number that you already have found, then it is prime number.
P.S. dont forget that primes.strem().... is loop also, so it is not a one loop code.
P.S.S. you can reduce this much further.
to understand the complexity of your algorithm you don't have to count the number of inner loops but the number of times you are iterating over your elements. To improve the performance of your algorithm you need to investigate if there are some iterations that could be unnecessary.
In your case when you do
for (int i = 2; i <= num / 2; i++) you are testing your num against values that are not necessary.. ex: if a number is divisible by 4 it will be by 2 too.
when you do for (int i = 2; i <= num / 2; i++) with num = 11
i will assume the values 2,3,4,5. 4 here is a not interesting number and represent an iteration that could be avoided.
anyway according to wikipedia the sieve of Eratosthenes is one of the most efficient ways to find all of the smaller primes.
public class PrimeSieve {
public static void main(String[] args) {
int N = Integer.parseInt(args[0]);
// initially assume all integers are prime
boolean[] isPrime = new boolean[N + 1];
for (int i = 2; i <= N; i++) {
isPrime[i] = true;
}
// mark non-primes <= N using Sieve of Eratosthenes
for (int i = 2; i*i <= N; i++) {
// if i is prime, then mark multiples of i as nonprime
// suffices to consider mutiples i, i+1, ..., N/i
if (isPrime[i]) {
for (int j = i; i*j <= N; j++) {
isPrime[i*j] = false;
}
}
}
// count primes
int primes = 0;
for (int i = 2; i <= N; i++) {
if (isPrime[i]) primes++;
}
System.out.println("The number of primes <= " + N + " is " + primes);
}
}
I don't know any way use a single loop for your question, but I do see two places where you can reduce the complexity:
Cache the prime numbers you found and use these prime numbers to decide if a number is prime or not. For example, to decide if 11 is a prime number, you just need to divide it by 2,3,5,7 instead of 2,3,4,5,6,...10
You don't need to check till num/2, you only need to check till the square root of num. For example, for 10, you only need to check 2,3 instead of 2,3,4,5. Because if number n is not prime, then n = a * b where either a or b is smaller than the square root x of n). If a is the smaller one, knowing that n can be divided by a is enough to decide that n is not prime.
So combining 1 & 2, you can improve the efficiency of your loops:
public static void main(String[] args) {
// Prime numbers in a range
int range = 15;
int num = 1;
int count = 0;
boolean prime = true;
ArrayList<Integer> primes = new ArrayList<>(range);
while (num < range) {
num = num + 1;
prime = true;
int numSquareRoot = (int) Math.floor(Math.pow(num, 0.5));
for (Integer smallPrimes : primes) {// only need to divide by the primes smaller than num
if (numSquareRoot > numSquareRoot) {// only need to check till the square root of num
break;
}
if (num % smallPrimes == 0) {
prime = false;
break;
}
}
if (prime) {
System.out.println(num);
primes.add(num);// cache the primes
}
}
}

sum of digits till the sum is one-digit number

I am a beginner java and trying to solve tricky problem
input=777
output should be 3
7+7+7=21 , 2+1=3;
From the above code if my input is 333 I am getting 9 as answer but when the sum is two digits(777=21) i am getting blank!
public static void main(String[] args)
{
int y=333;//if y is 777 i am getting blank
int sum=0;
String s;
char []ch;
do
{
s=String.valueOf(y);
ch=s.toCharArray();
if(ch.length>1)
{
for(int i=0;i<ch.length;i++)
{
sum+=Character.getNumericValue(ch[i]);
}
}
else
{
System.out.println(sum);
}
y=sum;
}while(ch.length>1);
}
your code maybe loop forever
the right solution is the following below
public static void main(String[] args) throws ParseException {
int y = 777;// if y is 777 i am getting blank
int sum = 0;
String s;
char[] ch;
do {
sum = 0;
s = String.valueOf(y);
ch = s.toCharArray();
if (ch.length > 1) {
for (int i = 0; i < ch.length; i++) {
sum += Character.getNumericValue(ch[i]);
}
} else {
System.out.println(ch[0]);
break;
}
y = sum;
} while (ch.length > 1);
}
Maybe the better choice is the following code
public static void main(String[] args) throws ParseException {
int y = 333;// if y is 777 i am getting blank
int sum = 0;
while (y % 10 != 0) {
sum += y %10;
y = y / 10;
if (0 == y && sum >= 10) {
y = sum;
sum = 0;
}
}
System.out.println(sum);
}
hope that helped
For a task like this, it is best practise to use recursion.
The workflow in pseudocode would look like this:
procedure sumTillOneDigit(n)
split n into it's digits
s := sum of all digits of n
if s has more than one digit:
sumTillOneDigit(s)
else
output s
I am intentionally writing this in pseudocode, since this should help you solving the task. I will not give you a Java implementation, as it looks like a homework to me.
For more information see:
https://en.wikipedia.org/wiki/Recursion_(computer_science)
http://introcs.cs.princeton.edu/java/23recursion/
You are getting that because you put the print statement in else condition..
Also note that to reset your sum value before reusing it. I.e. Set sum=0 at the start of do loop.
EDIT : there are two solutions to print you value
1. Don't put you print statements inside else conditions
Print sum outside the do while loop
First of all you must reset the value of sum variable.
and secondly you must print s in else condition and not the sum and rest is fine.
public static void main(String[] args)
{
int y=333;//if y is 777 i am getting blank
int sum;
String s;
char []ch;
do
{
sum=0;
s=String.valueOf(y);
ch=s.toCharArray();
if(ch.length>1)
{
for(int i=0;i<ch.length;i++)
{
sum+=Character.getNumericValue(ch[i]);
}
}
else
{
System.out.println(s);
}
y=sum;
}while(ch.length>1);
}
I think your solution has wrong basics. There is no point to convert your number to String and handle this as char array. You are doing too much unnecessary operations.
You can do is simpler if you stick with numbers.
You can do it using recursion:
public static int sumRec(int number){
if (number<10){
return number;
}
int sum = 0;
while(number!=0){
sum += number %10;
number /= 10;
}
return sumRec(sum);
}
or itteration
public static int sumIt(int number){
while(number>=10){
int sum = 0;
while(number!=0){
sum += number %10;
number /= 10;
}
number = sum;
}
return number;
}
it is much simpler, right?
You can solve this by 1 line:
public static int sumDigits(int n) {
return (1 + ((n-1) % 9);
}
For example: input 777--> return 1 + ( (777-1) % 9) = 3
Also can work with negative number.
Recursive variant
public static int myFunction(int num){
if(num/10 == 0){
return num;
}
int digitSum = num%10 + myFunction(num/10);
if(digitSum/10 == 0){
return digitSum;
}
return myFunction(digitSum);
}
public static int sum_of_digits(int n) {
return --n % 9 + 1;
}

How to print a variable as defined in a method?

public class Program {
public static void main(String[] args) {
int lastFibo = 1; // ADDED TO check if last fib calculated is over 4000000
for (int i = 3; lastFibo <= 4000000; i = i + (i - 1)) {
lastFibo = fibo(i);
}
}
public static int fibo(int i) {
int total = 0;
if (i % 2 == 0) {
total += i;
return total;
}
return total;
}
}
The purpose of this code is to print the sum of even numbers in the fibonacci sequence who's values are less than 4 million. Using recursion the code returns a stack overflow error so it was recommended to iterate through the numbers. The difficulty encountered was knowing how to print the "total" variable. Scope articles are very basic and creating a static int total = 0 would return 0.
First, as pointed out by some comments: your for loop will not iterate the Fibonacci sequence. Second, the variable total exists only in the scope of your fibo method. So every time the method is called, total starts with the value 0.
Use the correct Fibonacci algorithm and add the return value of the fibo method up to calculate the sum:
public class Program {
public static void main(String[] args) {
int total = 0;
int previousValue = 0;
int currentValue = 1;
while (currentValue < 4_000_000) {
int nextPreviousValue = currentValue;
currentValue += previousValue;
previousValue = nextPreviousValue;
total += fibo(currentValue);
}
System.out.println(total);
}
public static int fibo(int i) {
if (i % 2 == 0) {
return i;
}
return 0;
}
}
4_000_000 is an integer literal you can use since Java 7 for the number 4000000. The purpose of the underscores is to make it better readable for humans. Programmatically there is no difference to using 4000000. For details see Primitive Data Types in The Java Tutorials.
Note: This first part of the question was related to a misunderstanding. I supposed that it was necessary to calculated up to fib(4000000).
You must use BigInteger otherwise you can't handle so big numbers. It is a number with many thousands of digits!
fib(4000000) results in a number with over 835k digits. It is not possible to handle it with int or long.
The class BigInteger (or the equivalent BigDecimal for decimal values) borns to handle such kind of problems.
Note: this is the answer to the question
Now that the question is more clear it is possible to give the correct answer.
public void printEvenFib() {
int i = 1;
int lastFib = 1;
int sum = 0;
while (lastFib <= 4000000) {
if (lastFib % 2 == 0) {
sum += lastFib;
}
i++;
lastFib = fib(i);
}
System.out.println(sum);
}
// Without recursion
public int fib(int n) {
if (n <= 2) {
return 1;
}
int fibo1 = 1;
int fibo2 = 1;
int fibo = 0;
for (int i = 3; i <= n; i++) {
fibo = fibo1 + fibo2;
fibo2 = fibo1;
fibo1 = fibo;
}
return fibo;
}
class Program2{
public static void main(String args[]){
int n1=0,n2=1,n3,total=0,i;
for(i=1;n3<4000000;++i){
n3=n1+n2;
if(n3%2==0)
total+=n3;
n1=n2;
n2=n3;
}
System.out.println("total is "+total);
}
}

Checking if numbers of an integer are increasing (java)

What I am trying to do should be pretty easy, but as I'm new to java, I'm struggling with what might be basic programming.
The main issue is how to check if the (x+1) number of an integer is greater than the x number, which I am trying to do as follow :
for( int x=0; x < Integer.toString(numblist).length();x++) {
if (numblist[x] < numblist[x+1]) {
compliance= "OK";
} else{
compliance="NOK";
}
But it returns an error "array required but integer found".
It seems to be a basic type mistake, which might come from the previous step (keeping only the numbers included in a string):
for (int p = 0; p < listWithoutDuplicates.size(); p++) {
Integer numblist = Integer.parseInt(listWithoutDuplicates.get(p).getVariantString().replaceAll("[\\D]", ""));
I can't find the answer online, and the fact that it shouldn't be complicated drives me crazy, I would be grateful if someone could help me!
Do the reverse. If they are increasing starting from the first digit, it means that they are decreasing from the last to the first. And it is much easier to program this way:
public boolean increasingDigits(int input)
{
// Deal with negative inputs...
if (input < 0)
input = -input;
int lastSeen = 10; // always greater than any digit
int current;
while (input > 0) {
current = input % 10;
if (lastSeen < current)
return false;
lastSeen = current;
input /= 10;
}
return true;
}
You can't index an integer (i.e. numblist) using the [] syntax -- that only works for arrays, hence your error. I think you're making this more complicated than it has to be; why not just start from the back of the integer and check if the digits are decreasing, which would avoid all this business with strings:
int n = numblist;
boolean increasing = true;
while (n > 0) {
int d1 = n % 10;
n /= 10;
int d2 = n % 10;
if (d2 > d1) {
increasing = false;
break;
}
}
One way I could think of was this:
boolean checkNumber(int n) {
String check = String.valueOf(n); // Converts n to string.
int length = check.length(); // Gets length of string.
for (int i = 0; i < length-1; i++) {
if(check.charAt(i) <= check.charAt(i+1)) { // Uses the charAt method for comparison.
continue; // if index i <= index i+1, forces the next iteration of the loop.
}
else return false; // if the index i > index i+1, it's not an increasing number. Hence, will return false.
}
return true; // If all digits are in an increasing fashion, it'll return true.
}
I'm assuming that you're checking the individual digits within the integer. If so, it would be best to convert the Integer to a string and then loop though the characters in the string.
public class Test {
public static void main(String[] args) {
Integer num = 234; // New Integer
String string = num.toString(); // Converts the Integer to a string
// Loops through the characters in the string
for(int x = 0; x < string.length() - 1; x++){
// Makes sure that both string.charAt(x) and string.charAt(x+1) are integers
if(string.charAt(x) <= '9' && string.charAt(x) >= '0' && string.charAt(x+1) <= '9' && string.charAt(x+1) >= '0'){
if(Integer.valueOf(string.charAt(x)) < Integer.valueOf(string.charAt(x+1))){
System.out.println("OK");
}else{
System.out.println("NOK");
}
}
}
}
}
I think a simple way could be this
package javacore;
import java.util.Scanner;
// checkNumber
public class Main_exercise4 {
public static void main (String[] args) {
// Local Declarations
int number;
boolean increasingNumber=false;
Scanner input = new Scanner(System.in);
number = input.nextInt();
increasingNumber = checkNumber(number);
System.out.println(increasingNumber);
}
public static boolean checkNumber(int number) {
boolean increasing = false;
while(number>0) {
int lastDigit = number % 10;
number /= 10;
int nextLastDigit = number % 10;
if(nextLastDigit<=lastDigit) {
increasing=true;
}
else {
increasing=false;
break;
}
}
return increasing;
}
}
private boolean isIncreasingOrder(int num) {
String value = Integer.toString(num);
return IntStream.range(0, value.length() - 1).noneMatch(i -> Integer.parseInt(value.substring(i, i + 1)) > Integer.parseInt(value.substring(i + 1, i + 2)));
}

Categories