calculate Check Number in Java - java

Not sure if anyone can explain this to me or help me.
I have a 15 Digit Number of which I want to multiply each even number by 2 unless the even number is greater than 9. If it is this needs to be subtracted by 9 to give me an integer that again I can multiply by 2. Once I have all the even numbers multiplied by 2 i need to add them all together with the odd numbers.
Does that make sense.
UPDATE ***
so i have a number say 49209999856459. for that number I am looking to get the even integer so for example the first even one would be 4 then the second would be 2 and so on.
If one of those even numbers are multiplied by 2 then it might be above 9 so I want to subtract 9 to then use the remainder as the even number in its place.
SO !!!
Multiply by 2 the value of each even digit starting from index 0 and then each even index. In each case, if the resulting value is greater than 9, subtract 9 from it (which reduces larger values to a single digit). Leave the values of the digits at the odd indexes unchanged.
public String calculateCheckNumber()
String firstFifteen = longNumber.substring(0,15) ;
int i, checkSum = 0, totalSum = 0;
for (i = 0; i<firstFifteen.length(); i += 2) {
while (i < 9)
i *= 2;
if (i > 9)
i -= 9 ;
}
Was one option I was trying but it honestly I cant seem to get my head around it.
Any Help would be greatly appreciated.

Well, here is one approach. This uses the ternary (?:) operator to condense the operations. Edited base on clarification from the OP. The example you gave is actually a 14 digit string. But the following will work with any number of digits if they start out in a string. If you have a long value, then you can create the character array using:
long v = 49209999856459L;
char[] d = Long.toString(v).toCharArray();
Here is the main algorithm.
String s = "49209999856459";
int sum = 0;
char[] d = s.toCharArray();
for (int i = 0; i < d.length; i++) {
int v = d[i] - '0';
// The even digit will only be greater than 9 after
// doubling if it is >= 5 before.
sum += ((i % 2) == 1) ? v : (v >= 5) ? v+v-9 : v+v;
}
System.out.println(sum);
Prints
86

Related

Counting occurrences of an array element - Index out of bounds error but the index number and out of bounds length are the same number?

