Changing numbers depending on position - java

Hello I'm currently coding something for class. We are basically making a credit card checker to pull the numbers from a text file. The rules we have to follow for the check digit are the following.
Drop the last digit from the card number. The last digit is the check
digit.
Reverse the digits.
Multiply the digits in odd positions (1, 3, 5, etc.) by 2.
Subtract 9 from any result higher than 9.
Sum all the digits.
The check digit (the last number of the card) is the amount that you
would need to add to get a multiple of 10 (Modulo 10)
So I pulled the check digit away by setting a new variable and taking the card # /10. It's in a long so no decimals so this gets rid of the last digit. I then stored that digit as my check digit using %10 of the original number. I then used a loop to reverse the digits which can be seen as:
long lcards = Long.parseLong(cards);
long lastDigit = lcards % 10;
long newCard = lcards / 10;
long reverseCard = 0;
while (newCard != 0)
{
reverseCard = reverseCard * 10;
reverseCard = reverseCard + (newCard % 10);
newCard = newCard / 10;
}
I'm now stuck on the next step :/. How would I do this? Thanks!

Next step:
Multiply the digits in odd positions (1, 3, 5, etc.) by 2.
That requires you to iterate all digits in your input number. And there are two ways to do that:
More or less the same as your first attempt to get rid of the last digit - you can use modulo/division operations to "access" each digit in your number in a similar way as you did before!
Or, instead of working on one number, consider turning the whole number into an array of int values for example; like shown here. Now you can just iterate that array and make the necessary computations.
And in the end, just "merge" the array back into a single number. You could even do that upfront, to get rid of the last digit.
Hope that helps to get you going on the rest of the exercise!

Related

Validate if numbers are valid within a given range, depending on used pre-selection

