This question already has answers here:
How does this while block work? [closed]
(2 answers)
Closed 7 years ago.
Consider the following method:
public int foo(int n) {
int x = 1;
int k = 0;
while (x <= n) {
x = x * 2;
k = k + 1;
}
return k;
}
What value is returned by foo(13)? I know the answer is 4 but could someone please tell me why it is 4?
x doubles with every iteration through the loop, and k increases by 1 every time through.
It's simple enough to draw out with a table.
x | k
1 | 0
2 | 1
4 | 2
8 | 3
16 | 4
32 | <end of loop>
x doubles at each step until it becomes greater than 13. So x = 1 -> 2 -> 4 -> 8 -> 16. So it gets doubled 4 times and k is also incremented 4 times. So from 0 it becomes 4.
Below is the step/algorithm steps:
X=1 k=0 n =13
Step 1: x=2 k=1
Step 2: x=4 k=2
Step 3: x=8 k = 3. Since 8<13...
Step 4: x=16 k= 4. 16>13, so return k=4.
Its finding n < 2^k where k is your answer. When n = 13: 13 < 2^k = 2^4 = 16.
K is the number of times the while loop is entered.
As x is 2 power, 2^3 is little than 13, so it enters one last time, 2^4 is bigger than 13, and then k is 4
pretty simple...
public int foo([13]) {
int x = 1;
int k = 0;
while (x <= n) {
x = x * 2;
k = k + 1;
}
return k;
}
your while loop stops when x is bigger or equal to n[13]
each time x is multiplied by 2
(definition)x = 1
x = 2
x = 4
x = 8
x = 16 (is now over n[13])
and so the while loop runs 4 times
while (x <= n) {
x = x * 2;
k = k + 1;//dis thang
}
k[0]+1=1
k[1]+1=2
k[2]+1=3
k[3]+1=4
and thats why its 4.
Related
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.
Basically, the directions go as such:
Enter positive integer greater than 3 (n)
Program should print all possible pairs of positive integers greater than one whose product is <= to number entered (n)
Here is a sample output:
Enter an integer: 24
4 = 2 x 2
6 = 2 x 3
8 = 2 x 4
10 = 2 x 5
12 = 2 x 6
14 = 2 x 7
16 = 2 x 8
18 = 2 x 9
22 = 2 x 11
24 = 2 x 12
9 = 3 x 3
12 = 3 x 4
15 = 3 x 5
18 = 3 x 6
21 = 3 x 7
24 = 3 x 8
16 = 4 x 4
20 = 4 x 5
24 = 4 x 6
(Note: Products can appear more than once, but pairs should not)
For my solution, I started by determining the factors of n like so:
public static void main(String[] args){
Scanner keyboard = new Scanner(System.in);
int factors = 0;
System.out.println("Enter integer:");
int n = keyboard.nextInt();
for(int i = 2; i <=n ; i++) {
if(n % i == 0) {
System.out.println(i);
}
}
From there, it seems I should pull each factor and multiply it by an incremented variable starting at 2 until it is equal to or exceeds (n). I started to thing maybe this was incorrect, so I tried something like this instead:
Scanner keyboard = new Scanner(System.in);
System.out.println("Enter integer:");
int n = keyboard.nextInt();
int index = 2;
int multiplier = 2;
int result = 0;
while(result < n) {
result = multiplier * index;
System.out.println(result);
index++;
}
Which works, but only for result 4 - 24, as multiplier never increments two 3. Is the actual solution just a hybrid of these possible solutions? Guidance in the correct direction would be appreciated, thank you!
I think your current approach is off, and in particular is missing one critical element to solving this: a double loop. I think the easiest way to handle this is to loop twice and generate all pairs meeting the requirements.
int number = 24;
for (int i=2; i < (int)Math.ceil(Math.sqrt(number)); ++i) {
for (int j=i; j <= number / 2; ++j) {
int pair = i * j;
if (pair <= number) {
System.out.println(pair + " = " + i + " x " + j);
}
}
}
The tricky part here was in determining the bounds for the two for loops. The second loop variable starts with the value of the first, and can get as large as half the input number. This is because the widest pair would occur when the first number be 2, forcing the second number to be the input halved. The bounds on the first loop are a bit more complex. We used the ceiling of the square root as the bounds, because the largest it can ever be would occur when both numbers are the same.
Try something like this.
Scanner keyboard = new Scanner(System.in);
System.out.print("Enter integer: ");
int n = keyboard.nextInt();
for (int i = 2; i <= n / 2; i++) {
for (int j = 2; i * j <= n; j++) {
System.out.println(i + " x " + j + " = " + (i * j));
}
}
The result as follows.
Enter integer: 24
2 x 2 = 4
2 x 3 = 6
2 x 4 = 8
2 x 5 = 10
2 x 6 = 12
2 x 7 = 14
2 x 8 = 16
2 x 9 = 18
2 x 10 = 20
2 x 11 = 22
2 x 12 = 24
3 x 2 = 6
3 x 3 = 9
3 x 4 = 12
3 x 5 = 15
3 x 6 = 18
3 x 7 = 21
3 x 8 = 24
4 x 2 = 8
4 x 3 = 12
4 x 4 = 16
4 x 5 = 20
4 x 6 = 24
5 x 2 = 10
5 x 3 = 15
5 x 4 = 20
6 x 2 = 12
6 x 3 = 18
6 x 4 = 24
7 x 2 = 14
7 x 3 = 21
8 x 2 = 16
8 x 3 = 24
9 x 2 = 18
10 x 2 = 20
11 x 2 = 22
12 x 2 = 24
I need to solve this equation in my Java app:
(1080 * j + 1) modulo 7 = 0
Is there some more safe way how to get this value instead of this code? I am not much happy with while loop condition.
int j = 1;
int e = 7;
boolean found = false;
double r = 0;
while (!found) {
r = (1080 * j + 1);
found = r % e == 0;
j++;
}
int t = (int) (r / e);
You can improve your solution significantly using maths. You need to find a number that multiplied by 1080 will given a remainder 6 modulo 7 (because after adding 1 it should be divisible by 7). Now 1080 gives remainder 2 modulo 7. Thus you need to find number that multiplied by 2 gives 6 modulo 7. Lets check all 7 possible remainders:
0 * 2 = 0 (modulo 7)
1 * 2 = 2 (modulo 7)
2 * 2 = 4 (modulo 7)
3 * 2 = 6 (modulo 7)
4 * 2 = 1 (modulo 7)
5 * 2 = 3 (modulo 7)
6 * 2 = 5 (modulo 7)
So the only solutions to your problem are the numbers giving remainder 3 (modulo 7) and all such numbers are solutions of the equation.
(1080*j + 1)% 7 =((1080*j)%7 + 1%7 )%7
And (1080*j)%7 = ((1080%7)*(j%7))%7 = (2*(j%7))% 7
And actually, j only need to run from 0 to 6, as you can clearly see that this is a periodic cycle, which help you to avoid infinite loop, as well as any number (not necessary 7)
(1080*j+1) mod 7 = 0 => 1080*j = 1 (mod 7). So you can use For loop from 0 to 6 like this :
int j;
for(int i=0; i<7; i++){
if((1080*i) % 7==1) {
j=i; break;
}
}
Here is a way to simplify the equation :-
(1080*j + 1)mod 7 = 0
(1080*j)mod7 = 6
by multiplication theorem of modular arithmetic : -
(a*b)%k = (a%k * b%k)%k hence (1080*j)%7 = (1080%7 * j%7)
1080%7 = 2
hence (1080*j)%7 = (2* j%7)%7 = 6
Now j%7 could have values (0,1,2,3,4,5,6)
now of all possible values j%7 = 3 would give (2*3)%7 = 6
j%7 = 3
therefore j = k*7 + 3 is solution to equation where k is any whole
number
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;
}
}
I am trying to create a nested for loops that will generate all the pairs in a range specified by the user, ranging from negative values to positive values. It is a little tough to explain, but here is the code I have:
public class test method {
public static void main (String[] args) {
int a = Integer.parseInt(args[0]);
int b = Integer.parseInt(args[1]);
int c = 3;
int d = 4;
for (int i = -a; i <= a; i++)
for (int j = -b; j <= b; j++) {
System.out.println(a+" and "+b+" vs "+c+" and "+d+"\n");
}
}
}
Given command line arguments 1 and 2, my desired output would be something like:
-1 and -2 vs 3 and 4
-1 and -1 vs 3 and 4
-1 and 0 vs 3 and 4
-1 and 1 vs 3 and 4
-1 and 2 vs 3 and 4
0 and -2 vs 3 and 4
0 and -1 vs 3 and 4
0 and 0 vs 3 and 4
0 and 1 vs 3 and 4
0 and 2 vs 3 and 4
1 and -2 vs 3 and 4
1 and -1 vs 3 and 4
1 and 0 vs 3 and 4
1 and 1 vs 3 and 4
1 and 2 vs 3 and 4
I assume the lack of brackets in the first for is a problem in the copy & paste, but if that's your real code you've got a problem there.
a = Math.abs(a);
b = Math.abs(b);
for (int i = -a; i <= a; i++) {
for (int j = -b; j <= b; j++) {
System.out.println(i+" and "+j+" vs "+c+" and "+d+"\n");
}
}
Two things. First of all you should be printing i and j and second you should also consider negative values. Your for's will fail since -a if a = -1 will result in
for (int i = 1; i <= -1; i++)
The condition will not be met and the iteration won't take place. By doing Math.abs you get the absolute value of the inputs and you can do the iteration from that negative value to the positive one. If both a and b are positive the abs method will return the same values (assigning a and b with the same values they already have).
Whatever should be done with c and d remains to be seen. Your desired output says you leave them as they are so I won't touch them by now.
looks reasonable, exception for the '-a' business (and printing the wrong variables)
Assuming a/b are always positive, try
for (int i = (0-a); i <= a; i++)
for (int j = (0-b); j <= b; j++) {
System.out.println(i+" and "+j+" vs "+c+" and "+d+"\n");