Adding square of the digits in java - java

Recently i attended one interview there they asked me to write a program like below,
A number chain is created by continously adding the square of the digits in a number
to form a new number untill its has been seen before.
example :
44 -> 32 -> 13-> 10-> 1
85->89->145->42->20->4->16->37->58->89
therefore any chain arrives at 1 or 89 will become stuck in endless loop.
what is most amazing is that every starting number will eventually arrive at 1 or 89.
write a program to count the starting number below 10000 will arrive at 89?
I wrote programs like below,
int num =44;
int array[] = new int[100];
int power=0;
while(num > 0)
{
int mod = num % 10;
int div = num /10;
int sum =(mod * mod) + (div * div);
num =sum;
System.out.print(" => "+sum);
if(array.equals(sum))
// should not use any functions like Arrays.asList(array).contains(sum);
return;
else
{
//System.out.println("else");
array[power++] =sum;
}
}
I know that above program not satisfy their requirements.Some one tell me good code snip to make them code satisfaction(If same question ask in future).?
Note : should not use any function or import. Only logic is need.

Maintain a cache of already calculated numbers. This will reduce the number of unnecessary iterations which were already calculated.
Let's do some math
From you example
44 -> 32 -> 13-> 10-> 1
85->89->145->42->20->4->16->37->58->89
You already know that the numbers 85, 89, 145, 42, 20, 4, 16, 37, 58 lead to 89 and 44, 32,13, 10, 1 don't.
In some case say calculating it for 11.
11 - 2 - 4
Now we already know 4 leads to 89 and so we skip all the other unnecessary iteration from
4 - 16 - 37 - 58 - 89 and also we now know that 11, 2also lead to 89.
So no the algorithm would be:
while(num > 0)
{
if(calculate[i] == 1)//which mean leads to 89
{
// dont calculate again
}
else
{
// num = // your squares logic
}
}

I read this as a recursive problem. I made the assumption that you only want to know the number of steps until 1 or 89 is reached.
The helper method, getDigits() is just for simplicity. The conversion to the String isn't technically necessary, but it makes the code simple.
public static void main(String[] args) {
int v = 9843;
int[] count = {0};
System.out.println("Number of steps: " + countSteps(v,count)[0]);
}
private static int[] countSteps(int initialValue, int[] count){
if(initialValue == 1 || initialValue == 89){
return count;
}
count[0]++;
int[] digits = getDigits(initialValue);
initialValue = 0;
for (int k : digits) {
initialValue += k * k;
}
countSteps(initialValue,count);
return count;
}
private static int[] getDigits(int i){
String s = Integer.toString(i);
int[] digits = new int[s.length()];
for(int j=0;j<s.length();j++){
digits[j] = s.charAt(j) - '0';
}
return digits;
}

If you are generating a sequence it makes sense to use an Iterable.
public static class SquaredDigitsSequence implements Iterable<Integer> {
int start;
SquaredDigitsSequence(int start) {
this.start = start;
}
#Override
public Iterator<Integer> iterator() {
return new SquaredDigitsIterator(start);
}
static class SquaredDigitsIterator implements Iterator<Integer> {
int last;
Set<Integer> seen = new HashSet<>();
SquaredDigitsIterator(int start) {
last = start;
seen.add(last);
}
#Override
public boolean hasNext() {
return !seen.contains(step());
}
#Override
public Integer next() {
last = step();
seen.add(last);
return last;
}
int step() {
int next = 0;
for (int x = last; x != 0; x /= 10) {
next += (x % 10) * (x % 10);
}
return next;
}
}
}
public void test() {
for (int i = 0; i < 100; i++) {
System.out.print(i + " ");
for (int x : new SquaredDigitsSequence(i)) {
System.out.print(x + " ");
}
System.out.println();
}
}
This prints all sequences up to 100 and does indeed include the two examples you posted but sadly it does not always terminate at 1 or 89.

class SquareDigits{
public static void main(String[] args){
System.out.println("Amount of numbers ending on 89: " + loop(10000));
}
public static int loop(int limit){
int cnt = 0;
for(int i = 1; i < limit; i++){
if(arriveAt89(i))
cnt++;
}
return cnt;
}
public static boolean arriveAt89(int num){
while(num != 89 && num != 1){
num = addSquares(num);
}
if(num == 89)
return true;
return false;
}
public static int addSquares(int n){
int sum = 0;
for(Character c : ("" + n).toCharArray()){
sum += Character.getNumericValue(c)*Character.getNumericValue(c);
}
return sum;
}
}
Assuming you're just after the amount of numbers that ends with 89.