So I'm having some issues with code I'm writing for an assignment and it's kinda driving me crazy. It's my first semester and I've never done coding before, so I know I still have heaps to learn. Anyways, the issues:
I'm having two problems which could be related but I'm not 100% sure. I'm getting this error:
'Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: Index 125 out of bounds for length 125.'
Which points to the following section of code (Commented on specific line):
public static String gradesDistn() {
String gradeDistn = "0";
//Sort the above letterGrade array
Arrays.sort(letterGrade);
//This loop counts each occurrence of an element in the letterGrade array.
for (int i = 0; i < letterGrade.length - 1; i++) {
int count = 0;
for(int j = i + 1; j < letterGrade.length; j++) {
if (letterGrade[i] == letterGrade[j])
count++;
System.out.println (gradeDistn = letterGrade[i] + ": " + count); //THIS IS THE ERROR LINE.
i += (count-1);
}
}
return gradeDistn;
I can post the full code if additional context is needed. Essentially I'm am trying to count the occurrences of each letter grade (A, B, C, D, E and F) which are stored in an array. Each occurrence is based off of another array which stores number marks and is randomly generated. So the results should look something like this:
A: 6
B: 10
C:20
D: 9
E: 3
F: 1
instead I'm getting (copied from console):
A: 1
A: 2
A: 3
A: 4
B: 5
B: 6
B: 7
B: 8
B: 9
B: 10
B: 11
C: 11
C: 11
D: 11
D: 11
F: 11
C: 20
D: 9
E: 3
F: 1
I've spent so long looking at these code and trying to make it work, I feel like I'm am blind to the potentially obvious issues with it. Any help on this 2 issues would be really appreciated!
Also of note: The assignment requires a bunch of super specific methods such as this so that can't be changed, addition classes can not be used etc.
For this answer, I'm going to put aside the question of ArrayIndexOutOfBoundsException and offer guidance on how to generate a frequency distribution.
You are going to want a set of counters. Each counter will represent a range of values. To start, you should decide what range each counter will represent. Too fine a resolution, and your frequency distribution will not be very useful. For example, if your data is 100 meter sprint times for high school boys, and each counter represents an interval of 1/10,000 of a second, unless your sample size is very large, your frequency distribution would have a lot of values of '1' and '0'. You might want to separate by 1/10 of a second, 1 second, or 2 seconds, depending on how much variation there is in the boys' times.
But, if your data is species of farm animals, it would be fine to have a separate counter for each possible value.
So, determine how many counters you will need. What is the range of possible values? How closely do you want to group them?
Next, you will want a means of linking a particular value to a particular counter. In some cases, a little math can be used. In other cases, an if ... else if ... chain or a switch block is useful.
For the first example, I want to analyze daily high temperatures. I decide to group by 10 degrees Fahrenheit. I could decide on 5 degrees, 7 degrees, or some other interval. It could even be irregular intervals. But, keeping it regular and going by 10 degrees makes the example easier to follow.
Having settled on grouping by 10 degrees, I next want to decide the maximum and minimum. I'll pick -19 as the coldest, and 119 as the hottest. But, I want to allow for occurrences outside of that range. So, to hold the count, I will want an array of 15 counters.
Next, I will want a means of "translating" a temperature measurement to an array index. I use the int variable k for that in the following code. To make it easier to follow, I broke the calculation into 4 lines and then used the result as a subscript:
public static int [] tempFreqDist (WeatherStats [] daily) {
int [] count = new int [15]; // java initializes to zeros
int k;
for (int dIdx = 0; dIdx < daily.length; ++ dIdx) {
k = daily [dIdx].getHighTemp();
k = Math.max (k,-20);
k = Math.min (k,120);
k = k/10 + 2;
count [k]++;
}
return count;
}
That's it! One loop, and no sorting.
We want to group temps of -20 and colder together, regardless of how far below -20. So, we use Math.max. Similarly, we group temps of 120 and hotter by using Math.min. Next, divide by our grouping factor, and adjust the result so the lowest has 0 for the subscript value.
So, the result is the elements of count correspond to the temperature ranges: 0 ➔ -20 and colder; 1 ➔ "teens" (10 to 19) below zero; 2 ➔ single digits below zero; 3 ➔ zero and single digits above; 4 ➔ teens above zero; 5 ➔ twenties, ..., 14 ➔ teens above 100; 14 ➔ 120 and above.
But, suppose the 'width' of categories was irregular? One possibility is that you could use a chain of if ... else:
int t = daily [dIdx].getHighTemp();
if (t <= -20) k = 0;
else if (t <= -13) k = 1;
else if (t <= 0) k = 2;
else if (t <= 15) k = 3;
else if (t <= 28) k = 4;
and so on.
Another example counts animals you might see on a farm.
You can do that with an if ... else if ... chain:
public int[] animalFD (String [] species) {
int [] count = new int [6];
// 0 ➔ cattle, 1 ➔ pig, 2 ➔ sheep,
// 3 ➔ goat, 4 ➔ duck, 5 ➔ horse
...
for (int m = 0; m < species.length; ++m) {
if (species[m].equals("cow") count[0]++;
else if (species[m].equals("pig") count [1]++;
else if ...
But, for something like this, I prefer switch to if ... else chain:
public static int [] animalFD (String [] species) {
int [] count = new int [6];
for (int m = 0; m < species.length; ++m) {
switch (letterGrade [m]) {
case "cow":
count[0]++;
break;
case "pig":
count [1]++;
break;
case "sheep":
count [2]++;
break;
case "goat":
count [3]++;
break;
...
Here is a "trick" you can use to easily convert a letter to an index. Recall that a char is essentially a integer primitive: You can do numeric calculations on it.
char letter;
int idx;
...
if (letter >= 'A' && letter <= 'Z') {
idx = letter - 'A'; // result is zero to 25
...
This takes advantage of the fact that the letters A to Z are consecutive in character set encoding. However, that isn't universal. EBCDIC, for example, has non-letter characters between I and J, and between R and S, IIRC.

Improve performance of string to binary number conversion

This is one of the questions that I faced in competitive programming.
Ques) You have an input String which is in binary format 11100 and you need to count number of steps in which number will be zero. If number is odd -> subtract it by 1, if even -> divide it by 2.
For example
28 -> 28/2
14 -> 14/2
7 -> 7-1
6 -> 6/2
3 -> 3-1
2 -> 2/2
1-> 1-1
0 -> STOP
Number of steps =7
I came up with the following solutions
public int solution(String S) {
// write your code in Java SE 8
String parsableString = cleanString(S);
int integer = Integer.parseInt(S, 2);
return stepCounter(integer);
}
private static String cleanString(String S){
int i = 0;
while (i < S.length() && S.charAt(i) == '0')
i++;
StringBuffer sb = new StringBuffer(S);
sb.replace(0,i,"");
return sb.toString();
}
private static int stepCounter(int integer) {
int counter = 0;
while (integer > 0) {
if (integer == 0)
break;
else {
counter++;
if (integer % 2 == 0)
integer = integer / 2;
else
integer--;
}
}
return counter;
}
The solution to this question looks quite simple and straightforward, however the performance evaluation of this code got me a big ZERO. My initial impressions were that converting the string to int was a bottleneck but failed to find a better solution for this. Can anybody please point out to me the bottlenecks of this code and where it can be significantly improved ?
If a binary number is odd, the last (least significant) digit must be 1, so subtracting 1 is just changing the last digit from 1 to 0 (which, importantly, makes the number even).
If a binary number is even, the last digit must be 0, and dividing by zero can be accomplished by simply removing that last 0 entirely. (Just like in base ten, the number 10 can be divided by ten by taking away the last 0, leaving 1.)
So the number of steps is two steps for every 1 digit, and one step for every 0 digit -- minus 1, because when you get to the last 0, you don't divide by 2 any more, you just stop.
Here's a simple JavaScript (instead of Java) solution:
let n = '11100';
n.length + n.replace(/0/g, '').length - 1;
With just a little more work, this can deal with leading zeros '0011100' properly too, if that were needed.
Number of times you need to subtract is the number of one bits which is Integer.bitCount(). Number of times you need to divide is the position of most-significant bit which is Integer.SIZE (32, total number of bits in integer) minus Integer.numberOfLeadingZeros() minus one (you don't need to divide 1). For zero input I assume, the result should be zero. So we have
int numberOfOperations = integer == 0 ? 0 : Integer.bitCount(integer) +
Integer.SIZE - Integer.numberOfLeadingZeros(integer) - 1;
As per the given condition, we are dividing the number by 2 if it is even which is equivalent to remove the LSB, again if number is odd we are subtracting 1 and making it an even which is equivalent to unset the set bit (changing 1 to 0). Analyzing the above process we can say that the total number of steps required will be the sum of (number of bits i.e. (log2(n) +1)) and number of set bits - 1(last 0 need not to be removed).
C++ code:
result = __builtin_popcount(n) + log2(n) + 1 - 1;
result = __builtin_popcount(n) + log2(n);

I'm just having hard time understanding the class material from my java class

Can someone explain this code line by line. I just started to learn how to code and I'm learning java right now,but I'm having hard time how this function executes. What does new int[10]; really do? and I don't really get the difference or how repeatedDigits[index] part is used differently from the repeatedDigits[remainder] part.
Write a function that counts the repeated digits in the integer x.
For * example: if x is 999, then your function must print back that 9 occurs 3 * times. Another example, if the integer x is 992121, then your function * must print back that 9 occurs 2 times, 2 occurs 2 times and 1 occurs 2 * times. This was a guideline for the function.
public static void countRepeatedDigitsInANumber(int x) {
int[] repeatedDigits = new int[10];
while (x > 0) {
int remainder = x % 10;
x = x / 10;
repeatedDigits[remainder] = repeatedDigits[remainder] + 1;
}
int index = 0;
while (index < 10) {
if (repeatedDigits[index] != 0)
System.out.println("The digit " + index + " occurs " +
repeatedDigits[index]);
index++;
}
}
This is a code that compiles. I'm just posting this because I'm having hard time to understand. I would realy appreciate if someone could give any suggestion to learn java quickly as well!
What does new int[10];
It creates a new array of size 10 that can hold int values. All of the values in the array will be initialized to 0 (this is just how Java handles int primitives).
In this case, it looks like this array is being used to store the number of times that the digit corresponding to its index has been seen.
Hmm, that was confusing to type, and probably even more confusing to read, so let me use an example. For the input 992121, you'd expect the repeatedDigits array to look like this when the program is done:
[0, 2, 1, 0, 0, 0, 0, 0, 0, 2]
i.e. Two 1s, one 2, and two 9s
while (x > 0) {
This starts a loop that will keep going until x is equal to (or smaller than, but that shouldn't happen) zero.
int remainder = x % 10;
This essentially "captures" the right-most digit of the number using modular arithmetic. It divides the number by 10, and any remainder is going to be what's in the "ones place" (i.e. the right-most digit).
x = x / 10;
This shifts digits to the right by one, and throws away the right-most digit (since you've already captured it).
repeatedDigits[remainder] = repeatedDigits[remainder] + 1
This just increments the value in the array at the appropriate location. For example, if you just pushed a 9 off the right end of the number, this will increment the value in repeatedDigits[9] so you know that you just saw an additional 9.
int index = 0;
while (index < 10) {
We're about to do some looping! There are (in my opinion) better ways to do this, but this works just as well. Basically, you want index to start at 0, and loop all the way up to 9, but stop when you get to 10.
if (repeatedDigits[index] != 0)
If the value at a given location in the repeatedDigits array is not zero, then...
System.out.println("The digit " + index + " occurs " + repeatedDigits[index]);
... print it out!
index++;
And finally, increment index so we can check the next number. This is exactly the same as index = index + 1.
Welcome to SO and the beautiful world of Java! I've attached hyperlinks all throughout my answer that could possibly help you out.
int[] repeatedDigits = new int[10];
The above line of code is creating an array with 10 elements, from index: 0 to index: 9.
int remainder = x % 10;
The above line of code is calculating the remainder once 'x' has been divided by 10. For example, if 'x = 9192' then it would be dividing '9192 / 10 = 919.2' And taking the remainder. Which in this case is the '2'. Notice how it's actually looking at the number in reverse? So a number like '9192' is actually being processed as '2919'.
x = x / 10;
The above line of code is dividing the number down by 10- since it's integer division it drops all decimal values. Since we have already calculated the last number. So our '9192' is now just '919'.
repeatedDigits[remainder] = repeatedDigits[remainder] + 1;
The above line of code is going to the index of the array of the remainder value that we stored earlier. Remember how our remainder was '2'? It's not going to index: 2 in our array and adding 1 to it's value- which was originally 0. So now our array at index: 2 has the value: 1. Meaning the number 2 was repeated 1 time.
What I've laid out above is just 1 iteration of the while loop that the top half of your code is in. So get a piece of paper and redo everything I did above with the remaining number '919'.
Once you're finished you should notice that your array looks something like this:
index 0: 0
index 1: 1
index 2: 1
index 3: 0
index 4 to 8: 0
index 9: 2
This means that '1' came once. '2' came once. and '9' came twice.
As for advice on learning Java? Read a lot. Google every little question you have, and if you don't understand how something is working get a piece of paper and write it out.
int[] repeatedDigits = new int[10];
//create an array of integers of size 10
while (x > 0) {
//while the integer provided is greater than 0
int remainder = x % 10;
//gets the smallest value digit in a base ten system. 101%10 =1
x = x / 10;
//in base ten this reduces the size of the number by a tens place. 101/10 =10 as 10 can be fully divided into 101 10 times. You've dropped the last digit of the number in this way. This is what will allow you to exit the while loop, as eventually x will be equal to 0.
repeatedDigits[remainder] = repeatedDigits[remainder] + 1;
remainder here can be between 0-9. This is because remainder is the remainder of dividing the provided integer by 10. You can't divide a number greater than 0 by ten and have a value less than zero or greater than 9.
The array you created has indexes 0-9, as it is ten spaces long (0,1,2,3,4,5,6,7,8,9). You are assigning the value of the index of repeated Digits that corresponds to your remainder to whatever it was previously plus 1.
What this means is you have found that the last digit in the number is equal to some value X. X must be between 0-9. As you have an array with indexes between 0-9 you get the value associated with repeatedDigits[X], add one to it as you have found another value of X, and set repeatedDigits[X]'s value equal to what is was before you found this new X plus one.
}
int index = 0;
You start at the first value of an array (0)
while (index < 10) {
Go through the values of the array from 0 to 9
if (repeatedDigits[index] != 0)
if the value of the array repeatedDigits at index is not 0. This is the same as saying if there was a value of index found in the input number.
System.out.println("The digit " + index + " occurs " +
repeatedDigits[index]);
index is the number we looked at. The count of how many times it occurred is stored at repeatedDigits[index]. We are printing the value and how many times it occurred.
index++;
Increase the index, examining the next index value.
}
}
Let me see if I can clear a few things up for you. My first suggestion is to format your code so that the lines within loops are indented:
public static void countRepeatedDigitsInANumber(int x) {
int[] repeatedDigits = new int[10];
while (x > 0) {
int remainder = x % 10;
x = x / 10;
repeatedDigits[remainder] = repeatedDigits[remainder] + 1;
}
int index = 0;
while (index < 10) {
if (repeatedDigits[index] != 0)
System.out.println("The digit " + index + " occurs " + repeatedDigits[index]);
index++;
}
}
}
This helps us to see the structure of the program. We can now see that the program runs as follows:
Define a new int array: int[] repeatedDigits = new int[10];
Run a while loop: while (x > 0) { ... }
Define an int variable: int index = 0;
Run a second while containing an if statement: while (index < 10) { if ( ... ) { ... } }
I'll try to explain each of the four pieces one at a time.
First we define our int array. new int[10] defines an array with ten spots in it, each of which can hold an integer. You can think of this like ten boxes next to each other, each labeled with an index. This array will be used to keep track of how many times we've seen each integer. repeatedDigits[0] will hold the number of times we've seen a 0 digit in our number; repeatedDigits[6] will hold the number of times we've seen a 6 digit, and so on.
Here's the heart of the program. We're going to break down the number, one digit at a time, and for each digit, we add one to the spot in the array used to keep track of how many times we've seen that digit. This line gets us the rightmost digit in our number: int remainder = x % 10;. % is called the modulo operator, and you can search for that to learn more about it. With the input 992121, this will assign remainder to 1.
The next line uses integer division to remove that last digit from the number, so that the next time through the loop we get the next digit. if x = 992121 then after x = x / 10, x will equal 99212.
Finally, we add one to the spot in the repeatedDigits array corresponding to the digit we saw. So in our example, remainder = 1, so we add 1 to the repeatedDigits[1] spot. This line takes advantage of the fact that an uninitialized int defaults to 0.
We've reached the end of the while loop, so we check the condition, and find that x > 0, so we run the loop again. We repeat this for every digit in the input number`.
The hard work is now done; the rest of the program is there to print out the results.
We assign index to 0. The next while loop will increment this variable from 0 to 9, printing the value of the repeatedDigits array for each digit.
We run the loop from index = 0 to index = 9. For each value, we check to see if we saw that digit in our input number (that's the if statement). We check the value in repeatedDigits[index] to see if it doesn't equal 0. If so, then we must have incremented it in the previous loop, so we know that digit appeared at least once in the original input. In that case, we print a line to the console using System.out.println. Then we increment index and start the loop again.
Please let me know if you have any questions, and good luck!

Adding all numbers from 1 to N which have number of set bits as 2

I have a question where I have to add numbers from 1 to N which have their set bits as 2. Like for N = 5 we should get value 8, as number 3 and 5 have 2 bits set to one. I am implementing the same in java. I am getting the o/p correct for int value but when it comes to the long values, either it's taking a lot of time or freezing, and when I submit the same on code judge sites, it's giving run time exceeded message. Please guide me how may I optimise my code to run it faster, thanks :)
public static void main(String[] args)
{
long n = 1000000L;
long sum = 0;
long start = System.currentTimeMillis();
for(long i = 1L ; i <= n ; i++)
{
if(Long.bitCount(i) == 2)
{
sum += i;
}
}
long end = System.currentTimeMillis();
System.out.println(sum);
System.out.println("time="+(end-start));
}
As #hbejgel notes, there is no point in looping over all numbers and checking their bit count. You can simply construct numbers with 2 bits and add them up.
You can construct a number with 2 bits by picking two different bit positions in the long, the "higher" bit and the "lower" bit":
long i = (1 << higher) + (1 << lower);
So, you can simply loop over all such numbers, until the value you have constructed exceeds your limit:
long sum = 0;
outer: for (int higher = 1; higher < 63; ++higher) {
for (int lower = 0; lower < higher; ++lower) {
long i = (1 << higher) + (1 << lower);
if (i <= n) {
sum += i;
}
if (i >= n) break outer;
}
}
Let's say we know the closest number, x, equal to or lower than N with 2 set bits, then we can use the formula for power series to quickly sum all positions of the two set bits, for example, if x = b11000, we sum
4*2^0 + S(4)
+ 3*2^1 + S(4) - S(1)
+ 2*2^2 + S(4) - S(2)
+ x
where S(n) = 2 * (1 - 2^n) / (1 - 2) 
= 2 + 2^2 + 2^3 ... + 2^n
With numbers encoded 2 out of 5, exactly two bits are set in every one-digit number. The sum is 45, with the exception of N×(N-1)/2 for 0≤N<9.
I think the question is supposed to discover the pattern.
Fast forward. Given a number N, you can tell the largest number
should count by bitmask from the first two bits are set. So you have
a smaller number M
Skip to next counted number Given any number with two bit set, next
largest number is the shift the second bit by one, until underflow.
Skip to next order When underflow happens on set two, shift the
highest bit by one and also the bit on it's right.
You don't really need a loop on N, but the bits it have.
Next question: can you answer a large number? which N >100,000,000
Next Next question: can you answer the same question for X bits when X>2

Want to Convert decimal value in 2 raised to format and want to know its power of 2 in java

I have one decimal value like 65 and I want to divide this value in 2 raised to format.
For example, I have this type rule:
If I get 42 as a decimal number, I want to divide first 42 number in format of 2 raised to. Then, I want to output its power only, like:
OutPut : 1,3,5
For example, if I have 65 as a decimal number, then I want 6,0 as its output, because (2 raised to 6) + (2 raised to 0) = 65.
Thanks
Anybody can help me how I can achieve this thing in Java.
You can repeatedly compare the least significant bit, counting as you go, and right-shifting the number to look at each bit in turn:
int n = 65
int d = 0;
while (n > 0) {
if ((n & 1) == 1) { // check LSB
System.out.println(d);
}
n >>>= 1; // shift right
++d; // inc digit count
}
Integer.toString(65, 2);
Does the following output:
1000001
Then you work on the String.
This can be improved, but I think it'll do the job.
int n = 42;
String binary = Integer.toBinaryString(n);
for(int i = binary.length() - 1; i >= 0; i--){
if(binary.charAt(i) == '1')
System.out.print(i+1);
}
Here is the algorithm:
Find a log base 2 of given number x=log(2, input)
Find the floor and the ceiling of the result y = floor(x), z=ceiling(x)
Find 2^y, 2^z and choose the one closer to the input.
calculate the diff = (input - 2^(x or y)) and do the same for the diff recursively until dif=0.

Categories

Resources