So, I've created a simple app for moving a bug along a wire. The code works well (for the most part) though, I am having a few issues.
When reaching the end of the wire, the program terminates all well and good but I'm getting a double output that it's fallen off the wire when it reaches the end.
I am supposed to be writing a toString for this, but am having a bit of a hard time grasping why and how I should go about doing this.
If someone could assist with this, I'd greatly appreciate it.
import java.util.Scanner;
public class ClassPracticeMain {
public static void main(String [] args) {
Scanner input = new Scanner(System.in);
int userInput;
Bug bug1 = new Bug();
bug1.setInitialPosition();
bug1.setInitialDirection();
System.out.println("Your starting position is " + bug1.initialPosition
+ " and you are facing " + bug1.getCurrentDirection()
);
while (bug1.getExit(1) != 0) {
System.out.println("Which way would you like to move? 1 for left/ 2 for right or 0 for exit");
userInput = input.nextInt();
bug1.move(userInput);
bug1.getCurrentDirection();
bug1.getCurrentPosition();
System.out.println("You are now at " + bug1.currentPosition + " and you are facing " + bug1.getCurrentDirection());
bug1.getExit(userInput);
}
}
}
public class Bug {
final int WIRELEFTEND=-15;
final int WIRERIGHTEND=15;
int initialPosition=0, currentPosition=0, direction,exit=1;
String currentDirection;
String left = "left";
String right = "right";
public int setInitialPosition(){
return initialPosition;
}
public int setInitialDirection(){
direction=1;
return direction;
}
public int getCurrentPosition(){
return currentPosition;
}
public String getCurrentDirection(){
if (direction== 1){
currentDirection=left;
} else if (direction == 2){
currentDirection=right;
}
return currentDirection;
}
public int move(int move){
if(move==1 && direction==1){
currentPosition=currentPosition-1;
return currentPosition;
} else if (move==1 && direction==2){
direction=1;
return currentPosition;
} else if (move==2 && direction==1){
direction=2;
return currentPosition;
} else if (move==2 && direction ==2){
currentPosition=currentPosition+1;
return currentPosition;
}
return 0;
}
public int getExit(int exit){
if(currentPosition<(WIRELEFTEND)||currentPosition>WIRERIGHTEND){
System.out.println("You've fallen off the wire... Oh no!");
exit=0;
} else{
exit=exit;
}
return 1;
}
}
You probably want to write
public int getExitStatus(){
if(currentPosition<(WIRELEFTEND)||currentPosition>WIRERIGHTEND){
System.out.println("You've fallen off the wire... Oh no!");
return 0;
}
return 1;
}
instead of your current getExist(int) function. It always returns 1, and setting the exit argument doesn't do anything.
Related
I was asked in an interview to write code to check if a given string is a palindrome or can be a palindrome by altering some character without using a library function. Here is my Approach
import java.util.Scanner;
public class Palindrom {
static int temp=0;
static char[] cArr;
static boolean chackPotentialPalindrom(char[] cAr){
cArr=cAr;
if(cArr!=null){
char current=cArr[0];
for(int i=1;i<cArr.length;i++){
if(current==cArr[i]){
cArr=removeElement(i);
chackPotentialPalindrom(cArr);
break;
}
}
if(cAr.length==2){
if(cAr[0]==cAr[1]){
cArr=null;
}}
if(temp==0 && cArr!=null){
temp=1;
cArr=removeFirstElement(cArr);
chackPotentialPalindrom(cArr);
}
}
if(cArr==null){
return true;
}else{
return false;
}
}
static char[] removeFirstElement(char[] cAr){
cArr=cAr;
if(cArr!=null){
if(cArr.length >1){
char[] cArrnew=new char[cArr.length-1];
for(int j=1,k=0;j<cArr.length;j++,k++){
cArrnew[k]=cArr[j];
}
return cArrnew;
} else {
return null;
}
} else {
return null;
}
}
static char[] removeElement(int i){
if(cArr.length>2){
char[] cArrnew=new char[cArr.length-2];
for(int j=1,k=0;j<cArr.length;j++,k++){
if(i!=j){
cArrnew[k]=cArr[j];
}else{
k-=1;
}
}
return cArrnew;}
else{
return null;
}
}
public static void main(String[] args) {
Scanner scn=new Scanner(System.in);
while(true){
temp=0;
String s=scn.next();
char[] arr=s.toCharArray();
System.out.println(chackPotentialPalindrom(arr));
}
}
}
Any tips to optimize this code?I could not write this in an interview as they have given a pen and paper to code.It took 3 hrs for me to write this. Can I be a developer?
Title says "without loop" but you need to check all symbol pairs, so using recursion, as you have tried, looks reasonable. But you don't check and use results of recursive calls.
Pseudocode might look like (note we don't need to change source data or extract substring):
Edit to provide possibility to alter one char
boolean checkPotentialPalindrom(char[] cAr, start, end, altcnt){
if (end <= start)
return true
if (cAr[start] != cAr[end])
altcnt = altcnt + 1
if (altcnt > 1)
return false
return checkPotentialPalindrom(cAr, start + 1, end - 1, altcnt)
}
and make the first call with arguments 0, len(cAr-1), 0
Answering to your first question..You have to use recursion to solve this problem. Here is my approach.
public boolean isPalindrom(char[] str, int start, int end) {
if (end <= start)
return true;
if (str[start] != str[end] || arraySize(str) <= 1)
return false;
return isPalindrom(str, start + 1, end - 1);
}
public int arraySize(char[] str) {
int count = 0;
for (char i : str) {
count++;
}
return count;
}
You have tried to implement this algorithm using loops and you can simplify it like this
public boolean isPalindroms(char[] str) {
int diffCount = 0;
int left = 0;
int right = arraySize(str) - 1;
while (right > left) {
if (str[right--] != str[left++]) {
diffCount++;
}
}
return (diffCount < 2);
}
public int arraySize(char[] str) {
int count = 0;
for (char i : str) {
count++;
}
return count;
}
The answer for the second question that you have ask is definitely you can be a good developer. Computer programming is a Craft. Not Some Kind of Rocket Science. You have to master it by crafting it.
using recursive function
calling with left=0 and right = arr.length-1
public static boolean isPalindrom(char[] arr, int left, int right){
if(arr[left++] != arr[right--])
return false;
if(left < right)
isPalindromss(arr, left++, right--);
return true;
}
if you have to use while loop, you can simplify it like following
public boolean isPalindrom(char[] arr){
int left=0;
int right = arr.length-1;
while(left < right){
if(arr[left++] == arr[right--])
continue;
return false;
}
return true;
}
Using StringBuilder, We can do it
public static boolean isPalindrom(String str, int len){
StringBuilder sb= new StringBuilder(str);
if((len > 1) & !(sb.substring(0,len/2 + 1).equals(sb.reverse().substring(0,len/2 + 1))))
return false;
return true;
}
function palin(input, leftIdx = 0, rightIdx = input.length - 1) {
if (leftIdx >= rightIdx) return true;
if (input[leftIdx] != input[rightIdx]) return false;
return palin(input, leftIdx + 1, rightIdx - 1);
}
const testCases = {
air: false,
airia: true,
caria: false,
a: true,
bb: true,
bcdb: false,
zzaaaaz: false,
};
Object.keys(testCases).forEach(test =>
console.log("Test: ", test, " is palindrome: ", palin(test), testCases[test])
);
I have two files one is the driver, I'm having a problem with setters. It looks did set the value .
public class Movie {
private String name;
private int minutes;
protected int tomatoScore;
public Movie(String name, int minutes, int tomatoScore)
{
this.name=name;
this.minutes=minutes;
this.tomatoScore=tomatoScore;
}
public String getName() {return name;}
public void setName(String name) {this.name=name;}
public int getMinutes() {return minutes;}
public boolean setMinutes(int minutes) {return minutes>=0;}
public int getTomatoScore() {return tomatoScore;};
public boolean setTomatoScore(int tomatoScore) {return tomatoScore>=0 &&tomatoScore<=100;};
public boolean isFresh() {return tomatoScore>=60;};
public void display()
{
//this.name = name;
//this.minutes = minutes;
//this.tomatoScore =tomatoScore;
System.out.println("Movie: "+ getName());
System.out.println("Length: "+ getMinutes() +"min.");
if(tomatoScore>=60)
{
System.out.println("TomatoScore: Fresh");
}
else
{
System.out.println("TomatoScore: Rotten");
}
}
}
and bellow is the driver file if you notice the setters did do the job that is supposed to do I believe the problem is movie class, if you run the driver to test the program you see if you set the value to the negative the if statement does not function properly.( setMinutes and setTomatoScore are wrong. They do not set the class fields at all)
public class MovieDriver {
public static void main (String [] args){
Movie[] myCollection = new Movie[5];
myCollection[0] = new Movie("Batman The Dark Knight", 152, 94);
myCollection[1] = new Movie("Guardians of the Galaxy", 125, 91);
myCollection[2] = new Movie("The GodFather", 178, 98);
myCollection[3] = new Movie("Suicide Squad", 137, 27);
myCollection[4] = new Movie("Get out", 104, 99);
//TODO
//Initialize the variable below and add it to myCollection at index 4.
//You can pick any movie you wish.
Movie yourMovie;
System.out.println("Here are all the movies in my collection of movies.\n");
for(int i = 0; i < myCollection.length; i++) {
if(myCollection[i] != null)
myCollection[i].display();
}
System.out.println("_______________________________________________");
System.out.println("\nHere are the Fresh movies.");
for(int i = 0; i < myCollection.length; i++) {
if(myCollection[i] != null && myCollection[i].isFresh()) {
System.out.println(myCollection[i].getName() + " is fresh.");
}
}
System.out.println();
System.out.println("Here are the Rotten movies.");
for(Movie movieTmp: myCollection){
if (movieTmp != null && !movieTmp.isFresh())
System.out.println(movieTmp.getName() + " is rotten.");
}
System.out.println("_______________________________________________\n");
Movie harryPotter = new Movie("Harry Potter and the Prisoner of Azkaban", 144, 91);
System.out.println("The movie " + harryPotter.getName() + " was created.\n");
System.out.println("Is " + harryPotter.getName() + " a long movie?");
if(harryPotter.getMinutes() > 120) {
System.out.println("Yes, it is a bit long.\n");
} else {
System.out.println("Nope, that isn't too bad.\n");
}
System.out.println("Can I set the minutes of " + harryPotter.getName() + " to a negative number?");
harryPotter.setMinutes(-5);
if(harryPotter.getMinutes() == -5) {
System.out.println("It worked. The runtime is -5 minutes.\n");
} else {
System.out.println("It did NOT work. Negative runtimes are not allowed.\n");
}
System.out.println("Can I set tomato score of " + harryPotter.getName() + " to a negative number?");
harryPotter.setTomatoScore(-100);
if(harryPotter.getTomatoScore() == -100) {
System.out.println("It worked. The score is -100. This movie is terrible according to the site.\n");
} else {
System.out.println("It did NOT work. Negative scores are not allowed.\n");
}
System.out.println("Can I set tomato score of " + harryPotter.getName() + " to a number greater than 100?");
harryPotter.setTomatoScore(101);
if(harryPotter.getTomatoScore() == 101) {
System.out.println("It worked. The score is 101. Best Harry Potter movie ever!\n");
} else {
System.out.println("It did NOT work. Still the best Harry Potter movie out all the movies though.\n");
}
}
}
Your setMinutes and setTomatoScore methods don't set anything, they just return a boolean. I assume you've forgotten to add this.tomatoScore = tomatoScore for example.
As rzwitserloot mentioned, setter function for minutes and tomatoScore are not setting any thing.This might be the case.
Additional I would like add, I found it is better to use well known IDE for java programming like intellij, netBean, eclipse. They have provide many feature like auto generate setter, getter , constructor. So we can focus more on core logic and this saves our time and reduce possiblity of manual error.
One more point I would like to add,
It is better to use setter in the constructor, so before setting value is we want to perform any input validation,we can have that in setter and can use that even when setting value via constructor.
For an example,
public class Example {
private int x;
public Movie(int x){setMinutes(x);}
public void setX(int x) {
//some validation on input
if(x >= 0){this.x = x;}
public int getX() {return x;}
Looks like you need this:
public boolean setMinutes(int minutes) {
if(minutes >= 0 && minutes < 60) {
//I'm guessing the <60 part here, but whatever,
//this is how you'd set the 100 limit on your setTomatoScore method
this.minutes = minutes;
return true;
}
return false;
}
Make similar corrections for the setTomatoScore
You need to set something tomatoScore in the state of methods as shown below :
public boolean setTomatoScore(int tomatoScore) {
if (tomatoScore >= 0 && tomatoScore <= 100) {
this.tomatoScore = tomatoScore;
return true;
}
return false;
}
I made a simple game(well not really a game yet) in which the player can move in a room 4x20 characters in size. It runs in console.
But in my game loop I want to be able to move around in the room without pressing enter every time I want to move. The player should be able to press w/a/s/d and have the screen update instantly, but I don't know how to do that.
public class Main{
public static void main(String[] args){
MovementLoop();
}
public static void MovementLoop(){
Scanner input = new Scanner(System.in);
int pos=10, linepos=2;
String keypressed;
boolean playing = true;
while(playing == true){
display dObj = new display(linepos, pos);
dObj.drawImage();
keypressed=input.nextLine();
if(keypressed.equals("w")){
linepos -= 1;
}
else if(keypressed.equals("s")){
linepos += 1;
}
else if(keypressed.equals("a")){
pos -= 1;
}
else if(keypressed.equals("d")){
pos += 1;
}
else if(keypressed.equals("q")){
System.out.println("You have quit the game.");
playing = false;
}
else{
System.out.println("\nplease use w a s d\n");
}
}
}
}
public class display{
private String lines[][] = new String[4][20];
private String hWalls = "+--------------------+";
private String vWalls = "|";
private int linepos, pos;
public display(int linepos1, int pos1){
pos = pos1 - 1;
linepos = linepos1 - 1;
}
public void drawImage(){
for(int x1=0;x1<lines.length;x1++){
for(int x2=0;x2<lines[x1].length;x2++){
lines[x1][x2]="#";
}
}
lines[linepos][pos]="O";
System.out.println(hWalls);
for(int x2=0;x2<lines.length;x2++){
System.out.print(vWalls);
for(int x3=0;x3<lines[x2].length;x3++){
System.out.print(lines[x2][x3]);
}
System.out.println(vWalls);
}
System.out.println(hWalls);
}
}
The answer is simple
You can't do that
Because command line environment is different from swing, as swing can do such a thing as it deals with events and object, whereas, command line have no events.
So, maybe it's a right time to leave command line.
In my program, I have a while loop that will display a list of shops and asks for an input, which corresponds with the shop ID. If the user enters an integer outside the array of shops, created with a Shop class, it will exit the loop and continue. Inside this loop is another while loop which calls the sellItem method of my Shop class below:
public Item sellItem()
{
displayItems();
int indexID = Shop.getInput();
if (indexID <= -1 || indexID >= wares.length)
{
System.out.println("Null"); // Testing purposes
return null;
}
else
{
return wares[indexID];
}
}
private void displayItems()
{
System.out.println("Name\t\t\t\tWeight\t\t\t\tPrice");
System.out.println("0. Return to Shops");
for(int i = 0; i < wares.length; i++)
{
System.out.print(i + 1 + ". ");
System.out.println(wares[i].getName() + "\t\t\t\t" + wares[i].getWeight() + "\t\t\t\t" + wares[i].getPrice());
}
}
private static int getInput()
{
Scanner scanInput = new Scanner(System.in);
int itemID = scanInput.nextInt();
int indexID = itemID - 1;
return indexID;
}
The while loop in my main class method is as follows:
boolean exitAllShops = true;
while(exitAllShops)
{
System.out.println("Where would you like to go?\nEnter the number which corresponds with the shop.\n1. Pete's Produce\n2. Moore's Meats\n3. Howards Hunting\n4. Foster's Farming\n5. Leighton's Liquor\n6. Carter's Clothing\n7. Hill's Household Products\n8. Lewis' Livery, Animals, and Wagon supplies\n9. Dr. Miller's Medicine\n10. Leave Shops (YOU WILL NOT BE ABLE TO RETURN)");
int shopInput = scan.nextInt();
if(shopInput >= 1 && shopInput <= allShops.length)
{
boolean leaveShop = true;
while(leaveShop)
{
allShops[shopInput - 1].sellItem();
if(allShops == null)
{
System.out.println("still null"); // Testing purposes
leaveShop = false;
}
}
}
else
{
System.out.println("Are you sure you want to leave?\n1. Yes\n2. No");
int confirm = scan.nextInt();
if(confirm == 1)
{
exitAllShops = false;
}
}
The problem is here:
boolean leaveShop = true;
while(leaveShop)
{
allShops[shopInput - 1].sellItem();
if(allShops == null)
{
System.out.println("still null"); // Testing purposes
leaveShop = false;
}
}
No matter what I do, I can't get "still null" to print to confirm that I'm correctly calling the return statement of the method sellItem of the class Shop. What am I doing wrong?
After calling allShops[...].sellItem(), allShops is still a valid array reference -- there's no way it could be null! You probably want to test the return value from sellItem:
if(allShops[shopInput-1].sellItem() == null)
I've had this problem throughout multiple programs, but I can't remember how I fixed it last time. In the second while loop in my body, the second sentinel value is never read in for some reason. I've been trying to fix it for a while now, thought I might see if anyone had any clue.
import java.text.DecimalFormat; // imports the decimal format
public class Car {
// Makes three instance variables.
private String make;
private int year;
private double price;
// Makes the an object that formats doubles.
public static DecimalFormat twoDecPl = new DecimalFormat("$0.00");
// Constructor that assigns the instance variables
// to the values that the user made.
public Car(String carMake,int carYear, double carPrice)
{
make = carMake;
year = carYear;
price = carPrice;
}
// Retrieves variable make.
public String getMake()
{
return make;
}
// Retrieves variable year.
public int getYear()
{
return year;
}
// Retrieves variable price.
public double getPrice()
{
return price;
}
// Checks if two objects are equal.
public boolean equals(Car c1, Car c2)
{
boolean b = false;
if(c1.getMake().equals(c2.getMake()) && c1.getPrice() == c2.getPrice() &&
c1.getYear() == c2.getYear())
{
b = true;
return b;
}
else
{
return b;
}
}
// Turns the object into a readable string.
public String toString()
{
return "Description of car:" +
"\n Make : " + make +
"\n Year : " + year +
"\n Price: " + twoDecPl.format(price);
}
}
import java.util.Scanner; // imports a scanner
public class CarSearch {
public static void main(String[] args)
{
// initializes all variables
Scanner scan = new Scanner(System.in);
final int SIZE_ARR = 30;
Car[] carArr = new Car[SIZE_ARR];
final String SENT = "EndDatabase";
String carMake = "";
int carYear = 0;
double carPrice = 0;
int count = 0;
int pos = 0;
final String SECSENT = "EndSearchKeys";
final boolean DEBUG_SW = true;
// Loop that goes through the first list of values.
// It then stores the values in an array, then uses the
// values to make an object.
while(scan.hasNext())
{
if(scan.hasNext())
{
carMake = scan.next();
}
else
{
System.out.println("ERROR - not a String");
System.exit(0);
}
if(carMake.equals(SENT))
{
break;
}
if(scan.hasNextInt())
{
carYear = scan.nextInt();
}
else
{
System.out.println("ERROR - not an int" + count);
System.exit(0);
}
if(scan.hasNextDouble())
{
carPrice = scan.nextDouble();
}
else
{
System.out.println("ERROR - not a double");
System.exit(0);
}
Car car1 = new Car(carMake, carYear, carPrice);
carArr[count] = car1;
count++;
}
// Calls the method debugSwitch to show the debug information.
debugSwitch(carArr, DEBUG_SW, count);
// Calls the method printData to print the database.
printData(carArr, count);
// Loops through the second group of values and stores them in key.
// Then, it searches for a match in the database.
**while(scan.hasNext())**
{
if(scan.hasNext())
{
carMake = scan.next();
}
else
{
System.out.println("ERROR - not a String");
System.exit(0);
}
if(carMake.equals(SECSENT))
{
break;
}
if(scan.hasNextInt())
{
carYear = scan.nextInt();
}
else
{
System.out.println("ERROR - not an int" + count);
System.exit(0);
}
if(scan.hasNextDouble())
{
carPrice = scan.nextDouble();
}
else
{
System.out.println("ERROR - not a double");
System.exit(0);
}
Car key = new Car(carMake, carYear, carPrice);
// Stores the output of seqSearch in pos.
// If the debug switch is on, then it prints these statements.
if(DEBUG_SW == true)
{
System.out.println("Search, make = " + key.getMake());
System.out.println("Search, year = " + key.getYear());
System.out.println("Search, price = " + key.getPrice());
}
System.out.println("key =");
System.out.println(key);
pos = seqSearch(carArr, count, key);
if(pos != -1)
{
System.out.println("This vehicle was found at index = " + pos);
}
else
{
System.out.println("This vehicle was not found in the database.");
}
}
}
// This method prints the database of cars.
private static void printData(Car[] carArr, int count)
{
for(int i = 0; i < count; i++)
{
System.out.println("Description of car:");
System.out.println(carArr[i]);
}
}
// Searches for a match in the database.
private static int seqSearch(Car[] carArr, int count, Car key)
{
for(int i = 0; i < count; i++)
{
boolean b = key.equals(key, carArr[i]);
if(b == true)
{
return i;
}
}
return -1;
}
// Prints debug statements if DEBUG_SW is set to true.
public static void debugSwitch(Car[] carArr, boolean DEBUG_SW, int count)
{
if(DEBUG_SW == true)
{
for(int i = 0; i < count; i++)
{
System.out.println("DB make = " + carArr[i].getMake());
System.out.println("DB year = " + carArr[i].getYear());
System.out.println("DB price = " + carArr[i].getPrice());
}
}
}
}
I think this is your problem, but I might be wrong:
Inside your while loop, you have these calls:
next()
nextInt()
nextDouble()
The problem is that the last call (nextDouble), will not eat the newline. So to fix this issue, you should add an extra nextLine() call at the end of the two loops.
What happens is that the next time you call next(), it will return the newline, instead of the CarMake-thing.