selling a ticket and replacing the sold seat with a 0 - java

This is a movie ticket theatre seller program. The task is create a method that takes the price of the user's input, finds the first seat and replaces it with a 0, denoting a sold seat. I keep fiddling with it but it keeps wanting to change all instances of the price input to 0 instead of the first found.
public boolean getByPrice(int price) {
boolean retVal = false; //initially false, have not found
System.out.println("You chose to buy a ticket with price: $" + price);
if (price == 10) {
for (int i = 0;i<NUM_ROWS;i++) {
for (int j = 0; j<NUM_COLS; j++) {
if (seats[i][j] == 10) {
retVal = true;
seats[i][j] = 0;
}
pricesAvailable[0] = pricesAvailable[0] - 1;
}
}
}
if (price == 20) {
for (int i = 0; i<NUM_ROWS;i++) {
for (int j = 0; j<NUM_COLS;j++) {
if (seats[i][j] == 20) {
retVal = true;
seats[i][j] = 0;
}
pricesAvailable[1] = pricesAvailable[1] - 1;
}
}
}
if (price == 30) {
for (int i = 0; i<NUM_ROWS;i++) {
for (int j = 0; j<NUM_COLS; j++) {
if (seats[i][j] == 30) {
retVal = true;
seats[i][j] = 0;
}
pricesAvailable[2] = pricesAvailable[2] - 1;
}
}
}
if (price == 40) {
for (int i = 0; i<NUM_ROWS;i++) {
for (int j = 0; j<NUM_COLS;j++) {
if (seats[i][j] == 20) {
retVal = true;
seats[i][j] = 0;
}
pricesAvailable[3] = pricesAvailable[3] - 1;
}
}
}
if (price == 50) {
for (int i = 0; i<NUM_ROWS;i++) {
for (int j = 0; j<NUM_COLS;j++) {
if (seats[i][j] == 50) {
retVal = true;
price = 0;
}
pricesAvailable[4] = pricesAvailable[4] - 1;
}
}
}
return retVal;
}
Also, the other part is to implement the same type of method using location
public boolean getByLoc(int row, int col) {
boolean retVal = false; //initially false
System.out.println("You chose row: " + row + ", col: " + col);
//************YOUR SOLUTION GOES HERE************//
for (int i = 0;i<NUM_ROWS;i++) {
for (int j = 0; j<NUM_COLS; j++) {
}
}
return retVal; //return value
}
I am not sure how use to make the location method work at all

Your loop does not exit when you found a seat. You could use break like:
for (int i = 0; i<NUM_ROWS && !retVal; i++){
for (int j = 0; j<NUM_COLS && !retVal; j++){
if (seats[i][j] == 10){
retVal = true;
seats[i][j] = 0;
break;
}
}
if (retVal) break;
}
or you could add a condition to your loops like:
for (int i = 0; i<NUM_ROWS && !retVal; i++){
for (int j = 0; j<NUM_COLS && !retVal; j++){
...
}
}
I would also recomend to reduce the code duplication by having the same loop in multiple ifs. How about summarizing it like this? (I assumed the pricesAvailable should only be lowerd when a seat has been found)
if (price == 0) { throw new IllegalArgumentException("Not giving away freebies"); }
for (int i = 0; i<NUM_ROWS && !retVal; i++){
for (int j = 0; j<NUM_COLS && !retVal; j++){
if (seats[i][j] == price){
retVal = true;
seats[i][j] = 0;
pricesAvailable[(price/10)-1]--;
}
}
}
Edit: Of couse returning inside the loops would also work if this is all you want to do in this method:
if (price == 0) { throw new IllegalArgumentException("Not giving away freebies"); }
for (int i = 0; i<NUM_ROWS; i++){
for (int j = 0; j<NUM_COLS; j++){
if (seats[i][j] == price){
seats[i][j] = 0;
pricesAvailable[(price/10)-1]--;
return true;
}
}
}
return false;

You'll probably want to utilise a break; somewhere if you intend to keep your code as it is.
http://docs.oracle.com/javase/tutorial/java/nutsandbolts/branch.html
http://www.c4learn.com/java/java-break-statement/

