Project Euler #34: Digit factorials - review code : Java - java

A digital factorial need to be found out. This no. is easily divisible by sum of factorials of all the digits of the no.
I am trying this on HackerRank : https://www.hackerrank.com/contests/projecteuler/challenges/euler034/
My code is passing only one test case i.e. if n < 20.Other test cases are not passing.
Code is below.
import java.io.*;
import java.util.*;
import java.text.*;
import java.math.*;
import java.util.regex.*;
public class Solution {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int len,newt=0,pos = 0,ans=0;
long fac,sum;
for(int i=10;i<=n;i++){
newt = i;
sum =0;
len = String.valueOf(newt).length();
while(len>0){
fac=1;
pos = newt % 10;
newt = newt/10;
for(int k=1;k<=pos;k++){
fac = fac*k;
}
sum+=fac;
len--;
}
// System.out.print(sum+" "+i);
// System.out.println();
if(sum%i==0){
ans = i;
}
}
System.out.print(ans);
}
}

Your code for iterating the digits of a number n seems overly complex. It's a simple as this:
if (n <= 0)
throw new IllegalArgumentException("Not a positive number: " + n);
for (; n > 0; n /= 10) {
int digit = n % 10;
// use digit here
}
Your code can also be improved by using methods to separate the logic into independent parts, e.g.
private static int sumCuriousNumbers(int n) {
int sum = 0;
for (int i = 10; i <= n; i++)
if (isCuriousNumber(i))
sum += i;
return sum;
}
private static boolean isCuriousNumber(int number) {
int sum = 0;
for (int i = number; i > 0; i /= 10)
sum += factorial(i % 10);
return (sum % number == 0);
}
private static int factorial(int n) {
int f = 1;
for (int i = 1; i <= n; i++)
f *= i;
return f;
}
This helps document the code and the 3 methods can now be unit-tested too.

Related

Perfect Numbers in an ArrayList

This is an exercise.
A perfect number is a number whose sum of divisors without itself is equal to that number
6 is a perfect number because its divisors are: 1,2,3,6 and 1 + 2 + 3 = 6
28 is a perfect number because its divisors are: 1,2,4,7,28 and 1 + 2 + 4 + 7 = 28
Task: write the body of findNPerfectNumbers, which will find n prime perfect numbers and return them as a list
I must use this program:
import java.util.ArrayList;
public class Exercise {
public static ArrayList<Integer> findNPerfectNumbers(int n)
{
return new ArrayList<>();
}
public static void main(String[] args)
{
System.out.println(findNPerfectNumbers(4));
}
}
I create this code to resolve this problem, but I have a problem to return an ArrayList. I don't know how. It should look like this example: 6 = 1,2,3,6 ///// 28 = 1, 2, 4, 7
My idea:
import java.util.ArrayList;
public class Main
{
public static ArrayList<Integer> findNPerfectNumbers(int n)
{
int sum = 0;
ArrayList<Integer> perfectList = new ArrayList<>();
ArrayList<Integer> factorList = new ArrayList<>();
for (int i = 6; i < n; i++)
{
factorList.clear();
for (int j = 1; j <= i / 2; j++)
{
if (i % j == 0)
{
factorList.add(j);
}
}
sum = 0;
for (int h = 0; h < factorList.size(); h++)
{
sum = sum + factorList.get(h);
}
if (sum == i)
{
perfectList.add(i);
}
}
return perfectList;
}
public static void main(String[] args)
{
System.out.println(findNPerfectNumbers(28));
}
}
Anyone have an idea?
The question is as simple as to have the findNPerfectNumbers function return the first N perfect numbers.
The main part for the exercise is probably to do this as efficiently as possible. For example limiting divider check by half like you do in for (int j = 1; j <= i / 2; j++) is one of many options.
The reason your function doesn't return anything though is because your outer for loop is incorrect with the given input of 4 what you'r doing is for (int i = 6; i < 4; i++) which doesn't do any loops because 4 is smaller than 6.
what you probably intended to do issomething like for (int i = 6; perfectList.size() < n; i++) which would loop aslong as you have fewer than N perfect numbers.
example working code:
import java.util.ArrayList;
public class Exercise {
public static ArrayList<Integer> findNPerfectNumbers(int n) {
int sum = 0;
ArrayList<Integer> perfectList = new ArrayList<>();
for (int i = 6; perfectList.size() < n; i++) {
ArrayList<Integer> factorList = new ArrayList<>();
for (int j = 1; j <= i / 2; j++) {
if (i % j == 0) {
factorList.add(j);
}
}
sum = 0;
for (Integer factor : factorList) {
sum += factor;
}
if (sum == i) {
System.out.println("Found perfect number " + i + " with factors " + factorList);
perfectList.add(i);
}
}
return perfectList;
}
public static void main(String[] args) {
System.out.println(findNPerfectNumbers(4));
}
}
If number is less than 10^1500 you can use Euclid's method
public static List<Long> findPerfect(int n){
List<Long> perfectList=new ArrayList<>();
int x=0;
long sum=0;
long last;
while(perfectList.size()!=n){
last= (long) Math.pow(2,x);
sum+=last;
if(isPrime(sum))
perfectList.add(sum*last);
x++;
}
return perfectList;
}
public static boolean isPrime(long x){
if(x==1)
return false;
for (int i = 2; i <= Math.sqrt(x); i++) {
if(x%i==0)
return false;
}
return true;
}

