How to "invert" numbers in Java - java

Lets say I have a number 1-5, now if I have 2, I want 4 as an output, if I had 3 then have 3 as the output, if I have 1 then 4 as the output. Here is a chart of what I want:
1-10 Chart:
Give 1 return 9
Give 2 return 8
Give 3 return 7
Give 4 return 6
Give 5 return 5
What algorithm do I use for such a thing?

I don't see that you need an algorithm as much. What you have is:
InverseNumber = (myCollection.Length - MySelection);
Thats all you need for even numbers.
With a collection of 1 - 6 for example:
Give 2; 6 - 2 = 4. Also if given 4, 6 - 4 = 2.
You will need a slightly different problem for odds:
1 - 5; with 1 given 1 is at index 0, the opposite is 5, 2 given and the inverse ( 5 - 2) is 3. But if 3 is given, there is no inverse. So you might want to also add a catch for:
if (((myCollection.Length *.5).Round) == mySelection) { //Inverse does not exist!!!}
If you are using just integers, and not arrays of numbers then just replace the myCollection.Length with the upperbound integer.

I think the following code will work for what you need:
int a[] = new a[length_needed];
int counter = length_needed;
for(int c = 0; c < length_needed; c++) {
a[c] = counter;
counter--;
}
int number_inputed;
for(int c = 0; c < length needed; c++) {
if(c == number_inputed) System.out.println(a[c]);
}

Let's say you are giving max number as input. Then you are going to have 0-n numbers. For ex., if 9 is the max number you will have 0-9.
Then you can do something like this:
public static void main(String[] a) {
int max = a[0]; // read values from cmd line args
int forWhichNum = a[1]; //for which number we need its inverse
Sop(max- forWhichNum);
}

Integer value = 2;
Integer maxValue = 6;
Integer reverseCounter = 0;
for (int i = maxValue; i > 0; i--) {
reverseCounter++;
if (i == value) {
return reverseCounter;
}
}

Related

Why does my output give me the wrong amount of each number?

I am trying to make a program where I can input the size of a 2D array, the highest number in a 2D array, and the most amount of a certain number in the 2D array, and then fill it with random numbers in between 1 and the highest number. In my code, I specify that the max amount of times a number should repeat is 4, yet my output doesn't match that. Any suggestions?
This is my code:
class Main {
public static void main(String[] args) {
System.out.println(fill(6, 9, 4));
}
public static String fill(int size, int max, int most) {
int[][] list = new int[size][size];
int count = 0;
for (int i = 0; i < list.length; i++) {
for (int j = 0; j < list[i].length; j++) {
int x = (int)((Math.random()* max) + 1);
int y = 0;
count = 0;
for (int k = 0; k < list.length; k++) {
for (int l = 0; l < list[k].length; l++) {
if(list[k][l] == x) count++;
}
}
if(count < most) {
list[i][j] = x;
} else {
while(true) {
y = (int)((Math.random()* max) + 1);
if(y != x) break;
}
list[i][j] = y;
}
System.out.print(list[i][j] + " ");
}
System.out.println();
}
return "";
}
}
And this is my output:
9 4 6 1 9 1
7 1 4 4 3 2
6 1 4 2 7 9
5 9 4 7 2 5
3 5 3 5 7 4
3 8 8 6 2 6
Problem: There are 6 "4"s and 2 "8"s
You generate a random number.
You then check if this random number is 'invalid', in the sense that it's been used too many times.
Then, you generate a new random number, check that this isn't the same as your previous number, and then just roll with that. You are failing to check if this number, too, is 'overloaded'. So, what could have happened here is that your algorithm picked '9', counts 9s, finds 4 of them, rolls up a new random number, 9 again, so it rolls yet another number, 4, and just puts 4 in, without checking again.
Rejigger your while loops.
Or, better yet, make a utility class to offload the job of generating a random number, but not a number that's already been returned N times, to a separate class, so that you can untangle this messy code.
Your method
while(true) {
y = (int)((Math.random()* max) + 1);
if(y != x) break;
}
does not check that count of y did not already reached most
Your Issue is here:
while(true) {
y = (int)((Math.random()* max) + 1);
if(y != x) break;
}
list[i][j] = y;
This basically just rules out that x will be repeated more than most, but not y.
On a side note, I recommend using hash maps to keep track of the occurrences instead of iterating over the whole array over and over.

Java - How to get the bit number (index) from a given value? [duplicate]

This question already has answers here:
How do you calculate log base 2 in Java for integers?
(10 answers)
Closed 2 years ago.
I have one single number which is a guaranteed power of two (1,2,4,8,16,...etc).
How can I get the "bit index" from this number?
Say, I get the number "8" -> The answer I seek is "3" (bit#3)
1 -> 0
2 -> 1
4 -> 2
8 -> 3
16 -> 4
32 -> 5
..etc...
Of course I can build an array or a dictionary (the key being the number, the value the bit#) of... say 16 indices to get from the value to the bit#,
I can also do a
int i = 0, counter = 1;
while (counter != needed_value) {
counter *= 2;
i++;
}
// now "i" contains my bit#
but is there a... more fancy way?
Nothing fancy, just what the java.lang.Integer class provides (although the implementation is somewhat fancy):
int lowestOneBit = Integer.numberOfTrailingZeros(needed_value);
When 2^x = y then log2(y) = x. You know y, so the solution is:
Math.log(y) / Math.log(2)
This is because logb(a) = log(a) / log(b).
You can just find first significant bit in integer:
public static Optional<Integer> getFirstSignificantBit(int src) {
for (int i = 0; i < 32; i++) {
if ((src & 1) == 1) {
return Optional.of(i);
}
src >>= 1;
}
return Optional.empty();
}
How about recursive!
private static int bitIndex(int n) {
if (n <= 1)
return 0;
return 1 + bitIndex(n/2);
}

Having trouble filling an array of binary numbers from an integer

This is the question we were assigned :
Nine coins are placed in a 3x3 matrix with some face up and some face down. You can represent the state of the coins using a 3x3 matrix with values 0 (heads) and 1 (tails). Here are some examples:
0 0 0 1 0 1 1 1 0
0 1 0 0 0 1 1 0 0
0 0 0 1 0 0 0 0 1
Each state can also be represented using a binary number. For example, the preceding matrices correspond to the numbers:
000010000 101001100 110100001
There are a total of 512 possibilities, so you can use decimal numbers 0, 1, 2, 3,...,511 to represent all the states of the matrix.
Write a program that prompts the user to enter a number between 0 and 511 and displays the corresponding matrix with the characters H and T.
I want the method toBinary() to fill the array binaryNumbers. I realized that this does not fill in 0s to the left. I have to think that through but is that the only thing that is the problem?
//https://www.geeksforgeeks.org/java-program-for-decimal-to-binary-conversion/
import java.util.Scanner;
public class HeadsAndTails {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
int num = input.nextInt();
int[] binaryNumbers = toBinary(num);
for (int i = 0; i < 9; i++) {
printArr(binaryNumbers);
System.out.print(binaryNumbers[1]);
}
}
public static int[] toBinary(int inputtedNumber) {
int[] binaryNum = new int[9];
int i = 0;
while (inputtedNumber > 0) {
binaryNum[i] = inputtedNumber % 2;
inputtedNumber = inputtedNumber/2;
inputtedNumber++;
} return binaryNum;
}
public static void printArr(int[] arr) {
for (int i = 0; i < 9; i++) {
if (arr[i] == 0) {
System.out.print("H ");
} else {
System.out.print("T ");
}
if (arr[i+1] % 3 == 0) {
System.out.println();
} System.out.print(arr[i]);
}
}
}
Looks like you are incrementing the wrong variable in your while loop:
while (inputtedNumber > 0) {
binaryNum[i] = inputtedNumber % 2;
inputtedNumber = inputtedNumber/2;
i++; // NOT inputtedNumber
} return binaryNum;
Also note, a new int[9] is probably already initialized to 0, but if not, you could just loop 9 times, rather than until the inputtedNumber is 0:
for (int i = 0; i < 9; i++) {
binaryNum[i] = inputtedNumber % 2;
inputtedNumber = inputtedNumber/2;
}
return binaryNum;
Finally, I think your array might be backwards when you're done, so you may need to reverse it or output it in reverse order
I realize this is a homework assignment so you should stick with your current approach. However, sometimes it can be fun to see what can be achieved using the built in features of Java.
The Integer class has a method toBinaryString that's a good starting point:
int n = 23;
String s1 = Integer.toBinaryString(n);
System.out.println(s1);
Output: 10111
But as we can see, this omits leading 0s. We can get these back by making sure our number has a significant digit in the 10th place, using a little bit-twiddling:
String s2 = Integer.toBinaryString(1<<9 | n);
System.out.println(s2);
Output: 1000010111
But now we have a leading 1 that we don't want. We'll strip this off using String.substring, and while we're at it we'll use String.replace to replace 0 with H and 1 with T:
String s3 = Integer.toBinaryString(1<<9 | n).substring(1).replace('0','H').replace('1','T');
System.out.println(s3);
Output: HHHHTHTTT
Now we can print this string in matrix form, again using substring to extract each line and replaceAll to insert the desired spaces:
for(int i=0; i<9; i+=3)
System.out.println(s3.substring(i, i+3).replaceAll("", " ").trim());
Output:
H H H
H T H
T T T
If we're up for a bit of regex wizardry (found here and here) we can do even better:
for(String sl : s3.split("(?<=\\G.{3})"))
System.out.println(sl.replaceAll(".(?=.)", "$0 "));
Putting it all together we get:
int n = 23;
String s3 = Integer.toBinaryString(1<<9 | n).substring(1).replace('0','H').replace('1','T');
for(String s : s3.split("(?<=\\G.{3})"))
System.out.println(s.replaceAll(".(?=.)", "$0 "));

Correct Algorithm for Game of two stacks on HackerRank

I just attempted a stack based problem on HackerRank
https://www.hackerrank.com/challenges/game-of-two-stacks
Alexa has two stacks of non-negative integers, stack A and stack B where index 0 denotes the top of the stack. Alexa challenges Nick to play the following game:
In each move, Nick can remove one integer from the top of either stack A or B stack.
Nick keeps a running sum of the integers he removes from the two stacks.
Nick is disqualified from the game if, at any point, his running sum becomes greater than some integer X given at the beginning of the game.
Nick's final score is the total number of integers he has removed from the two stacks.
find the maximum possible score Nick can achieve (i.e., the maximum number of integers he can remove without being disqualified) during each game and print it on a new line.
For each of the games, print an integer on a new line denoting the maximum possible score Nick can achieve without being disqualified.
Sample Input 0
1 -> Number of games
10 -> sum should not exceed 10
4 2 4 6 1 -> Stack A
2 1 8 5 -> Stack B
Sample Output
4
Below is my code I tried the greedy approach by taking the minimum element from the top of the stack & adding it to the sum. It works fine for some of the test cases but fails for rest like for the below input
1
67
19 9 8 13 1 7 18 0 19 19 10 5 15 19 0 0 16 12 5 10 - Stack A
11 17 1 18 14 12 9 18 14 3 4 13 4 12 6 5 12 16 5 11 16 8 16 3 7 8 3 3 0 1 13 4 10 7 14 - Stack B
My code is giving 5 but the correct solution is 6 the elements popped out in series are 19,9,8,11,17,1
First three elements from stack A & then from Stack B.
**
I don't understand the algorithm It appears like DP to me can anyone
help me with the approach/algorithm?
**
public class Default {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int numOfGames = Integer.parseInt(br.readLine());
for (int i = 0; i < numOfGames; i++) {
String[] tmp = br.readLine().split(" ");
int numOfElementsStackOne = Integer.parseInt(tmp[0]);
int numOfElementsStackTwo = Integer.parseInt(tmp[1]);
int limit = Integer.parseInt(tmp[2]);
int sum = 0;
int popCount = 0;
Stack<Integer> stackOne = new Stack<Integer>();
Stack<Integer> stackTwo = new Stack<Integer>();
String[] stOne = br.readLine().split(" ");
String[] stTwo = br.readLine().split(" ");
for (int k = numOfElementsStackOne - 1; k >= 0; k--) {
stackOne.push(Integer.parseInt(stOne[k]));
}
for (int j = numOfElementsStackTwo - 1; j >= 0; j--) {
stackTwo.push(Integer.parseInt(stTwo[j]));
}
while (sum <= limit) {
int pk1 = 0;
int pk2 = 0;
if (stackOne.isEmpty()) {
sum = sum + stackTwo.pop();
popCount++;
} else if (stackTwo.isEmpty()) {
sum = sum + stackOne.pop();
popCount++;
}
else if (!stackOne.isEmpty() && !stackTwo.isEmpty()) {
pk1 = stackOne.peek();
pk2 = stackTwo.peek();
if (pk1 <= pk2) {
sum = sum + stackOne.pop();
popCount++;
} else {
sum = sum + stackTwo.pop();
popCount++;
}
} else if(stackOne.isEmpty() && stackTwo.isEmpty()){
break;
}
}
int score = (popCount>0)?(popCount-1):0;
System.out.println(score);
}
}
}
Ok I will try to explain an algorithm which basically can solve this issue with O(n), you need to try coding it yourself.
I will explain it on the simple example and you can reflect it
1 -> Number of games
10 -> sum should not exceed 10
4 2 4 6 1 -> Stack A
2 1 8 5 -> Stack B
First you will need to creat 2 arrays, the array will contain the summation of all the number up to its index of the stack, for example for stack A you will have this array
4 6 10 16 17 //index 0 ->4
Same will be done for stack B
2 3 11 16
then for each array start iterating from the end of the array until you reach a number less than or equal to the "sum you should not exceed"
now your current sum is the sum of the point you reached in both arrays, should be 10 +3 = 13 so in order to reach 10 will absolutely need to remove more entries
to remove the additional entries we will be moving the indexes on the array again, to decide which array to move it's index take the entry you are pointing at (10 for array 1 and 3 for array 2) and device it by index+1 (10/3 ~ 3) , (3/2 ~1) then move the index for the highest value and recalculate the sum
Suppose we have:
a = 1 1 1 211 2
b = 1 85
and maxSum = 217
Now, on calculating prefix sums,
a' = 1 2 3 214 216
and b' = 1 86
current sum = 86+216 > 217
so to decide which index to remove, we compare `
216/5~43.2` and `86/2=43`,
so we move pointer in a'. BUT, that doesn't solve it - `
214+86 is still > 217!!`
Had we removed 86, it would've been better! So we should always go ahead by removing the one which has larger difference with previous element!
In case both values are equal its logical to move the index on the value which has larger difference with its previous ( remember we are moving the index in reverse order).
the result will be the sum of the indexes +2.
This solution works great.... i hope it helps ...
import java.util.Scanner;
public class Solution {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int g = sc.nextInt();
for (int tc = 0; tc < g; tc++) {
int n = sc.nextInt();
int m = sc.nextInt();
int x = sc.nextInt();
int[] a = readArray(sc, n);
int[] b = readArray(sc, m);
System.out.println(solve(a, b, x));
}
sc.close();
}
static int[] readArray(Scanner sc, int size) {
int[] result = new int[size];
for (int i = 0; i < result.length; i++) {
result[i] = sc.nextInt();
}
return result;
}
static int solve(int[] a, int[] b, int x) {
int lengthB = 0;
int sum = 0;
while (lengthB < b.length && sum + b[lengthB] <= x) {
sum += b[lengthB];
lengthB++;
}
int maxScore = lengthB;
for (int lengthA = 1; lengthA <= a.length; lengthA++) {
sum += a[lengthA - 1];
while (sum > x && lengthB > 0) {
lengthB--;
sum -= b[lengthB];
}
if (sum > x) {
break;
}
maxScore = Math.max(maxScore, lengthA + lengthB);
}
return maxScore;
}
}
solution in python3
# stack implementation
class Stack:
lis = []
def __init__(self, l):
self.lis = l[::-1]
def push(self, data):
self.lis.append(data)
def peek(self):
return self.lis[-1]
def pop(self):
self.lis.pop()
def is_empty(self):
return len(self.lis) == 0
# number of test cases
tests = int(input())
for i in range(tests):
na, nb, x = map(int, input().split(' '))
a = list(map(int, input().split(' ')))
b = list(map(int, input().split(' ')))
temp = []
stk_a = Stack(a)
stk_b = Stack(b)
score = 0
count = 0
# first taking elements from stack A , till score becomes just less than desired total
for j in range(len(a)):
if score + stk_a.peek() <= x:
score += stk_a.peek()
count += 1
temp.append(stk_a.peek())
# storing the popped elements in temporary stack such that we can again remove them from score
# when we find better element in stack B
stk_a.pop()
# this is maximum number of moves using only stack A
max_now = count
# now iterating through stack B for element lets say k which on adding to total score should be less than desired
# or else we will remove each element of stack A from score till it becomes just less than desired total.
for k in range(len(b)):
score += stk_b.peek()
stk_b.pop()
count += 1
while score > x and count > 0 and len(temp) > 0:
count = count - 1
score = score - temp[-1]
temp.pop()
# if the score after adding element from stack B is greater than max_now then we have new set of moves which will also lead
# to just less than desired so we should pick maximum of both
if score <= x and count > max_now:
max_now = count
print(max_now)
I see that there exist a solution and you marked it as correct, but I have a simple solution
add all elements from stack one that satisfy condition <= x
every element you add push it on stack called elements_from_a
set counter to size of stack
try add elements from stack b if sum > x so remove last element you added you can get it from stack elements_from_a
increment bstack counter with each add , decrements from astack with each remove
compare sum of steps with count and adjust count return count
here is code sample for the solution :
def twoStacks(x, a, b):
sumx = 0
asteps = 0
bsteps = 0
elements = []
maxIndex = 0
while len(a) > 0 and sumx + a[0] <= x :
nextvalue = a.pop(0)
sumx+=nextvalue
asteps+=1
elements.append(nextvalue)
maxIndex = asteps
while len(b) > 0 and len(elements) > 0:
sumx += b.pop(0)
bsteps+=1
while sumx > x and len(elements) > 0 :
lastValue = elements.pop()
asteps-=1
sumx -= lastValue
if sumx <= x and bsteps + asteps > maxIndex :
maxIndex = bsteps + asteps
return maxIndex
I hope this is more simple solution.
void traversal(int &max, int x, std::vector<int> &a, int pos_a,
std::vector<int> &b, int pos_b) {
if (pos_a < a.size() and a[pos_a] <= x) {
max = std::max(pos_a + pos_b + 1, max);
traversal(max, x - a[pos_a], a, pos_a + 1, b, pos_b);
}
if (pos_b < b.size() and b[pos_b] <= x) {
max = std::max(pos_a + pos_b + 1, max);
traversal(max, x - b[pos_b], a, pos_a, b, pos_b + 1);
}
}
int twoStacks(int x, std::vector<int> &a, std::vector<int> &b) {
int max = 0;
traversal(max, x, a, 0, b, 0);
return max;
}
A recursion solution, easy to understand. This solution takes the 2 stacks as a directed graph and traversal it.
The Accepted Answer is Wrong. It fails for the below test case as depicted in the image.
For the test case given, if maximum sum should not exceed 10. Then correct answer is 5. But if we follow the approach by Amer Qarabsa, the answer would be 3. We can follow Geeky coder approach.