You need to break the for-loop when you have found a matching seat, otherwise it will continue to check all the other seats.
You have two nested loops, but you want to break out of both. There are a few ways to do this, but as this is relatively simple code, a label will suffice. Take a look at http://docs.oracle.com/javase/tutorial/java/nutsandbolts/branch.html.
As the comments have pointed out, this is obviously homework, so I won't post a full code listing, instead, here is a snippet:
rows:
for (int i = 0; i < NUM_ROWS; i++)
{
cols:
for (int j = 0; j < NUM_COLS; j++)
{
if (seats[i][j] == 30)
{
retVal = true;
seats[i][j] = 0;
}
pricesAvailable[2] = pricesAvailable[2] - 1;
break rows;
}
}
Also, please use braces around if-statements, it's just another way to introduce bugs.

That is because you keep looping even after you have found the first seat with that price. The best thing here would be to use a method, like below, and return after you're done with the first one. This will solve both your refactoring problems and your incorrect values:
public boolean findFirst(int cost){
for (int i = 0;i<NUM_ROWS;i++)
for (int j = 0; j<NUM_COLS; j++)
if (seats[i][j] == cost){
seats[i][j] = 0;
pricesAvailable[cost / 10 - 1] -= 1;
return true;
}
return false;
}
Then call it from your getByPrice function like this:
public boolean getByPrice(int price) {
boolean retVal = false; //initially false, have not found
System.out.println("You chose to buy a ticket with price: $" + price);
if (price == 10)
retval = findFirst(10);
//rest of the code...

You should break the loop as soon as the place is found. Otherwise you'll put 0 on all places that have the price == 10.
if (price == 10) {
for (int i = 0;i<NUM_ROWS;i++) {
for (int j = 0; j<NUM_COLS; j++) {
if (seats[i][j] == 10) {
retVal = true;
seats[i][j] = 0; //and here break/return.
}
pricesAvailable[0] = pricesAvailable[0] - 1;
}
}
}
Also your basically copying the same code 5 times. What if there were 100 different prices? Whould you copy that code 100 times?
You should consider putting the code that is duplicated inside a method and the variable part (price in this example) should be an input parameter.
Moreover variable pricesAvailable is quite problematic. First it's not named the best way. Maybe seatsAvailableAtPrice would sound better? And I don't think that array is the best container for that - you should try using Map where first integer would be the price, and the second would be the number of seats left for that price.
Map<Integer, Integer> seatsAvailableAtPrice = new HashMap<Integer, Integer>();
Putting it all together you could create a method like that:
private void reserveFirstAvailableSeatForPrice(final int price) {
for (int i = 0;i<NUM_ROWS;i++) {
for (int j = 0; j<NUM_COLS; j++) {
if (seats[i][j] == price) {
seats[i][j] = 0;
seatsAvailableAtPrice.put(price, seatsAvailableAtPrice.get(price) - 1);
return;
}
}
}
}
As for the second part - isn't that just checking if i=row and j=col? And if so making a reservation (setting price to 0)?

Related

Break statement not taking me outside of loop java

I am solving this problem on code forces.
https://codeforces.com/contest/1675/problem/B
The break statement I have doesn't break out of the while loop.
When I use this input:
It outputs -1 one twice in the same case, which shows that the break statement isn't taking me outside the loop?
Why is this happening?
public class vanita {
public static void main (String[]args) {
Scanner in = new Scanner(System.in);
int cases = in.nextInt();
for (int i = 0; i < cases; i++) {
boolean test = true;
int arrLength = in.nextInt();
int arr[] = new int[arrLength];
for (int j = 0; j < arrLength; j++) {
arr[j] = in.nextInt();
}
int operations = 0;
int after;
for (int j = arrLength-1; j >= 1 ; j--){
after = arr[j-1];
while (arr[j] <= after) {
arr[j-1] = (int)Math.floor(arr[j-1]/2);
after = arr[j-1];
operations++;
if (arr[j] == 0 && arr[j-1] == 0) {
//System.out.println("current: " + arr[j]);
//System.out.println("after: " + arr[j-1]);
//System.out.println("Case " + i);
System.out.println("-1");
test = false;
break;
}
}
}
for (int s = 0; s < arrLength; s++) {
//System.out.print(arr[s] + " ");
}
//System.out.println(" ");
if (test == true) {
System.out.println(operations);
}
}
}
}
i think it breaks out of the inner while loop, but not the outer for loop. So the inner while loop runs multiple times.
Problems
Normally a break; will always break out of the most recent loop. If you can't break out of your loop, the problem is your algorithm or your condition.
Solutions
First, always debug to see if you enter your if statement.
Second, use something else as condition of your while loop. You could use a boolean and change its value to break the while condition. Ex:
boolean hasFoundDuplicate = false;
while(!hasFoundDuplicate){
arr[j-1] = (int)Math.floor(arr[j-1]/2);
after = arr[j-1];
operations++;
if(arr[j] == 0 && arr[j-1] == 0){
hasFoundDuplicate = true;
}
}

Making a java 2048 game, upon sliding it goes through the loop more times than it should and hits tests/alters numbers already altered

So I have a solid slide function, the problem is (which is very hard to explain!) it goes through all the possibilities including spaces in the 2d array that have already been added together: say there is a setup like this: 4,4,8,2 ---after one swipe to the right, it ends up like this: ,_,16,2. however in the actual game, after one swipe right, it should look like this: ___,8,2.
Basically, how can I fix this? You don't need to tell me the code, it's my project for my final, but I'd like to get some sort of explanation as to why this is happening.
I've attempted to loop through the array from right to left but that resulted in the numbers not even moving.
processUserChoice(String i) {
if (i.equals("d")) {
while ((slideRight())) {
moveRight();
}
}
printBoard();
}
public boolean slideRight() {
for (int i = 0; i < board.length; i++) {
for (int j = 0; j < board[i].length - 1; j++) {
if (board[i][j + 1] == 0 && board[i][j] != 0) {
return true;
} else if (board[i][j + 1] == board[i][j] && board[i][j] != 0) {
return true;
}
}
}
return false;
}
public void moveRight() {
for (int i = 0; i < board.length; i++) {
for (int j = 0; j < board[i].length - 1; j++) {
if (board[i][j + 1] == 0 && board[i][j] != 0) {
board[i][j + 1] = board[i][j];
board[i][j] = 0;
} else if (board[i][j + 1] == board[i][j] && board[i][j] != 0) {
board[i][j + 1] = board[i][j + 1] + board[i][j];
board[i][j] = 0;
}
}
}
//checkLose();
}
After one swipe right, it should look like this:" ___,8,2 "(From the example before).
I did something similar to this in the past. I would to do it pretty much the same way as you are at the moment but add a Boolean array that checks if the tile has collided or not and only merges tiles that haven't been collided.
class Tile {
public int value;
public Boolean collided;
public Tile(int value) {
this.value = value;
collided = false;
}
public Tile attemptMerge(Tile target) {
if (target.value == value) {
Tile t = new Tile(value * 2);
t.collided = true;
return t;
} else {
return null;
}
}
public void reset() {
value = 0;
collided = false;
}
}
Somewhere in your main update loop:
void slideRight() {
for (int row = 0; row < 4; row++) {
for (int column = 3; column >= 0; column--) {
Tile current = board[row][column];
if (current.value == 0) continue;
for (int slot = column + 1; slot < 3; slot++) {
Tile target = board[row][slot];
if (target.value == 0) {
target.value = current.value;
current = target;
board[row][slot - 1].reset();
} else if (target.value == current.value) {
Tile product = target.merge(current);
if (!target.collided && !current.collided) {
current = product;
board[row][slot - 1].reset();
} else {
break;
}
} else {
break;
}
}
}
}
}
I believe something along those lines should work. Sorry if the logic is a bit flawed.

Exception being thrown for connect 4 algorithm

So I keep running into a problem with my code for checking if there is a connect 4 vertically. Preface to my code: the board has 6 rows and 7 columns, the variable player1 holds the value of the character being used as a chip and playerID just holds the value of whoever gets the connect 4.
public int verticalWin() {
int playerID = 0;
for (int x = 0; x < board[x].length; x++) {
int count = 1;
for (int y = board.length-2; y >= 0; y--) {
if (board[y][x] == board[y+1][x]) {
count++;
if (count == 4) {
if (board[y][x] == player1) {
playerID = 1;
} else {
playerID = 2;
}
}
} else {
count = 1;
}
}
}
return playerID;
}
The problem I keep running into is that an exception java.lang.ArrayIndexOutOfBoundsException: 6 keeps happening and I think it's in the first line, but I can't seem to find the problem.
Some cleaner code
boolean isWinnerOnColumn(int playerID, int column) {
int count = 0;
for (int row = 0; row < 6; row++) {
count = (board[row][column] == playerID) ? (count + 1) : 0;
if (count == 4){
return true;
}
}
return false;
}
public int verticalWin() {
for (int column = 0; column < 7; column++) {
if (isWinnerOnColumn(1, column) {
return 1;
}
if (isWinnerOnColumn(2, column) {
return 2;
}
}
return 0; // no winner
}

I am trying to assign a number to each character

import java.util.Scanner;
public class Recursion
{
//variables to hold string values
public static String s1 = new String(new char[10]);
public static String s2 = new String(new char[10]);
public static String s3 = new String(new char[11]);
public static String charSet = new String(new char[11]);
//variables to hold number values
public static int numberOne;
public static int numberTwo;
public static int numberThree;
public static int maxCharCount;
public static int[] numberSet = new int[10];
//function which generates a number
public static void checkForEquality()
{
numberOne = numberTwo = numberThree = 0;
int i;
int j;
for (i = 0; i < s1.length(); i++)
{
for (j = 0; j < maxCharCount; j++)
{
if (s1.charAt(i) == charSet.charAt(j))
{
if (i == 0 && numberSet[j] == 0)
return;
//generate the number
numberOne = (numberOne * 10) + numberSet[j];
}
}
}
for (i = 0; i < s2.length(); i++)
{
for (j = 0; j < maxCharCount; j++)
{
if (s2.charAt(i) == charSet.charAt(j))
{
if (i == 0 && numberSet[j] == 0)
return;
//generate number
numberTwo = (numberTwo * 10) + numberSet[j];
}
}
}
for (i = 0; i < s3.length(); i++)
{
for (j = 0; j < maxCharCount; j++)
{
if (s3.charAt(i) == charSet.charAt(j))
{
if (i == 0 && numberSet[j] == 0)
return;
//generate the number
numberThree = (numberThree * 10) + numberSet[j];
}
}
}
}
public static void display(){
if (numberOne + numberTwo == numberThree) {
//display the output
int i=0;
System.out.println();
System.out.print(" Summation Puzzle solved. ");
System.out.print("n");
System.out.print(s1);
System.out.print("<==>");
System.out.print(numberOne);
System.out.print("n");
System.out.print(s2);
System.out.print("<==>");
System.out.print(numberTwo);
System.out.print("n");
System.out.print(s3);
System.out.print("<==>");
System.out.print(numberThree);
System.out.print("n");
//loop to show the result
for (i = 0; i < maxCharCount; i++)
{
System.out.println(charSet.charAt(i));
System.out.print("<==>");
System.out.print(numberSet[i]);
System.out.print("n");
}
System.exit(0);
}
}
//recursive function which will call itself
public static void Combinations(int indexCounter, int[] availableSet)
{
int i;
if (indexCounter != 0)
{
for (i = 0; i < 10; i++)
{
numberSet[indexCounter] = i;
if (availableSet[i] == 1)
{
availableSet[i] = 0;
Combinations(indexCounter + 1, availableSet);
availableSet[i] = 1;
}
}
}
if (indexCounter == maxCharCount)
checkForEquality();
}
public static void createCharSet()
{
int i;
int setIndex;
int present;
int j;
setIndex = 0;
for (i = 0; i < s1.length(); i++)
{
present = 0;
for (j = 0; j < setIndex; j++)
{
if (s1.charAt(i) == charSet.charAt(j))
{
present = 1;
}
}
if (present == 0)
{
charSet = StringFunctions.changeCharacter(charSet, setIndex++, s1.charAt(i));
}
}
for (i = 0; i < s2.length(); i++)
{
present = 0;
for (j = 0; j < setIndex; j++)
{
if (s2.charAt(i) == charSet.charAt(j))
{
present = 1;
}
}
if (present == 0)
{
charSet = StringFunctions.changeCharacter(charSet, setIndex++, s2.charAt(i));
}
}
for (i = 0; i < s3.length(); i++)
{
present = 0;
for (j = 0; j < setIndex; j++)
{
if (s3.charAt(i) == charSet.charAt(j))
{
present = 1;
}
}
if (present == 0)
{
charSet = StringFunctions.changeCharacter(charSet, setIndex++, s3.charAt(i));
}
}
maxCharCount = setIndex;
}
public static void calculateSummation()
{
int loop;
if (maxCharCount > 10)
{
System.out.print("Please check the input again");
return;
}
else
{
int[] avaliableSet = new int[10];
for (loop = 0; loop < 10; loop++)
{
avaliableSet[loop] = 1;
}
Combinations(0, avaliableSet);
}
}
//main method
public static void main(String[]args) {
Scanner scan = new Scanner(System.in);
System.out.print("Enter the first String :");
s1 = scan.next();
System.out.print("Enter the second String :");
s2 = scan.next();
System.out.print("Enter the thirsd String :");
s3 = scan.next();
createCharSet();
System.out.print(" result of your 3 three strings = ");
System.out.print(charSet);
calculateSummation();
checkForEquality();
display();
}
}
Every time I run the program it just assigns 0 to each value. I want to be able to assign a value from 1-10 to each non numeric character.
can someone help me out.?
it should look something like this
Sample output
First off, you may find debugging easier if you properly format your code. I remember you posting last night where you experienced similar issues resulting from syntax. You may find that your code is easier to read if you format it like this:
//function which generates a number
public static void checkForEquality(){
numberOne = numberTwo = numberThree = 0;
int i;
int j;
for (i = 0; i < s1.length(); i++){
for (j = 0; j < maxCharCount; j++){
if (s1.charAt(i) == charSet.charAt(j)){
if (i == 0 && numberSet[j] == 0)
return;
//generate the number
numberOne = (numberOne * 10) + numberSet[j];
}
}
}
for (i = 0; i < s2.length(); i++){
for (j = 0; j < maxCharCount; j++){
if (s2.charAt(i) == charSet.charAt(j)){
if (i == 0 && numberSet[j] == 0)
return;
//generate number
numberTwo = (numberTwo * 10) + numberSet[j];
}
}
}
Take a look at just this portion of your code and see if it still properly follows your algorithm. You may find an error which you could've located yourself with properly formatted code. If you take a look at a previous question of yours (which I answered) you'll find a helpful link that guides you to writing better code.
Also, I didn't try to compile this in my own IDE, but you should take a look at Eclipse. A lot of the small errors you're getting could be located automatically by Eclipse.

Prime numbers loop returning blank string

public String primeNumbers()
{
//create variable to be returned
String prime = "";
int num = 0;
for(int i = 0; i < this.limit; i++)
{
num = this.limit - i;
for(int count = 2; count < this.limit; count++)
{
if ( num % count == 0)
{
count = this.limit + 1;
}
else if ( num == count)
{
prime += num + ", ";
}
}
}
return prime;
}
The goal of this is to produce a list of prime numbers in between 1 and the upper limit which is the private variable limit. However, when I run the code, I get a blank message as a return. Why is this?
I don't quite understand the logic of your code, but having helper methods is good.
public String primeNumbers()
{
//create variable to be returned
String prime = "";
for(int i = 0; i < this.limit; i++)
{
if(this.isPrime(i)){
prime += i + ", ";
}
}
return prime;
}
private boolean isPrime(int number){
if(number <= 1){
return false;
} else if(number == 2){
return true;
}
for(int i = 2; i < number; i++){
if(number%i == 0){
return false;
}
}
return true;
}
The isPrime() is naive, and can definitely be optimized.
There was a question about this yesterday and I ended up writing this as a refresher for myself.
public class Erasthotenes
{
private int range;
private boolean[] nums;
public Erasthotenes(int range)
{
this.range = range;
nums = new boolean[range];
for(int i = 0; i < nums.length; ++i)
{
nums[i] = true;
}
nums[0] = nums[1] = false;
}
public void sieve()
{
int root = (int) Math.sqrt(range);
for(int i = 2; i < root; ++i)
{
for(int j = i + 1; j < range; ++j)
{
if(j % i == 0)
{
nums[j] = false;
}
}
}
}
public void printPrimes()
{
for(int i = 0; i < nums.length; ++i)
{
if(nums[i] == true)
{
System.out.print(i + ", ");
}
}
}
}
http://en.wikipedia.org/wiki/Sieve_of_Eratosthenes

Categories