Maximum Integer Value java

I was trying to solve the Maximum Integer Value problem form Geeksforgeeks.
The problem states the following:
Given a string S of digits(0-9), your task is to find the maximum value that can be obtained from the string by putting either '*' or '+' operators in between the digits while traversing from left to right of the string and picking up a single digit at a time.
Input:
The first line of input contains T denoting the number of testcases. T testcases follow. Each testcase contains one line of input denoting the string.
Output:
For each testcase, print the maximum value obtained.
this is what I did:
class GFG
{
public static void sort(int[] numbers)
{
int n = numbers.length;
for (int i = 1; i < n; ++i)
{
int key = numbers[i];
int j = i - 1;
while (j >= 0 && numbers[j] > key)
{
numbers[j + 1] = numbers[j];
j = j -1 ;
}
numbers[j + 1] = key;
}
System.out.println(numbers.length - 1);
}
public static void main (String[] args)
{
Scanner sc = new Scanner(System.in);
int testCases = sc.nextInt();
int [] maxNum;
for(int i = 0; i< testCases; i++)
{
String numbers = sc.nextLine();
char[] cNumbers = numbers.toCharArray();
maxNum = new int [cNumbers.length];
for(int j = 0; j + 1 < cNumbers.length; j++)
{
int sum = 0;
int mult = 0;
sum = cNumbers[j] + cNumbers[j + 1];
mult = cNumbers[j] * cNumbers[j + 1];
int maxNumber = Math.max(sum, mult);
maxNum[i] = maxNumber;
}
sort(maxNum);
}
}
}
an example of Input:
2
01230
891
My Output:
-1
4
Correct Output:
9
73
What is wrong with my code?!
Just quick glance it would seem if your digit is less than two it should be added. 2 or larger should get multiplied. Not at a PC to test though.
The idea is to put the operators alternatively and choose the maximum results.
import java.util.Scanner;
public class Demo {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int testCases = Integer.parseInt(sc.nextLine());
for (int i = 0; i < testCases; i++) {
String numbers = sc.nextLine();
int max = 0;
for (int j = 0; j + 1 < numbers.length(); j++) {
int next = Integer.parseInt(numbers.substring(j, j+1));
if (max + next > max * next)
max = max + next;
else
max = max * next;
}
System.out.println(max);
}
sc.close();
}
}
After the execution of
int testCases = sc.nextInt();
the buffer contains a new line character. So when executing the line
String numbers = sc.nextLine();
it read '\n' into numbers, so you got -1 as the first output.
Also you need to convert character to Integer before using it any arithmetic operations.
sum = cNumbers[j] + cNumbers[j+1];
mult = cNumbers[j] * cNumbers[j+1];
So the above code will give you wrong results.
I tried the following sample and worked.
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String inputAsString = sc.nextLine();
int testCases = Integer.parseInt(inputAsString);
int maxNumber = 0;
for (int i = 0; i < testCases; i++) {
String numbers = sc.nextLine();
if(!numbers.matches("\\d+")){
System.out.println("Only numeric values are expected.");
continue;
}
char[] cNumbers = numbers.toCharArray();
int sum = 0;
int mult = 1;
for (int j = 0; j < cNumbers.length; j++) {
int nextNumber = Character.getNumericValue(cNumbers[j]);
sum = sum + nextNumber;
mult = mult * nextNumber;
maxNumber = mult > sum ? mult : sum;
sum = maxNumber;
mult = maxNumber;
}
System.out.println(maxNumber);
}
sc.close();
}
I read your description and what you do is wrong. please read question carefully specially the example in reference site.
as mentioned in comments by moilejter you use sc.nextInt() which doesn't read '\n' and make problem. the next sc.nextLine() will read only a empty string and your program throw exception.
Second problem is that you must calculate max continuously and you don't need an int array (you calculate max result of operation between two successive number and save them in an array which is not correspond to max integer value. you only find max between each two digit but not max of operation on all digit).
Third problem is that you use character as numbers which is made incorrect result. (you must convert them to integer)
So there is a code that works for your output:
public class GFG
{
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int testCases = Integer.valueOf(sc.nextLine());
for (int i = 0; i < testCases; i++)
{
String numbers = sc.nextLine();
char[] cNumbers = numbers.toCharArray();
long maxUntilNow = cNumbers[0] - '0';
for (int j = 1; j < cNumbers.length; j++)
{
int numberOfThisPlace = cNumbers[j] - '0';
maxUntilNow = Math.max(maxUntilNow + numberOfThisPlace,
maxUntilNow * numberOfThisPlace);
}
System.out.println(maxUntilNow);
}
}
}
I hope this is what you want.
As per the problem statement, we need to obtain maximum value from the string by putting either * or + operators in between the digits while traversing from left to right of the string and picking up a single digit at a time.
So, this can be solved in O(n) without using any sorting algorithm.
The simple logic behind the solution is whenever you find "0" or "1" in any of the operands use "+" and the rest of the places use "*".
Here is my solution which got successfully submitted:
import java.util.*;
import java.lang.*;
import java.io.*;
class GFG {
public static void main (String[] args) {
Scanner scan = new Scanner(System.in);
int T = Integer.parseInt(scan.nextLine());
while(T-- > 0) {
String str = scan.nextLine();
maxValue(str);
}
}
static void maxValue(String str) {
long maxNumber = 0;
for(int i = 0; i < str.length(); i++) {
int n = Character.getNumericValue(str.charAt(i));
if (maxNumber == 0 || maxNumber == 1 ||
n == 0 || n == 1) {
maxNumber += n;
} else {
maxNumber *= n;
}
}
System.out.println(maxNumber);
}
}