How to create an array of integers that equal a certain value?

Hello i am having a tough time trying to write a function that can create an array that holds integers, that equal my simple math problem.
my problem is not adding integers into the array but finding the correct integers that could add up to a math problem.
for example i have a simple math problem like: 10 + 10 = ? we know it equals 20
so i want my array to hold up to ten integers, that when added all together equal 20.
this is what i have been trying in code but not getting the results i want.
while (totalCount != answer
&& count < setCount) {
randomNumber = rand.nextInt((int) answer / 2) + 1;
if(count < setCount) {
sumOfBalloons.add(randomNumber);
totalCount += randomNumber;
count++;
}
if(totalCount > answer) {
count = 0;
totalCount = 0;
sumOfBalloons.clear();
}
}
i am trying to find random numbers that add up to the math problems answer so i can draw them on balloons. problem is i can never get ten numbers to equal the answer in my while loop.
does anyone know some way of doing something like this?
need array to hold 3 - 10 integers that equals my math problems answer.
** update on code thanks to the advice i received i managed to fix my while loop now it looks like this
had to post like this cause my rep is very low. sorry.
while (totalCount != answer) {
randomNumber = rand.nextInt((int) answer / 2) + 1;
if(totalCount + randomNumber > answer) {
randomNumber = rand.nextInt((int) answer - totalCount) + 1;
}
if(count + 1 == setCount) {
randomNumber = answer - totalCount;
}
if(count < setCount) {
sumOfBalloons.add(randomNumber);
totalCount += randomNumber;
count++;
}
if(totalCount > answer
|| totalCount == answer
&& count < setCount
|| totalCount != answer
&& count == setCount) {
count = 0;
totalCount = 0;
sumOfBalloons.clear();
}
}
this is what i got in my console from this code
Total count = 10
Total totalCount = 20
sumOfBalloons 0 = 2
sumOfBalloons 1 = 3
sumOfBalloons 2 = 3
sumOfBalloons 3 = 2
sumOfBalloons 4 = 1
sumOfBalloons 5 = 4
sumOfBalloons 6 = 2
sumOfBalloons 7 = 1
sumOfBalloons 8 = 1
sumOfBalloons 9 = 1
I think there are a few options here re: generating random numbers that sum to 20.
Here's one possible solution:
Create an array of length 4, for example.
Generate random number between 1 and 6 for each of the first 3 indices of your array.
At this point you'll have an array of the form: { 4, 5, 2, _ } (where our 4th element hasn't been chosen yet).
Sum our first 3 elements: 4 + 5 + 2 = 11. Determine 4th element by calculating 20 - current_total (11) = 9.
Set myArray[3] = 9;
A few things to note:
You may need to modify the range of possible random numbers ( 1-6 ) I've given. Consider what happens if the array we generate turns out to be { 2, 1, 2, _ }...then there's no digit that will ensure the elements sum to 20.
Another option is to use an arrayList instead of an array. The benefit to this is that you can keep adding elements to your arrayList until you either hit 20 (then you're done) or go over (in which case you delete the most recent element and begin adding again). You also won't need (or be able) to know the length of your arrayList in advance.

Categories

Resources