This prints all numbers that end up in 89 below 89.
//array = boolean array to hold cache
//arr= list to store numbers in the chain that goes up to 89 used in setting cache
public static void main(String args[]) {
Boolean[] array = new Boolean[100];
Arrays.fill(array, Boolean.FALSE);
for(int i=2;i<89;i++){
checkChain(i,array);
}
for(int k=0;k<89;k++){
if(array[k]){System.out.println(k);}
}
}
private static void checkChain(int num,Boolean[] array) {
List<Integer> arr= new ArrayList<Integer>();
int initial = num;
int next;
do{
next=0;
arr.add(num);
while(num>0){
if(array[num] || num==89){
for(Integer j:arr){
array[j]=true;
}
break;
}
next = next+(num%10)*(num%10);
num=num/10;
}
num=next;
if(next<initial && array[next]){
array[initial]=true;
break;
}
}while((next>initial));
}
}

Related

Random characters showing up in my output, not sure where they're coming from [duplicate]

This question already has answers here:
What's the simplest way to print a Java array?
(37 answers)
Closed 2 years ago.
I'm creating a program that uses two methods to print all the odd numbers in an array and then get the sum of the odd numbers. However, I'm getting an output that makes no sense. This is the code that I'm using:
public class ArrayMethods1 {
public static int[] printOdds(int[]arrayExample) {
int i;
String oddNum = "";
int [] newArray = new int [3];
int x = 0;
for (i = 0; i < arrayExample.length; i++) {
if (arrayExample[i] % 2 != 0) {
System.out.print(arrayExample[i] + " ");
}
}
int[] sumOfOdds = new int [1];
sumOfOdds = sumOdds(newArray);
return sumOfOdds;
}
public static int[] sumOdds(int[]arrayExample1) {
int i;
int[] oddsTotal = new int[1];
int total = 0;
for (i = 0; i < arrayExample1.length; i++) {
if (arrayExample1[i] % 2 != 0) {
total = total + arrayExample1[i];
}
}
oddsTotal[0] = total;
return oddsTotal;
}
public static void main(String[] args) {
int [] mainArray = new int [5];
mainArray[0] = 17;
mainArray[1] = 92;
mainArray[2] = 21;
mainArray[3] = 984;
mainArray[4] = 75;
printOdds(mainArray);
int [] oddSum = new int[1];
oddSum = sumOdds(mainArray);
System.out.println(oddSum);
}
}
And I'm getting this as output:
17 21 75 [I#51016012
I have absolutely no idea where that second part is coming from, so any help would be awesome. Thanks!
well you are storing the result of the sum in an array and then you print the reference of type int[], that's why you get [I#51016012. so you need to print oddSum[0].
It is not quite clear why you return int[] from the methods that just print and calculate the sum of the odd numbers.
So the code could be enhanced:
public static void printOdds(int[] arr) {
for (int n : arr) {
if (n % 2 == 1) {
System.out.print(n + " ");
}
}
System.out.println();
}
public static int sumOdds(int[] arr) {
int total = 0;
for (int n : arr) {
if (n % 2 == 1) {
total += n;
}
}
return total;
}
Also, it may be worth to use Java 8+ stream to implement both tasks in one run:
import java.util.Arrays;
public class PrintAndSumOdds {
public static void main(String [] args){
int[] arr = {17, 92, 21, 984, 75};
int sumOdds = Arrays.stream(arr) // get IntStream from the array
.filter(n -> n % 2 == 1) // filter out the odds
.peek(n -> System.out.print(n + " ")) // print them in one line
.sum(); // and count the sum (terminal operation)
System.out.println("\nTotal odds: " + sumOdds);
}
}
Output:
17 21 75
Total odds: 113

3 quick for-loop integer homework problems

Have some loops homework to do, and need some help! Here are the 3 questions:
Us the method below to take two integers and only output numbers divisible by ten. Make the list start with the largest of the numbers.
public static void divisibleByTen( int start, int end )
The above method is the example on the HW sheet. I have no idea how to implement it. I also don't know how to start with the largest number. Right now, I don't know how to take user input into the loop, so I made an example with 10 and 100:
public class QuestionOne {
public static void main(String [] args) {
for (int i = 10; i <= 100; i += 10){
System.out.println(i + "");
}
}
}
Use the method below to output the triangle below. Assume the positive number is between 3 and 9.
public static void printLeftUpper( int num)
Desired output is this number triangle:
1 2 3 4 5
1 2 3 4
1 2 3
1 2
1
Here's my code so far:
public class QuestionTwo {
public static void main(String [] args) {
for(int i = 5; i >= 1; i--) {
for(int j = 1; j <= i; ++j) {
System.out.print(j + " ");
}
System.out.println();
}
}
}
The third question I have ZERO idea how to start.
3. public static void sumEvens( int begin, int end )
Use the method above to take in two numbers, called begin and end, inclusive, checks if the numbers between them are even. Include the numbers in the sum if they are even as well, and print out the sum of all such numbers.
Example: sumEven(16, 11) uses 16+14+12 = 42, and outputs "For numbers between 16 and 11, the sum of all even numbers is 42."
The help is GREATLY appreciated. Thanks so much!!
Who likes homework? I've taken the liberty of doing Question 3, hope that helps!
import java.util.List;
import java.util.ArrayList;
public class OddEven {
public static void main(String[] args) {
sumEvens(0,1000);
}
// Gets sum of odd and even numbers between a given range:
public static void sumEvens(int begin, int end)
{
List<Integer> evenNumbers = new ArrayList<Integer>();
List<Integer> oddNumbers = new ArrayList<Integer>();
if (begin < end)
{
for (int i = begin; i <= end; i++)
{
// Number is even:
if (i % 2 == 0)
{
evenNumbers.add(i);
}
// Number is odd:
else
{
oddNumbers.add(i);
}
}
}
else
{
for (int i = begin; i >= end; i--)
{
// Number is even:
if (i % 2 == 0)
{
evenNumbers.add(i);
}
// Number is odd:
else
{
oddNumbers.add(i);
}
}
}
// Calculate even values:
int evenSum = 0;
for (int i: evenNumbers) {
evenSum += i;
}
System.out.println("The sum of all even numbers is: " + evenSum);
// Calculate odd values:
int oddSum = 0;
for (int i: oddNumbers) {
oddSum += i;
}
System.out.println("The sum of all odd numbers is: " + oddSum);
}
}
public class QuestionOne {
public static void main(String [] args) {
divisibleByTen( 1, 100 );
}
public static void divisibleByTen( int start, int end ){
// reversal big to small (100 to 1)
for(int i = end; i >= start; i--){
// use mod (%) to check if i is divisible by 10
if( i%10 == 0 ){
// it is then output
System.out.println(i);
}
}
}
}
Question 2 is correct.
Question 3
public static void main(String [] args) {
sumEvens( 16, 10);
}
public static void sumEvens( int begin, int end ){
int start = 0;
int last = end;
int sum = 0;
if(begin > end){
start = end;
end = begin;
}else{
start = begin;
}
for(int i = start; i <= end; i++){
// get even integers
if(i%2 == 0){
sum += i;
}
}
System.out.println("For numbers between " +begin+ " and " +last+ ", the sum of all even numbers is " +sum);
}

calculating consecutive 1's in a Binary number

import java.util.Scanner;
import java.util.Arrays;
class Solve
{
public static void main(String args[])
{
Scanner in = new Scanner(System.in);
int i=0,count=0;
int[] arr = new int[10];
int n =in.nextInt();
while(n!=0)
{
arr[i]=n%2;
i++;
n=n/2;
}
System.out.println(Arrays.toString(arr));
}
}
}
I just want to calculate number of consecutive 1's. ? like 1110011001 will give me answer 5.. How can i do that??
System.out.println(Integer.toBinaryString(n).replaceAll("(0|(?<!1)1(?!1))", "").length());
The regex means: replace all 0's and any 1 not preceded or followed by another 1
You can handle this as a String [Edited to sum all consecutive 1's]:
String binary = in.nextLine();
String[] arrayBin = binary.split("0+"); // an array of strings without 0's
int result=0;
for (int i=0; i < arrayBin.length; i++){
if (arrayBin[i].length()<2){
result+=0;
}
else {
result+=arrayBin[i].length();
}
}
System.out.println("Total consecutive = "+result);
We can identify two consecutive binary ones in the least significant positions like this:
(value & 0b11) == 0b11
We can move the bits in value to the right like so:
value >>>= 1;
It's important to use tripple >>> over double >> because we don't care about the sign bit.
Then all we have to do is keep track of the number of consecutive 1s:
int count(int value) {
int count = 1;
int total = 0;
while (value != 0) {
if ((value & 0b11) == 0b11) {
count++;
} else {
if (count > 1) {
total += count;
}
count = 1;
}
value >>>= 1;
}
return total;
}
Test cases:
assertEquals(0, count(0b0));
assertEquals(0, count(0b1));
assertEquals(0, count(0b10));
assertEquals(2, count(0b11));
assertEquals(5, count(0b1110011));
assertEquals(5, count(0b1100111));
assertEquals(6, count(0b1110111));
assertEquals(7, count(0b1111111));
assertEquals(32, count(-1));
If you only want the length of the maximum, I have a similar answer: https://stackoverflow.com/a/42609478/360211
You can make use of Brian Kernighan’s Algorithm for counting the highest consecutive number of 1's.
A java pseudocode would be something like this
// Initialize result
int count = 0;
// Count the number of iterations to
// reach n = 0.
while (n!=0)
{
// This operation reduces length
// of every sequence of 1s by one.
n = (n & (n << 1));
count++;
}
public class Solution {
public int findMaxConsecutiveOnes(int[] nums) {
if(nums == null || nums.length == 0){
return 0;
}
int counter = 0, max = Integer.MIN_VALUE;
for(int i = 0; i < nums.length; i++){
if(nums[i] == 1){
counter += nums[i];
} else{
counter = nums[i];
}
max = Math.max(counter, max);
}
return max;
}
}
To this problem one trick which we can use here with help of some Java operators.
& operator and left shift (<<) in java.
Code snippet will be like :
public getConsecutiveCount(int inputNumber)
{
int count = 0 ;
while(inputNumber != 0)
{
inputNumber = inputNumber & (inputNumber << 1);
count++;
}
}
Explanation :
This function is taking input (ex : we want to check how many
consecutive 1's integer 6 have in its binary representation)
so out input number will be like :
inputNumber = ((110) & ((110)<<1)) {This left shift will result in 100 so final op :
110 & 100 which 100 , every time '0' is added to
our result and we iterate until whole number will
be zero and value of our count variable will be
our expected outcome }
To find Maximum consecutive 1's in binary(like 101)
int n = Convert.ToInt32(Console.ReadLine());
string[] base2=Convert.ToString(n,2).Split('0');
int count=0;
foreach(string s in base2)
count=s.Length>count?s.Length:count;
Console.WriteLine(count);
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int n = in.nextInt();
String bs = Integer.toBinaryString(n);// bs=Binary String
char[] characters = bs.toCharArray();
int max = 1;
int temp = 1;
for (int i = 0; i < characters.length - 1; i++) {
if (characters[i] == characters[i + 1] & characters[i] == '1' & characters[i + 1] == '1') {
temp++;
if (temp > max) {
max = temp;
}
} else {
temp = 1;
}
}
System.out.println(max);
}
/* Given a decimal number print maximum number of consecutive 1's after binary conversion */
import java.io.*;
import java.util.*;
public class Solution {
public void countBinaryOne(int num){
int var =0, countOne= 0, maxCt=0;
while(num>0){
var= num%2;
if(var==1){
countOne=countOne+1;
}else{
if(maxCt<countOne){
maxCt= countOne;
countOne=0;
}else{
countOne=0;
}
}
num=num/2;
}
System.out.println(Math.max(countOne,maxCt));
}
public static void main(String[] args) {
Scanner in= new Scanner(System.in);
int n= in.nextInt();
Solution sol= new Solution();
sol.countBinaryOne(n);
}
}
public static void digitBinaryCountIfOne(int n){
int reminder=0, sum=0, total = 0;
while(n>0)
{
reminder = n%2;
n/=2;
if(reminder==1){
sum++;
if(sum>=total)
total=sum;
}else{
sum=0;
}
}
System.out.println(total);
}

Project Euler 14 - Java StackOverflowError

For those unfamiliar with the problem, here it is.
I am getting a StackOverflowError with the following code:
public class LongestCollatzSequence {
static int count = 1;
public static void main(String[] args) {
final int range = 1000000;
int maxSeq = 0;
List<Integer> chainList = new ArrayList<Integer>();
for(int i = 1; i <= range; i++) {
generateSequence(i);
if(chainList.isEmpty()) {
chainList.add(count);
count = 1;
} else if(!chainList.contains(count) && count > Collections.max(chainList)) {
chainList.clear();
chainList.add(count);
maxSeq = i;
count = 1;
}
}
System.out.println("Sequence starting number: "+maxSeq);
}
private static void generateSequence(int num) {
if(num == 1) {
return;
}
if(num % 2 == 0) {
count++;
generateSequence(num/2);
} else {
count++;
generateSequence(num*3+1);
}
}
}
High level flow:
-For numbers 2 - 100000, generate a collatz sequence for that number.
-Chain list is a list to store the length of the sequence generated for each number i.e. sequence size for number 13 is 10 (see example).
-If the current sequence size is bigger than the max in the chain list, clear chain list and add the new max, also store the value of i in maxReq to remember the starting number that produces the longest chain.
Interesting problem but the int in java is limited to 2^31-1 you could crox this limit use long or BigInteger
private static void generateSequence(long num) {
if (num == 1) {
return;
}
if (num % 2 == 0) {
count++;
generateSequence(num / 2);
} else {
count++;
generateSequence(num * 3 + 1);
}
}

Cycle through an int array and the use of modulo within it

I need to implement a method that returns the alternating sum of all elements with odd indexes minus the sum of all elements with even indexes. The total sum returned should be -1. 1 - 4 + 9 - 16 + 9 = -1.
Here is my code:
public class Arrays
{
public static void main(String[] args){
int [] data = {1 ,4, 9, 16, 9};
oddAndEven(data);
}
public static int[] oddAndEven(int[] data){
int sum = 0;
int sumA = 0;
int index = data.length;
for(int i:data){
if(index % sumA == 1){
sum = sum-i;
}
else{
sum = sum+i;
}
}
System.out.println(sum);
return sum;
}
}
Can someone tell me where I am going wrong please?
This is a class session, so forgive my basic code and errors.
This is how I would do it:
public class test {
public static void main(String[] args) {
int [] data = {1 ,4, 9, 16, 9};
oddAndEven(data);
}
public static void oddAndEven(int[] data) {
int total = 0;
for (int i = 0; i < data.length; i++)
{
if (i%2==0)
total = total + data[i];
else
total = total - data[i];
}
System.out.println(total);
}
I've gotten rid of the return in the method and changed it to void (as you are printing out the result within it, so there is no need to return it.
You don't need the two different sum values, or the length of the array stored.
The total value is used and set to 0. The for loop then goes through the length of the array. The %2 divides the number by 2 and determines the remainder. So for the first loop, it will calculate 0/2 and work out the remainder (obviously 0). As it ==0, the first if statement in the for loop is executed (adding the numbers).
The second time through, it calculates 1/2, which is 0 with 1 remaining - so the else statement is executed and so on.
Additionally, note how I've gotten rid of the braces around the if and else statements. As long as these statements are a single line, the braces aren't needed - taking the out tends to make the program easier to read (in my opinion). Obviously, if more than one line were needed under them, the braces need to be readded.
What about this ?
public class ArrayMeNow {
public static void main(String[] args) {
int [] data = {1 ,4, 9, 16, 9};
int result = oddAndEven(data);
System.out.println(result);
}
private static int oddAndEven(int[] data) {
int multiplier = 1;
int result = 0;
for(int v:data){
result += v * multiplier;
multiplier *= -1;
}
return result;
}
}
public static int oddAndEven(int[] data) {
int sum = 0;
for (int i=0;i<data.length;i++) {
if (i % 2 == 1) {
sum = sum - data[i];
} else {
sum = sum + data[i];
}
}
System.out.println(sum);
return sum;
}
for(int i:data) doesn't change the value of index. And sumA is supposed to be 2.
Change your for-loop to something like:
for (int i = 0; i < data.length; i++)
if (i % 2 == 1)
sum -= data[i];
else
sum += data[i];
You have to return sum which is of type int NOT int[]. Here is another way to do it.
public static int doAlternateAddSubOn(int[] array) {
int sum = 0;
for(int i=0; i<array.length; i++) {
// When index 'i' is Even, the position is Odd
sum = (i%2==0) ? sum+array[i] : sum-array[i];
}
return sum;
}

Categories

Resources