Write a method to work out the sum of the first n odd numbers

First of all let me say I am quite new to programming its been my second week since I started so if you see any bad practice or error in code please accept my apologies.
I want to print sum of first n odd numbers. But so far I can only do the sum of odd number up to the given number. kindly help.
public static void main(String[] args)
{
Scanner userInput = new Scanner(System.in);
System.out.print("Please enter the number : ");
int num1 = userInput.nextInt();
int sum = sumOfOdd(num1);
System.out.println("sum of first " +num1 + " odd numbers is " + sum);
userInput.close();
}
static int sumOfOdd(int num)
{
int sum = 0;
for (int i = 0; i <= num; i++)
{
if(i % 2 != 0)
{
sum += i;
}
}
return sum;
}
}
You don't have to use a loop at all
static int sumOfOdd(int num) {
return num*num;
}
For Any Arithmetic Progression, the sum of numbers is given by,
Sn=1/2×n[2a+(n-1)×d]
Where,
Sn= Sum of n numbers
n = n numbers
a = First term of an A.P
d= Common difference in an A.P
Using above formula we can derive this quick formula to calculate sum of first n odd numbers,
Sn(odd numbers)= n²
Try this it uses a for loop that increments by two to only account for odd numbers.
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.print("Enter the value of n: ");
int n = scanner.nextInt();
System.out.println("The sum of the first " + n + " odd numbers is: " + sumOfOddNumbers(n));
}
public static int sumOfOddNumbers(int n) {
int sum = 0;
for(int i = 1; i < n*2; i+=2) {
sum += i;
}
return sum;
}
}
Example usage:
Enter the value of n: 5
The sum of the first 5 odd numbers is: 25
Try this:
static int sumOfOdd(int num) {
int sum = 0;
for (int i = 0; i < num; i++){
sum += i*2+1;
}
return sum;
}
It sums up all odd numbers until the limit is reached.
With i*2+1 you get the next odd number. Then you add it to the sum.
Tested with System.out.println(sumOfOdd(4)); and got the expected result 16 (1+3+5+7)
Change the counter to the number of times you add an odd number to the sum value...
static int sumOfOdd(int num) {
int sum = 0;
int i = 0;
int count = 0;
do {
if(i % 2 != 0) {
sum += i;
count++;
}
i++;
} while (count < num);
return sum;
}
Or even cleaner:
static int sumOfOdd(int num) {
int sum=0;
for (int i=1;i<num*2;i+=2) {
sum=sum+i;
}
return sum;
}
You should count how many numbers have you added and in the condition to check if count of numbers you summed is less or equal than your n. Just add the counter in your for loop and set condition to: count <= num and it should work.
Every time you add a number to the sum increment the count by count++.
The code suppose to look like this:
static int sumOfOdd(int num)
{
int sum = 0;
int count = 0;
for (int i = 0, count= 0; count <= num; i++)
{
if(i % 2 != 0)
{
sum += i;
count++;
}
}
return sum;
}
I haven't checked it, but it should be correct
Since you don't know how many loop cycles are required you have to change the exit condition of the for loop.
Or you can use a while loop exploiting the same exit condition.
static int sumOfOdd(int num){
int sum = 0;
int counter = 0;
int currentNumber = 0;
while (counter<num){
if(currentNumber % 2 != 0){
sum += currentNumber;
counter++;
}
currentNumber++;
}
return sum;
}
Here is the complete code you'd be using:
public class YourClass {
public static void main(String[] args)
{
Scanner userInput = new Scanner(System.in);
System.out.print("Please enter the number : ");
int num1 = userInput.nextInt();
int sum = sumOfOdd(num1);
System.out.println("sum of first " +num1 + " odd numbers is " + sum);
userInput.close();
}
static int sumOfOdd(int num)
{
int counter = 0;
for (int i = 0;; i++)
{
int sum = 0;
if(i % 2 != 0)
{
counter++;
sum += i;
}
if(counter == num) return sum;
}
}
}
Another alternative.
static int sumOfOdd(int num) {
int sum = 0;
int last = 2*num-1;
for (int i = 1; i <= last; i+=2){
sum += i;
}
return sum;
}
Obviously return num*num; is the most efficient but if you're obliged to use a loop then this method avoids a * inside the loop.
This will be a tiny (tiny) bit more efficient than:
for (int i = 0; i < num; ++i){
sum += 2*i+1;
}
import java.util.*;
class karan{
public static void main(String args[]) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int i = n;
int sumOddNumber = n * i;
System.out.println(n*i);
}
}

