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.
My problem is when I sort a list it will get the last element of the array wrong, ending up with it at the beginning of the array. In my example it fails to sort the last element which is 9, ending up printed first ahead of small numbers such as 0 and 1. Here is my code:
public class ty {
public static void main(String[]argus){
int []numbers={45,23,34,545,56,23,4,1,66,0,9};
int j;
for( int i=0;i<numbers.length;i+=1){
int first=0;
for(j=0;j<=i;j+=1){
if(numbers[j]>=first){
first=numbers[j];
numbers[j]=numbers[i];
numbers[i]=first;}
}//inner loop
}//first loop
for(int i=0;i<numbers.length;i+=1){
System.out.print(numbers[i]+" ");}
}
}
//the output is 9 0 1 4 23 23 34 45 56 66 545
As you see, they are in order except for the 9 at the start which is out of place.
You have the wrong output as a result of a logical error. You have mistakes in the Selection sort technique. Here's how to do it:
int []numbers={45,23,34,545,56,23,4,1,66,0,9};
for(int i=0; i<numbers.length-1; i+=1){
int m = i;
for(int j=i+1; j<numbers.length; j+=1){
if(numbers[m]>numbers[j])
m = j;
}
int temp = numbers[m];
numbers[m] = numbers[i];
numbers[i] = temp;
}
for(int i=0; i<numbers.length; i+=1)
System.out.print(numbers[i]+"\t");
This will work correctly and give the output:
0 1 4 9 23 23 34 45 56 66 545
I want my output to be like this e.g. if the user inputs 3:
without using 2d array
1 2 3
1 1 2 3
2 1 4 6
3 3 6 9
My code so far
public void matrixmutilplication() {
String thenumberofmatrix = JOptionPane.showInputDialog(null, "Enter the number of column and rows ");
int i = Integer.parseInt(thenumberofmatrix);
int[] cloumnarray = new int[i];
int[] rowarray = new int[i];
for (int z = 0; z <= i - 1; z++) {
cloumnarray[z] = z + 1;
rowarray[z] = z + 1;
}
for (int j = 0; j < i; j++) {
System.out.println(cloumnarray[j] * rowarray[j]);
}
}
I tried different options and can't get this to work properly.
public static void matrixmutilplication() {
String thenumberofmatrix = JOptionPane.showInputDialog(null, "Enter the number of column and rows ");
int i = Integer.parseInt(thenumberofmatrix);
for (int a = 0; a <= i; a++) {
for (int b = 0; b <= i; b++) {
// top corner, don't print nothing
if (a == 0 && b == 0) System.out.print("\t");
// top row 0-1, 0-2, 0-3 etc... just 1,2,3...
else if (a == 0) {
System.out.print(b + "\t");
// last line, print extra line break
if (b == i)
System.out.print("\n");
}
// first column 1-0, 2-0, 3-0... just a + space (tabulator)
else if (b == 0) System.out.print(a + "\t");
// any other cases, are candidates to multiply and give result
else System.out.print(a*b + "\t");
}
//look this is out of scope of nested loops, so,
// in each a iteration, print line break :)
System.out.print("\n");
}
}
public static void main(String[] args) throws Exception {
matrixmutilplication();
}
OUTPUT (3)
1 2 3
1 1 2 3
2 2 4 6
3 3 6 9
OUTPUT (5)
1 2 3 4 5
1 1 2 3 4 5
2 2 4 6 8 10
3 3 6 9 12 15
4 4 8 12 16 20
5 5 10 15 20 25
But problem (for me) is the numbers are not padded in the natural order, so, to achieve your goal, exactly as in your demo, will need a bit of padding like this
public static void matrixmutilplication() {
String thenumberofmatrix = JOptionPane.showInputDialog(null, "Enter the number of column and rows ");
int i = Integer.parseInt(thenumberofmatrix);
for (int a = 0; a <= i; a++) {
for (int b = 0; b <= i; b++) {
if (a == 0 && b == 0) System.out.print("\t");
else if (a == 0) {
System.out.print(String.format("%3s", b));
if (b == i)
System.out.print("\n");
}
else if (b == 0) System.out.print(a + "\t");
else System.out.print(String.format("%3s", a*b));
}
System.out.print("\n");
}
}
public static void main(String[] args) throws Exception {
matrixmutilplication();
}
OUTPUT (7)
1 2 3 4 5 6 7
1 1 2 3 4 5 6 7
2 2 4 6 8 10 12 14
3 3 6 9 12 15 18 21
4 4 8 12 16 20 24 28
5 5 10 15 20 25 30 35
6 6 12 18 24 30 36 42
7 7 14 21 28 35 42 49
What looks quite good :)
So this should be pretty simple.
public void matrixmutilplication() {
String thenumberofmatrix = JOptionPane.showInputDialog(null, "Enter the number of column and rows ");
int i = Integer.parseInt(thenumberofmatrix);
for (int a = 0; a < i; a++) {
for (int b = 0; b < i; b++) {
System.out.print(a*b + "\t");
}
System.out.print("\n");
}
}
Whenever you're working with a matrix involving two arrays (especially if you're trying to a solve a problem that deals with patterns), you want to have a nested for loop like so:
for(int row = 0; row < numSelected; row++) {
for(int col = 0; col < numSelected; col++) {
...
}
}
That way, each cell in the matrix will be covered. Now using that, you can try multiplying the row index and the col index and storing that to the correct cell.
How do I make this loop properly? it right now So it loops but it does not loop properly. It does this
Here are the numbers:
15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 [1]
How many positions do you want to shift?: 2
2 1 15 14 13 12 11 10 9 8 7 6 5 4 3 [3]
How many positions do you want to shift?: 4
the [] are where its suppose to ask me for my input instead of me just putting in a input
its suppose to run like this:
re are the numbers:
15 14 13 12 11 10 9 8 7 6 5 4 3 2 1
How many positions do you want to shift?: 1
2 1 15 14 13 12 11 10 9 8 7 6 5 4 3
How many positions do you want to shift?: 4
System.out.println("Here are the numbers:");
for (i=0; i<numberArray.length; i++) {
System.out.print(numberArray[i] + " ");
}
while (x != input.nextInt()){
System.out.printf("How many positions do you want to shift?: ");
int shiftTimes=input.nextInt();
for( i = 0; i < shiftTimes; ++i)
shift.Shifter(numberArray);
for(j = 0; j < numberArray.length; j++)
System.out.printf(numberArray[j]+" ");
}
}
}
Also How Do I make it exit the program when I enter in a invalid number and how do I get get it to read a negative value and get it to shift left
Edit: heres my shifter code
public static void Shifter(int[] list)
{
int i;
if (list.length < 2) return;
int last = list[list.length - 1];
for(i = list.length - 1; i > 0; i--) {
list[i] = list[i - 1];
}
list[0] = last;
}
This should work for right shift. It should work with inputs larger then array length as well.
for (int i = shiftTimes%numberArray.length; i > 0; i--) {
System.out.print(numberArray[numberArray.length - i] + " ");
}
for (int i = 0; i < numberArray.length - shiftTimes%numberArray.length; i++) {
System.out.print(numberArray[i] + " ");
}
Reversing this logic should produce a left shift approach.
An invalid input would be the length of the array (because the result will be the same) or 0 because that doesn't do anything:
if (shiftTimes == numberArray.length || shiftTimes == 0) {
// present error to user
}
UPDATE: Putting the logic in your function. Also updated the invalid input check.
public static void Shifter(int[] list, int input)
{
for (int i = input%list.length; i > 0; i--) {
System.out.print(list[list.length - i] + " ");
}
for (int i = 0; i < list.length - input%list.length; i++) {
System.out.print(list[i] + " ");
}
}
The function call would be:
Shifter(numberArray, shiftTimes);
I am doing this homework project that produces the pascals triangle but I'm getting an error and I can't find it. I looked it over many times but to me it seems okay, Can someone help me find the bug?
public class PascalsTriangle {
public static void main(String[] args) {
int[][] triangle = new int[11][];
fillIn(triangle);
print(triangle);
}
public static void fillIn(int[][] triangle) {
for (int i = 0; i < triangle.size(); i++) {
triangle[i] = new int[i++];
triangle[i][0] = 1;
triangle[i][i] = 1;
for (int j = 1; j < i; j++) {
triangle[i][j] = triangle[i-1][j-1] + triangle[i-1][j];
}
}
}
public static void print(int[][] triangle) {
for (int i = 0; i < triangle.length; i++) {
for (int j = 0; j < triangle[i].length; j++) {
System.out.print(triangle[i][j] + " ");
}
System.out.println();
}
}
I assume you have already changed your code to use length instead of size as the other answer mentions.
When you call this method:
public static void fillIn(int[][] triangle) {
for (int i = 0; i < triangle.length; i++) {
triangle[i] = new int[i++]; // this line
triangle[i][0] = 1;
The line pointed out above should be:
triangle[i] = new int[i + 1];
When you call i++ the int array will be initialized with length i and then i will be incremented. You are already incrementing i in the declaration of your for loop. So, we take away the ++.
But then we have another problem. You start the loop at i = 0. Then you initialize an array with length 0. Then you add an element to that array. Something doesn't make sense. What you meant to do was to initialize the array as int[i + 1].
Finally the program displays some lines from Pascal's Triangle:
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
1 5 10 10 5 1
1 6 15 20 15 6 1
1 7 21 35 35 21 7 1
1 8 28 56 70 56 28 8 1
1 9 36 84 126 126 84 36 9 1
1 10 45 120 210 252 210 120 45 10 1
not sure this method exist
triangle.size()
try
triangle.length
instead