I'm writing a program that generates n number of bonuses, it does well but when it comes to generate their id numbers i am stuck. The program at that point needs the user to tell the program a Min value and a Max value between 10000 and 10000, until there no problem all easy.
The part after it is making me scratch my head because the program needs to know how many numbers can be generated at a given position of the value generated so it's not a fixed range, the ids generated must and only include the numbers that the user specified for every x position and it has to know that so when it's reading the values that are going to be used for that purpose, they get verified for it's corresponding position.
I have tried to use some some conditions for some cases that i have identified within the working program, but i'm actually stuck because it seems like ill have to build a lot of if statements to contain all of the possible types of ids that can occur.
// from left to right the "positions"
int min = 1 0 0 0 0;
int max = 1 0 9 9 9;
int temp = max - min;
// tells how many different digits can be used from 1 to 10 for each position (0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
// leftmost position aka first
delta[0] = temp / 10000;
// aka second position
delta[1] = (temp % 10000) / 1000;
// aka third position
delta[2] = ((temp % 10000) % 1000) / 100;
// aka fourth position
delta[3] = (((temp % 10000) % 1000) % 100) / 10;
// aka fifth position
delta[4] = ((((temp % 10000) % 1000) % 100) % 10);
these formulas work as expected, however when a given position resets there is no way for the formulas to say "you can include all 10 digits on this position because it's not just 0, it's 10000 to 10999".
[EDIT]
To clarify the question above, i am required by my teacher to do the following in order to generate the bonuses id numbers:
ask the user a range (inclusive) between 10000 and 99999. this means that i can only generate 5 digit ids for a given amount of bonuses, they should not repeat.
also ask the user numbers allowed for every position within that 5 digits range given, i.e. my range goes from 12000 to 22000, from left to right of the 5 digits that can be generated user says that he only wants the number 1 to appear so that now limits my ids to generate to values from 12000 to 19999... but he can also say that he only wants the number 2 to be at that particular position so the opposite might happen as well (from 20000 to 22000 ids are only possible to be used). this applies for all 5 digits that can be generated at any given range between min and max.
It would be much, much simpler to keep a List of numbers, generate your ids randomly, and compare, like so:
public class IdGenerator {
private static List<Integer> usedIds = new ArrayList<>();
... (other fields and methods here)
public int generateNumber() {
// Check if all ids are used. (Redesign your ID scheme to prevent this situation, otherwise you'll run out of IDs and your application will stop working.
if (usedIds.size() >= 1000) {
throw new IllegalStateException("All allowable IDs used, please free up an ID to continue generation.");
}
// Generate a random ID with a value between 10000 and 10999.
int idCandidate = ThreadLocalRandom.current().nextInt(10000, 10999 + 1);
// ID in use, try again with new number.
if (usedIds.contains(idCandidate) {
return generateNumber();
}
// ID is not taken and can therefore be saved.
usedIds.add(idCandidate);
return idCandidate;
}
}
Even better would to be to use UUIDs, since they are more or less guaranteed to be unique.

Using recursion to determine the number of digits

I'm currently stuck on one line of code that I'm not fully understanding.
So, I'm reading example codes from the book, and one of "programs" used recursion to determine the number of digits in an integer n. The one line of code that I got stuck at and do not fully understand is:
if (number >= 10) {
return numberOfDigits(number / 10) + 1;
For an example, this makes the number 42 return 2, which it's supposed to do. But how exactly does the function return 2? 42 divided by 10 is equal to 4,2 or 4. That plus 1 is 5, so how does it return 2?
Recursion is a way to get one call of the method to perform some of the work, while deferring the remainder of the work to making another recursive call. Here, a "number of digits" recursive method says that the number of digits in a number is equal to 1 for the last digit plus the number of digits remaining after the last digit is removed.
In the return statement, the + 1 counts the last digit in the number, while number / 10 performs truncating integer division to remove the last digit. The recursive call counts the digits in the number with the last digit removed.
What you haven't shown is the base case of the recursion, when the number is single-digit (not greater than or equal to 10). That is simply 1 digit. The value 4 is not figured into the calculation. The method effectively counts the digits, one at a time, until there are no more digits left. There is one recursive method call per digit.
The full method probably looks something like this:
public int numberOfDigits(int number) {
if (number >= 10) {
return numberOfDigits(number / 10) + 1;
}
// base case: only one digit
return 1;
}
By inspection, if we pass a two digit number, the if statement will be hit, which will return whatever the recursive call of the input / 10 is, plus one. Let's say the input were 42. In this case, it would return numberOfDigits(42 / 10) + 1. We know that numberOfDigits(4) returns 1, so this would return a total of 2, which is correct.
Using inductive reasoning, we can build up to convince ourselves of any number of arbitrary length.
Side note: In my travels, I have more often seen the base case handled first using an if statement, with the inductive case happening by default. So, I would have expected to see this code:
public int numberOfDigits(int number) {
if (number < 10) return 1;
return numberOfDigits(number / 10) + 1;
}

Java - how to divide an integer into 5 random parts

I'm working on an android graphics app, and at some point in the code, I need to divide lets say, a rectangle's width into 5 random sizes.
I have my randomintegerfunction(int min, int max) in my activity, but that can help me divide it into 2 parts.
How do I go about dividing an integer, lets say 100, into 5 random parts, so that the first one or two parts arent always the biggest, then I subdivide for the third, fourth and fifth parts?
Right now, I am know I can try to implememt it using my random integer generator,but the issue, I think is that I'd have to use some forced divisions, like dividing the first 70% of the integer into 2 parts, then dividing the remaining 20% into two parts, to make a total of 5 parts, but such a method would always make the first part be bigger than the fifth part, which I'd like to avoid...to make it truly random.
What I'd like, for example...
the first part to potentially be 7,
second part 25,
third part 5,
fourth part 40,
fifth/last/remaining part 23. To add up to 100 (or any integer).
I am not sure about how to write the logic of such a function...so please if you have any ideas of how to implement a function that randomly divides an integer into 3 or 4 or 5 or 6 truly random sizes/parts, please enlighten me!
Thanks for your time!
You could randomly select from the amount remaining.
int[] nums = new int[5];
int total = 100;
Random rand = new Random();
for (int i = 0; i < nums.length-1; i++) {
nums[i] = rand.nextInt(total);
total -= nums[i];
}
nums[nums.length-1] = total;
Arrays.sort(nums);
This will select a random number and ensure the sum is always the same. The last sort ensures they are in ascending order.
A simple algorithm is to put the numbers 1-99 into a list, shuffle them, and take the first 4 elements as your "split points", i.e. positions at which to divide the number range.
List<Integer> splitPoints =
IntStream.rangeClosed(1, 99)
.boxed().collect(Collectors.toList());
Collections.shuffle(splitPoints);
splitPoints.subList(4, splitPoints.size()).clear();
Collections.sort(splitPoints);
Now, you have 4 randomly-placed split points. The ranges go from:
0 -> splitPoints.get(0)
splitPoints.get(0) -> splitPoints.get(1)
...
splitPoints.get(3) -> 100.
Take four numbers from below range:
4 to n-1
And then divide each number by four .
And fifth number to be n - (sum of other four).
Where n is 100 in the given case..
Again this is one way of implementation and there are hundred of ways to implement it
Hope that helps.
The most efficient way to do this and to keep proper distribution - looks like this.
1) In general cases. You need divide line into N parts.
generate N-1 doubles [0,1], add 0 and 1, and sort them -> x[i] = {0, ..., 1}
N-1 point divide line into N parts -> 0=x[0]..x[1]; x[1]...x[2]; ... x[N]..x[N+1]=1
scale each part to proper size -> len[i] = (x[i+1]-x[i])*total_length
cast to int if needed
2) In case when you need large Objects and small gaps - split you length with desirable proportion, like 70% for objects and 30% for gaps. Or generate it nextDouble(0.2)+0.2 for [0.2,0.4) range for gaps. Then use proposed algorithm twice.