Convert binary to decimal using arrays in java

I'd like to write a program that converts binary to decimal using arrays. This is the code I have written so far:
public void BinConvertorDec(){
int j;
Scanner in = new Scanner(System.in);
System.out.println("Enter Binery Index Size: ");
j = in.nextInt();
int []ConValue = new int[j]
System.out.println("Enter a Binary value to convert:");
for(int i=0; i<ConValue.length; i++){
ConValue [i] = in.nextInt();
}
}
int decimal = 0;
int power = 0;
for(int i = 0 ; i < ConValue.length ; i++){
int tmp = ConValue[i]%10;
decimal += tmp*Math.pow(2, power);
power++;
}
System.out.println(decimal);
Add that after your for loop. This assumes that the user inputs the string from right to left, changing this should be easy .It works but it would be much easier for your user if they could just input a simple binary string rather than every element of the binary.
this is Easy to understand.
import java.util.*;
class Power{
int pow(int base , int exponent)
{
int result = 1;
while( exponent != 0)
{
result *= base;
--exponent;
}
return result;
}
}
class Decimal{
Power obj = new Power();
int dec(int x []){
int decimal = 0; int exp = 0;
for( int i = x.length - 1; i > -1; i--){
decimal += x[i] * obj.pow(2, exp);
exp++;
}
return decimal;
}
}
class code{
public static void main(String [] args){
Decimal DecObj = new Decimal();
int bin[]= {0,0,1,1,1};
System.out.println(DecObj.dec(bin));
}
}
Here is the code convert a number binary to decimal in java.
import java.util.*;
public class HelloWorld {
static int btod(int n) {
int count = 0;
int mul = 1;
while(n != 0) {
int dig = n%10;
count+= dig * mul;
n /= 10;
mul *= 2;
}
return count;
}
public static void main(String []args){
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
System.out.println("Results: " + HelloWorld.btod(n));
}
}

Calculate factorial of 50 using array only in java

