I'm creating a battleship game where a ship occupies 3 cells and you have to guess which cell. Once they guess it you return "hit" and if not you return "miss". Once they hit all 3 you return "kill". I've written the code but it states I still haven't returned a string.
public class SimpleBattleShip{
int[] shipCoordinates;
int numOfHits;
String updateStatus(int guess){
for(int i=0;i<shipCoordinates.length;i++){
if(guess == shipCoordinates[i]){
numOfHits++;
if(numOfHits ==3){
return "kill";
}else{
return "hit";
}
}else{
return "miss";
}
}
}
}
Have you tried just separating the NumberofHits If statement from the for loop. The problem may be the for loop iterating the whole 'hit check' for each value of 'i' which may cause it to put up false values before tallying the full amount of hits.
I've tried throwing in an else if to maybe tighten the parameters. turn it back to else if you want (this is for hit & miss).
public class SimpleBattleShip {
int[] shipCoordinates;
int numOfHits;
String updateStatus(int guess) {
for (int i = 0; i < shipCoordinates.length; i++) {
if (guess == shipCoordinates[i]) {
numOfHits++;
}
}
if (numOfHits == 3) {
return "kill";
} else if (numOfHits < 3 && numOfHits >= 1) {
return "hit";
} else {
return "miss";
}
}
}
I am trying to solve a coding problem. The problem is following:
Given a sequence of integers as an array, determine whether it is possible to obtain a strictly increasing sequence by removing no more than one element from the array.
For example:
[1,3,2,1] is false
[1,3,2] is true
I implemented it in Java. The code is as follows:
boolean almostIncreasingSequence(int[] sequence) {
int count =0;
for(int i =0; i < sequence.length; i++){
if (sequence[i] <= sequence[i-1]){
count++;
}
if(count>1){
return false;
}
if(sequence[i] <= sequence[i-2] && sequence[i+1] <= sequence[i-1]){
return false;
}
}
return true;
}
This is the following error:
Execution error on test 1: Your program had a runtime error.
Any help will be appreciated. It seems a small problem but I can't resolve it.
One implementation can be based on remove just 1 element when strictly ascending condition is not achieved.
public class TestAlmostIncreasingSequence {
public static boolean almostIncreasingSequence(int[] sequence)
{
if(sequence==null) return false;
//mandatory to remove just 1 element, if no one(or more) removed then false
boolean flag_removed=false;
for(int i=1, prev=sequence[0];i<sequence.length;i++)
{
if(prev>=sequence[i] && flag_removed==false)
{
//mark removed
flag_removed=true;
}
//if element was removed then false
else if(prev>=sequence[i] && flag_removed==true)
{
return false;
}
else
{
//change only if element removed is not the current
//comparisons will not be done with removed element
prev=sequence[i];
}
//System.out.println(prev);
}
//could have a strictly increased arr by default which will return false [1,2,3]
return flag_removed;
}
public static void main(String[] args)
{
//only for printing purpose
String arr="";
int s1[] = {1,2,3,1};
arr=Arrays.stream(s1).mapToObj(t->String.valueOf(t)).
collect(Collectors.joining(",","[","]"));
System.out.println(arr+"\n"+almostIncreasingSequence(s1)+"\n");
int s2[] = {1,2,3};
arr=Arrays.stream(s2).mapToObj(t->String.valueOf(t)).
collect(Collectors.joining(",","[","]"));
System.out.println(arr+"\n"+almostIncreasingSequence(s2)+"\n");
int s3[] = {1,2,3,1,2};
arr=Arrays.stream(s3).mapToObj(t->String.valueOf(t)).
collect(Collectors.joining(",","[","]"));
System.out.println(arr+"\n"+almostIncreasingSequence(s3)+"\n");
int s4[] = {1};
arr=Arrays.stream(s4).mapToObj(t->String.valueOf(t)).
collect(Collectors.joining(",","[","]"));
System.out.println(arr+"\n"+almostIncreasingSequence(s4)+"\n");
int s5[] = {1,1};
arr=Arrays.stream(s5).mapToObj(t->String.valueOf(t)).
collect(Collectors.joining(",","[","]"));
System.out.println(arr+"\n"+almostIncreasingSequence(s5)+"\n");
int s6[] = null;
arr="null";
System.out.println(arr+"\n"+almostIncreasingSequence(s6)+"\n");
}
}
Output
[1,2,3,1]
true
[1,2,3]
false
[1,2,3,1,2]
false
[1]
false
[1,1]
true
null
false
Note: The implementation have a case when the result is wrong [1,5,2,3], just update with one more branch with removed element=the previous one(not the current) and check both branched (one true means true)
This should fix the case
//method name is misguided, removePrev is better
public static boolean removeCurrent(int[] sequence)
{
if(sequence==null) return false;
//mandatory to remove just 1 element, if no one remove then false
boolean flag_removed=false;
for(int i=1, prev=sequence[0];i<sequence.length;i++)
{
if(prev>=sequence[i] && flag_removed==false)
{
//mark removed
flag_removed=true;
}
//if element was removed then false
else if(prev>=sequence[i] && flag_removed==true)
{
return false;
}
//compared element will be the current one
prev=sequence[i];
//System.out.println(prev);
}
//could have a strictly increased arr by default which will return false [1,2,3]
return flag_removed;
}
and use
int s1[] = {1,5,2,3};
arr=Arrays.stream(s1).mapToObj(t->String.valueOf(t)).
collect(Collectors.joining(",","[","]"));
boolean result= (almostIncreasingSequence(s1)==false) ? removeCurrent(s1) : true;
System.out.println(arr+"\n"+result +"\n");
Output
[1,5,2,3]
true (from removeCurrent_branch)
Seems one more case is wrong [5,6,3,4], means need to see if element[i-2](only after remove element) is not greater then current and 'prev' on last branch.
6>3 remove 6 (prev=3, 3<4 but [5>4 or 5>3] so false)
public static boolean removeCurrent(int[] sequence)
{
if(sequence==null) return false;
//mandatory to remove just 1 element, if no one remove then false
boolean flag_removed=false;
for(int i=1, prev=sequence[0], twoprev=Integer.MIN_VALUE;i<sequence.length;i++)
{
if(prev>=sequence[i] && flag_removed==false)
{
//mark removed
flag_removed=true;
if(i>=2) twoprev=sequence[i-2];
}
//if element was removed then false
else if(prev>=sequence[i] && flag_removed==true)
{
return false;
}
else if(twoprev>=sequence[i] || twoprev>=prev)
{
return false;
}
//compared element will be the current one
prev=sequence[i];
//System.out.println(prev);
}
//could have a strictly increased arr by default which will return false [1,2,3]
return flag_removed;
}
Output
[5,6,3,4]
false
Now, as far as I see all cases seems covered.
Brute force can also generate a solution but will be less optimal.(use a loop to remove an element, sort the result and compare with base)
public class TestInc {
public static void main(String[] args)
{
int s1[] = {1,1,2,3};
System.out.println(checkInc(s1));
}
public static boolean checkInc(int[] arr)
{
if(arr==null || arr.length==1) return false;
List<Integer> lst = Arrays.stream(arr).boxed().collect(Collectors.toList());
//remove this check if requirement is other(or return true)
if(checkIfAlreadySortedAsc(lst))
{
return false;
}
for(int i=0;i<lst.size();i++)
{
List<Integer> auxLst = new ArrayList<Integer>(lst);
auxLst.remove(i);
List<Integer> sorted = new ArrayList<Integer>(auxLst);
sorted = sorted.stream().distinct().sorted().collect(Collectors.toList());
if(auxLst.equals(sorted))
{
// System.out.println("=");
return true;
}
else
{
// System.out.println("!=");
}
}
return false;
}
//any ascending sorted list will be the same type if remove one element
//but as requirement on this case will return false
//(or don't use method in want other)
public static boolean checkIfAlreadySortedAsc(List<Integer> lst)
{
List<Integer> auxLst = new ArrayList<Integer>(lst);
auxLst = auxLst.stream().distinct().sorted().collect(Collectors.toList());
if(auxLst.equals(lst))
{
return true;
}
return false;
}
}
Output
[1,1,2,3]
true
This line would produce an ArrayIndexOutOfBoundsException when i == 0 because it will attempt to access sequence[-1]
if (sequence[i] <= sequence[i-1]){
I am adding elements to an ArrayList and I have it designed to show an error whenever the user tries to add a preexisting element (same for when it tries to remove a nonexistent element). From what it is showing, it adds the new element but still says that the element matches one that is already in the ArrayList. What have I been overlooking? The ArrayList is created and manipulated in the FacebookUser.java class. Thanks (and I apologize in advance if it's a silly mistake).
DriverClass.java
public class DriverClass {
public static void main(String[] args) {
FacebookUser fu0 = new FacebookUser("Samuel", "password1");
FacebookUser fu1 = new FacebookUser("Michael", "password2");
FacebookUser fu2 = new FacebookUser("Amy", "password3");
FacebookUser fu3 = new FacebookUser("Eugene", "password4");
fu0.setPasswordHint("p1");
fu3.setPasswordHint("p4");
fu0.friend(fu1);
fu0.friend(fu2);
fu0.friend(fu3);
fu0.friend(fu3);
System.out.println(fu0.getFriends());
fu0.defriend(fu1);
fu0.defriend(fu1);
System.out.println(fu0.getFriends());
fu0.getPasswordHelp();
fu3.getPasswordHelp();
}
}
FacebookUser.java
import java.util.ArrayList;
public class FacebookUser extends UserAccount {
private String passwordHint;
private ArrayList<FacebookUser> friends = new ArrayList<FacebookUser>();
public FacebookUser(String username, String password) {
super(username, password);
friends = new ArrayList<FacebookUser>();
}
#Override
public void getPasswordHelp() {
System.out.println("Password Hint: " + passwordHint);
}
void setPasswordHint(String hint) {
passwordHint = hint;
}
void friend(FacebookUser newFriend) {
System.out.println(friends.size());
if (friends.size() == 0) {
friends.add(newFriend);
} else {
for (int i = 0; i < friends.size(); i++) {
if (friends.get(i).equals(newFriend)) {
System.out.println("That person is already in your friends list.");
break;
} else if (!friends.get(i).equals(newFriend) && i == friends.size() - 1) {
friends.add(newFriend);
}
}
}
}
void defriend(FacebookUser formerFriend) {
if (friends.size() == 0) {
System.out.println("That person is not in your friends list.");
} else {
for (int i = 0; i < friends.size(); i++) {
if (friends.get(i).equals(formerFriend)) {
friends.remove(i);
break;
} else if (!friends.get(i).equals(formerFriend) && i == friends.size() - 1) {
System.out.println("That person is not in your friends list.");
}
}
}
}
ArrayList<FacebookUser> getFriends() {
ArrayList<FacebookUser> friendsCopy = new ArrayList<FacebookUser>();
for (int i = 0; i < friends.size(); i++) {
friendsCopy.add(friends.get(i));
}
return friendsCopy;
}
}
UserAccount.java
public abstract class UserAccount {
private String username;
private String password;
private boolean active;
public UserAccount(String username, String password) {
this.username = username;
this.password = password;
active = true;
}
public boolean checkPassword(String password) {
if (password.equals(this.password)) {
return true;
} else {
return false;
}
}
public void deactivateAccount() {
active = false;
}
public String toString() {
return username;
}
public boolean checkActive() {
if (active == true) {
return true;
} else {
return false;
}
}
public abstract void getPasswordHelp();
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((username == null) ? 0 : username.hashCode());
return result;
}
#Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
UserAccount other = (UserAccount) obj;
if (username == null) {
if (other.username != null)
return false;
} else if (!username.equals(other.username))
return false;
return true;
}
}
Execution:
0
1
That person is already in your friends list.
2
That person is already in your friends list.
3
That person is already in your friends list.
[Michael, Amy, Eugene]
That person is not in your friends list.
[Amy, Eugene]
Password Hint: p1
Password Hint: p4
You're comparing against size() in your for loop, even though you are also potentially adding items to the list in the loop, so you end up comparing the item against itself on the last iteration.
for (int i = 0; i < friends.size(); i++) { // result of size() will change
if (friends.get(i).equals(newFriend)) {
System.out.println("That person is already in your friends list.");
break;
} else if (!friends.get(i).equals(newFriend) && i == friends.size() - 1) {
friends.add(newFriend);
}
}
You can just extract the result of calling size() so that it doesn't change when you add a new item. Or you could also break from the loop after adding the item.
Save size:
int size = friends.size();
for (int i = 0; i < size; i++) {
if (friends.get(i).equals(newFriend)) {
System.out.println("That person is already in your friends list.");
break;
} else if (!friends.get(i).equals(newFriend) && i == friends.size() - 1) {
friends.add(newFriend);
}
}
Or, probably better, use break once you've decided that you should add the item:
for (int i = 0; i < friends.size(); i++) {
if (friends.get(i).equals(newFriend)) {
System.out.println("That person is already in your friends list.");
break;
} else if (!friends.get(i).equals(newFriend) && i == friends.size() - 1) {
friends.add(newFriend);
break;
}
}
And then, an altogether better solution might be to avoid the loop and use contains instead:
void friend(FacebookUser newFriend) {
System.out.println(friends.size());
if (friends.contains(newFriend)) {
System.out.println("That person is already in your friends list.");
return;
}
friends.add(newFriend);
}
Your loop is wrong:
for (int i = 0; i < friends.size(); i++) {
if (friends.get(i).equals(newFriend)) {
System.out.println("That person is already in your friends list.");
break;
} else if (!friends.get(i).equals(newFriend) && i == friends.size() - 1 ) {
friends.add(newFriend);
}
}
You are iterating through the friends list, then you add it when you get to the end, then the friends list becomes one larger, so then you compare with the one you just added, and it says it is already there.
You want this:
boolean alreadyThere = false;
for (int i = 0; i < friends.size(); i++) {
if (friends.get(i).equals(newFriend)) {
System.out.println("That person is already in your friends list.");
alreadyThere = true;
break;
}
}
if(!alreadyThere) {
friends.add(newFriend);
}
More simply, it could be this:
if(friends.contains(newFriend)) {
System.out.println("That person is already in your friends list.");
} else {
friends.add(newFriend);
}
You are going in the right direction, but the iteration over the last added friend is the problem.
A quick fix could be breaking the loop after adding:
friends.add(newFriend);
break;
But it isn't a proper solution. We can use the contains in here:
if (friends.contains(newFriend)) {
System.out.println("That person is already in your friends list.");
return;
}
friends.add(newFriend);
When you add newFriend to the list, its size grows and so the loop execute one more time actually comparing newFriend to itself and so displaying the message.
The quick fix is to add a break; but this make things quite complex...
To me you could just write:
if (friends.contains(newFriend)) {
System.out.println("That person is already in your friends list.");
} else {
friends.add(newFriend)
}
without having to loop manually on the list elements.
But an even simpler solution would be to implement equals/hashCode for FacebookUser (required anyway for proper use of contains and finding the right friend) and use a Set of friends rather than a list. The Set structure always ensure there no duplicate and would perform much faster if there was to be many friends.
private Set<FacebookUser> friends = new HashSet<FacebookUser>();
[...]
if (!friends.add(newFriend)) {
System.out.println("That person is already in your friends list.");
}
well this is my array stack separated from my main
i have just one problem though, my code have no problems yet it lacks
something like if i run pop yet the stack is empty, it must have a dialog saying that it is empty, i tried an if else statement yet i dont know where to put it or is it really the if else statement needed, anyways here's my code. . .
public class ArrayStack {
int STACK_MAX = 20;
int size = -1 ;
int top = -1 ;
int StackObj[] = new int[STACK_MAX];
/**************** for PUSH METHOD *********/
public void Push(int obj) {
if (size()==STACK_MAX){
System.out.println("STACK is FULL");
}
else{
StackObj[++top]= obj;
}
}
/**************** for SIZE Method ********/
public int size() {
return (top+1);
}
/******************** for Display Method****/
public void DisplayStack() {
String disp="";
for (int i=top; i>=0; i--){
disp += StackObj[i] + "\n";
}
JOptionPane.showMessageDialog(null, "Elements of the Stacks : \n" + disp);
}
/***************** for isEmpty Method *******/
public boolean isEmpty(){
return (top == -1);
}
/***************** for Top Method ***********/
public int Topmethod(){
int taas = StackObj[top];
JOptionPane.showMessageDialog(null,"Top is : "+taas);
return (top);
}
/***************** for Pop Method ***********/
public int pop(){
int topItem = StackObj[top];
top--;
JOptionPane.showMessageDialog(null,"The recently pushed number was Deleted: "+topItem);
return(top);
}
}
You would want to add something in your pop method to handle recognizing when the stack was empty then handling the case of an empty stack such as:
public int pop(){
if(size() == 0){ //detect empty stack
JFrame frame = new JFrame("my frame");; //handle empty stack
JOptionPane.showMessageDialog(frame,"Stack is empty!");
return null; //make sure you handle a null return value if you use this
}
int topItem = StackObj[top];
top--;
JOptionPane.showMessageDialog(null,"The recently pushed number was Deleted: "+topItem);
return(top);
}
here i edited it
public int pop(){
if(size() == 0){ //detect empty stack
JOptionPane.showMessageDialog(null,"Stack is empty!");
return (top); //make sure you handle a null return value if you use this
}
int topItem = StackObj[top];
top--;
JOptionPane.showMessageDialog(null,"The recently pushed number was Deleted: "+topItem);
return(top);
}
I know i will get this exception when i try to modify or remove from the list, but just for reading from it ?! What is the solution here ?
public boolean recieveHello(Neighbor N, HelloMsg H) {
Iterator<Neighbor> I = NTable.iterator();
Iterator<Neighbor> J = NTable.iterator();
if(!J.hasNext()) {
this.NTable.add(N);
}
while(I.hasNext()) {
if(I.next().nid == N.getnid()) { /*EXCEPTION IS HERE*/
//case where the node is already present in the NTable
}
else {
N.setnhrc(0);
this.NTable.add(N);
//case where the node is to be added to the NTable
}
}
return true;
}
By the way, I must mention that NTable is an arrayList and is a member of the class whose method this is
EDIT
I solved the problem using ::
public boolean recieveHello(Neighbor N, HelloMsg H) {
Iterator<Neighbor> I = NTable.iterator();
Iterator<Neighbor> J = NTable.iterator();
if(!J.hasNext()) {
this.NTable.add(N);
}
boolean flag = false;
for (int i=0; i<NTable.size(); i++) {
if(NTable.get(i).nid == N.getnid()) {
//case where the node is already present in the NTable
}
else {
flag = true;
N.setnhrc(0);
this.NTable.add(N);
//case where the node is to be added to the NTable
}
}
if(flag == true) {
}
return true;
}
Well you're changing the size of the list while iterating over it when you say
this.NTable.add(N);
So, instead keep track of which ones to add in a separate list, then append the items after the first iteration.