Bulls and Cows Java code explanation

I've been searching for the source code of this game and found this one. However, I didn't understand the hasDupes method at the end of the code.
Could you explain it to me?
Source code - here
public static boolean hasDupes(int num){
boolean[] digs = new boolean[10];
while(num > 0){
if(digs[num%10]) return true;
digs[num%10] = true;
num/= 10;
}
return false;
So let's step through it:
boolean[] digs = new boolean[10];
In Java, all the items in an array declaration are given a default value. In the case of boolean, it is false. So this creates an array of 10 elements where each element is false
while(num > 0){
if(digs[num%10]) return true;
digs[num%10] = true;
num/= 10;
}
Modding a number by 10 (num % 10) and then dividing by 10 (num/= 10) is a common way to "pop" off the last digit from a number. For example,
int someNum = "1357";
int lastDigit = mod % 10; // lastDigit is 7
someNum /= 10; // someNum is now 135
As you can see, the 7 gets removed. So the while loop is just popping of each digit of num until all the digits are processed. Now, for each digit that is being removed, digs[num%10] = true; is simply keeping track of the digits already removed. By keeping track of these, if(digs[num%10]) return true; will return true from the method if a digit has already been processed.
So, in much simpler words, this method just checks to see if a number contains more than 1 of the same digit.
12345 will return false
12341 will return true
Just make a pen & paper test. Our number system has 10 digits: 0 to 9. digs represents, whether a digit has occured already. with num % 10 you get the last digit of num. So let's say num has an 1 at the least significant position. That means: digs[i] will be set to true (digs[num%10] = true;). Now let's look on: with num /= 10 you remove the last digit from an integer. For example, 3211 /= 10 will be 321 (integer arithmetics, I know you cannot apply /= to literals, but it is only a demonstration to explain the semantics). Since num is > 0, the loop is executed again. This time, the if-condition will be true (because we set digs[1] to true one iteration before), we found a duplicate digit. If the method is able to leave the loop without entering the if, num has pairwise unequal digits. That's it.
It's checking if any value in base 10 has duplicated digits.
So 9019 has duplicated digits (9) when written as a decimal value. 123 does not.
In the context of the game, it basically checks to see if the given integer, num, has duplicated digits. It does so by creating an array of 10 boolean values, such that two digits that are duplicated will be dropped into the same cell in the array. The algorithm uses
An array of 10 boolean values to represent each digit in our base 10 number system. So if you are dealing with base 16 number system, you will need an array of 16 boolean values.
num modulo 10 to extract the least significant digit of num until all digits have been examined. Again, it uses modulo 10 because it is assuming a base 10 number system.
The moment that duplicated digits are detected, the method returns true:
if(digs[num%10]) return true;
If you look at the main() method in your sample codes, the algorithm will attempt to keep generating random number, until one with no duplicated digits is found.
while(hasDupes(target= (gen.nextInt(9000) + 1000)));

Sorting by least significant digit

I am trying to write a program that accepts an array of five four digit numbers and sorts the array based off the least significant digit. For example if the numbers were 1234, 5432, 4567, and 8978, the array would be sorted first by the last digit so the nest sort would be 5432, 1224, 4597, 8978. Then after it would be 1224, 5432, 8978, 4597. And so on until it is fully sorted.
I have wrote the code for displaying the array and part of it for sorting. I am not sure how to write the equations I need to compare each digit. This is my code for sorting by each digit so far:
public static void sortByDigit(int[] array, int size)
{
for(int i = 0; i < size; i++)
{
for(int j = 0; j < size; j++)
{
}
for(i = 0; i < size; i++)
{
System.out.println(array[i]);
}
}
}
I am not sure what to put in the nested for loop. I think I need to use the modulus.
I just wrote this to separate the digits but I don't know how to swap the numbers or compare them.
int first = array[i]%10;
int second = (array[i]%100)/10;
int third = (array[i]%1000)/10;
int fourth = (array[i]%10000)/10;
Would this would go in the for loop?
It seems like your problem is mainly just getting the value of a digit at a certain index. Once you can do that, you should be able to formulate a solution.
Your hunch that you need modulus is absolutely correct. The modulo operator (%) returns the remainder on a given division operation. This means that saying 10 % 2 would equal 0, as there is no remainder. 10 % 3, however, would yield 1, as the remainder is one.
Given that quick background on modulus, we just need to figure out how to make a method that can grab a digit. Let's start with a general signature:
public int getValueAtIdx(int value, int idx){
}
So, if we call getValueAtIdx(145, 2), it should return 1 (assuming that the index starts at the least significant digit). If we call getValueAtIdx(562354, 3), it should return 2. You get the idea.
Alright, so let's start by using figuring out how to do this on a simple case. Let's say we call getValueAtIdx(27, 0). Using modulus, we should be able to grab that 7. Our equation is 27 % x = 7, and we just need to determine x. So 27 divided by what will give us a remainder of 7? 10, of course! That makes our equation 27 % 10 = 7.
Now that's all find and dandy, but how does 10 relate to 0? Well, let's try and grab the value at index 1 this time (2), and see if we can't figure it out. With what we did last time, we should have something like 27 % x = 27 (WARNING: There is a rabbit-hole here where you could think x should be 5, but upon further examination it can be found that only works in this case). What if we take the 10 we used earlier, but square it (index+1)? That would give us 27 % 100 = 27. Then all we have to do is divide by 10 and we're good.
So what would that look like in the function we are making?
public int getValueAtIdx(int value, int idx){
int modDivisor = (int) Math.pow(10, (idx+1));
int remainder = value % modDivisor;
int digit = remainder / (modDivisor / 10);
return digit;
}
Ok, so let's to back to the more complicated example: getValueAtIdx(562354, 3).
In the first step, modDivisor becomes 10^4, which equals 10000.
In the second step, remainder is set to 562354 % 10000, which equals 2354.
In the third and final step, digit is set to remainder / (10000 / 10). Breaking that down, we get remainder / 1000, which (using integer division) is equal to 2.
Our final step is return the digit we have acquired.
EDIT: As for the sort logic itself, you may want to look here for a good idea.
The general process is to compare the two digits, and if they are equal move on to their next digit. If they are not equal, put them in the bucket and move on.

Categories