I'm a total beginner of java.
I have a homework to write a complete program that calculates the factorial of 50 using array.
I can't use any method like biginteger.
I can only use array because my professor wants us to understand the logic behind, I guess...
However, he didn't really teach us the detail of array, so I'm really confused here.
Basically, I'm trying to divide the big number and put it into array slot. So if the first array gets 235, I can divide it and extract the number and put it into one array slot. Then, put the remain next array slot. And repeat the process until I get the result (which is factorial of 50, and it's a huge number..)
I tried to understand what's the logic behind, but I really can't figure it out.. So far I have this on my mind.
import java.util.Scanner;
class Factorial
{
public static void main(String[] args)
{
int n;
Scanner kb = new Scanner(System.in);
System.out.println("Enter n");
n = kb.nextInt();
System.out.println(n +"! = " + fact(n));
}
public static int fact(int n)
{
int product = 1;
int[] a = new int[100];
a[0] = 1;
for (int j = 2; j < a.length; j++)
{
for(; n >= 1; n--)
{
product = product * n;
a[j-1] = n;
a[j] = a[j]/10;
a[j+1] = a[j]%10;
}
}
return product;
}
}
But it doesn't show me the factorial of 50.
it shows me 0 as the result, so apparently, it's not working.
I'm trying to use one method (fact()), but I'm not sure that's the right way to do.
My professor mentioned about using operator / and % to assign the number to the next slot of array repeatedly.
So I'm trying to use that for this homework.
Does anyone have an idea for this homework?
Please help me!
And sorry for the confusing instruction... I'm confused also, so please forgive me.
FYI: factorial of 50 is 30414093201713378043612608166064768844377641568960512000000000000
Try this.
static int[] fact(int n) {
int[] r = new int[100];
r[0] = 1;
for (int i = 1; i <= n; ++i) {
int carry = 0;
for (int j = 0; j < r.length; ++j) {
int x = r[j] * i + carry;
r[j] = x % 10;
carry = x / 10;
}
}
return r;
}
and
int[] result = fact(50);
int i = result.length - 1;
while (i > 0 && result[i] == 0)
--i;
while (i >= 0)
System.out.print(result[i--]);
System.out.println();
// -> 30414093201713378043612608166064768844377641568960512000000000000
Her's my result:
50 factorial - 30414093201713378043612608166064768844377641568960512000000000000
And here's the code. I hard coded an array of 100 digits. When printing, I skip the leading zeroes.
public class FactorialArray {
public static void main(String[] args) {
int n = 50;
System.out.print(n + " factorial - ");
int[] result = factorial(n);
boolean firstDigit = false;
for (int digit : result) {
if (digit > 0) {
firstDigit = true;
}
if (firstDigit) {
System.out.print(digit);
}
}
System.out.println();
}
private static int[] factorial(int n) {
int[] r = new int[100];
r[r.length - 1] = 1;
for (int i = 1; i <= n; i++) {
int carry = 0;
for (int j = r.length - 1; j >= 0; j--) {
int x = r[j] * i + carry;
r[j] = x % 10;
carry = x / 10;
}
}
return r;
}
}
How about:
public static BigInteger p(int numOfAllPerson) {
if (numOfAllPerson < 0) {
throw new IllegalArgumentException();
}
if (numOfAllPerson == 0) {
return BigInteger.ONE;
}
BigInteger retBigInt = BigInteger.ONE;
for (; numOfAllPerson > 0; numOfAllPerson--) {
retBigInt = retBigInt.multiply(BigInteger.valueOf(numOfAllPerson));
}
return retBigInt;
}
Please recall basic level of math how multiplication works?
2344
X 34
= (2344*4)*10^0 + (2344*3)*10^1 = ans
2344
X334
= (2344*4)*10^0 + (2344*3)*10^1 + (2344*3)*10^2= ans
So for m digits X n digits you need n list of string array.
Each time you multiply each digits with m. and store it.
After each step you will append 0,1,2,n-1 trailing zero(s) to that string.
Finally, sum all of n listed string. You know how to do that.
So up to this you know m*n
now it is very easy to compute 1*..........*49*50.
how about:
int[] arrayOfFifty = new int[50];
//populate the array with 1 to 50
for(int i = 1; i < 51; i++){
arrayOfFifty[i-1] = i;
}
//perform the factorial
long result = 1;
for(int i = 0; i < arrayOfFifty.length; i++){
result = arrayOfFifty[i] * result;
}
Did not test this. No idea how big the number is and if it would cause error due to the size of the number.
Updated. arrays use ".length" to measure the size.
I now updated result to long data type and it returns the following - which is obviously incorrect. This is a massive number and I'm not sure what your professor is trying to get at.
-3258495067890909184

Categories