Solution with CCC 2015? - java

I'm trying to #2 of the Canadian Computing Contest, but my solution doesn't work. It only reads the first few characters(the first three I believe) and just ends the loop, then proceeding to provide the adequate output based only on the first three characters.
Here is the past paper:http://cemc.uwaterloo.ca/contests/computing/2015/stage%201/juniorEn.pdf
My code
Scanner input = new Scanner(System.in);
String lines = input.next();
char[] line = lines.toCharArray();
int happy = 0;
int sad = 0;
int i = 0;
while(i < line.length)
{
if(line[i] == ':' && line[i+1] == '-')
{
if(line[i+2] == ')')
happy++;
else if(line[i+2] == '(')
sad++;
i+=3;
}
else i++;
}
if(happy == 0 && sad == 0)
System.out.print("none");
else if(happy == sad)
System.out.print("unsure");
else if(happy>sad)
System.out.print("happy");
else if (sad>happy)
System.out.print("sad");

consider that with
while(i < line.length)
if i == line.length - 1
then if you do
line[i+1]
you will exceeed the length or your array and get an OutOfBoundsException

Related

StringIndexOutofBoundsException Error when inputing an empty String Java [duplicate]

This question already has answers here:
Java charAt() String index out of range: 0
(5 answers)
How do I compare strings in Java?
(23 answers)
Closed 3 years ago.
Hi I keep getting this error whenever I try to input an empty String. Everything else so far works and if I put a space inside the String it works. I know this is really picky but I'm super curious what I should do in this situation to make sure it returns just an empty String.
**> HW2.nthWord(2,"")
java.lang.StringIndexOutOfBoundsException: String index out of range: 0
at java.lang.String.charAt(Unknown Source)
at HW2.nthWord(HW2.java:124)**
I did create a special instance for when this value is put in but it still does not work.
What do I need to to correct this?
/*nthWord takes an int and a String as input and returns a String:
The input int represents a number n that is assumed to be positive, and the output string
contains every nth word of the input string, starting with the first word, separated by a single space.
For this method, a word is defined to be a sequence of non-space characters.
There should be no space at the end of the output string.
*/
public static String nthWord( int number, String input ){
StringBuilder create = new StringBuilder();
int totalspaces = 0; //This is to hold a count of the number of spaces in a String
if( number == 0){
return input;
}
if(input == ""){
return input;
}
else{
for(int i = 0; input.charAt(i) != ' '; i = i + 1){
create.append(input.charAt(i));
}
for( int i = 0; i < input.length() - 1 ; i = i + 1){
if(input.charAt(i) == ' ' && i < input.length() - 1 && input.charAt(i+1) != ' '){
if( i != input.length()-1 && input.charAt(i+1) != ' '){
totalspaces = totalspaces + 1;
}
if(totalspaces % number == 0 && totalspaces != 0){
create.append(' ');
for(int j = i+1; input.charAt(j) != ' ' && j < input.length(); j = j+1){
create.append(input.charAt(j));
i = j;
}
}
}
}
return create.toString();
}
}
I noticed a few things
for(int i = 0; input.charAt(i) != ' '; i = i + 1){
create.append(input.charAt(i));
}
This loops will keep adding characters of "input" until it reaches a space' ' character. If input does not have a space character then this loop will go beyond the length of input and cause the error. You may want something like:
for(int i = 0; i < input.length(); i = i + 1){
if(input.charAt(i) == ' ' ){
break;
} else {
create.append(input.charAt(i));
}
}
Also, when you get to the line:
if(input.charAt(i) == ' ' && i < input.length() - 1 && input.charAt(i+1) != ' '){
you already know that i < input.length() - 1 because you are in a for loop. You may change that line to:
if(input.charAt(i) == ' ' && input.charAt(i+1) != ' '){
For the same reason, your next section:
if( i != input.length()-1 && input.charAt(i+1) != ' '){
totalspaces = totalspaces + 1;
}
can be changed to
if( i != input.length()-1 ){
totalspaces = totalspaces + 1;
}
Also, I noticed that you may be making the problem harder than it needs to be. The problem will be much easier if you solve it in a single for-loop.
for(int i = 0; i < input.length(); i = i + 1){
if( x ) //x is some code that determines if you are part of the nth word
create.append(input.charAt(i));
}

How can I make this faster, without making it multi-threaded?

My program is working fine, in terms of output, but for some of my test cases it takes too long to find an answer (sometimes taking 18 seconds). I would like to know how I can improve the performance of my code.
What my code does:
It's a take on Pebble Solitaire. The user inputs n number of games and after that inputs a strings of length 23 that contains a combinations of only 'o' (pebble) and '-' (empty space). If there are 2 adjacent pebbles and an empty space on either side, ie (oo- OR -oo), then you remove the middle pebble and you swap other two pieces with each other, ex 'oo-' will turn into '--o'.
My current approach is pretty much an exhaustive approach where it tries out every possible move and results the move set with the least number of pebbles left.
I would like to know how I can improve this solution without making it multi-threaded.
Here is what I have:
package Pebble;
import java.util.Scanner;
public class PebbleSolitaire {
public static void main(String[] args){
Scanner input = new Scanner(System.in);
int numOfGames = Integer.parseInt(input.nextLine());
while (numOfGames > 0){
char[] values = input.nextLine().toCharArray();
long startTime = System.nanoTime();
System.out.println(solve(values));
System.out.println("Time to finish in ms: " + (System.nanoTime() - startTime) / 1000000);
numOfGames--;
}
input.close();
}
private static int solve(char[] game){
if(game != null && game.length == 0){
return -1;
}
int result = 0;
for (int i = 0; i < game.length; i++){
if(game[i] == 'o'){
result++;
}
}
//print(game);
for (int i = 0; i < game.length; i++ ){
char[] temp = new char[game.length];
copyArray(temp, game);
if (i-2 >= 0 && temp[i] == '-' && temp[i-2] == 'o' && temp[i-1] == 'o'){//move pebble forwards
temp[i-1] = temp[i-2] = '-';
temp[i] = 'o';
result = Math.min(result, solve(temp));
}
copyArray(temp, game);
if(i+2 < temp.length && temp[i] == '-' && temp[i+1] == 'o' && temp[i+2] == 'o'){//move pebble backwards
temp[i+1] = temp[i+2] = '-';
temp[i] = 'o';
result = Math.min(result, solve(temp));
}
}
return result;
}
private static void copyArray(char[] copy, char[] og){
for(int x = 0; x < copy.length; x++){
copy[x] = og[x];
}
}
private static void print(char[] c){
for(char ch: c){
System.out.print(ch);
}
System.out.println();
}
}
My sample input and output:
2
-o----ooo----o----ooo--
6
Time to finish in ms: 0
oooooooooo-ooooooooooo-
4
Time to finish in ms: 18149
EDIT: Would making this completely iterative drastically improve the performance?
Maybe you can improve this parte:
for (int i = 0; i < game.length; i++ ){
char[] temp = new char[game.length];
copyArray(temp, game);
if (i-2 >= 0 && temp[i] == '-' && temp[i-2] == 'o' && temp[i-1] == 'o'){//move pebble forwards
temp[i-1] = temp[i-2] = '-';
temp[i] = 'o';
result = Math.min(result, solve(temp));
}
copyArray(temp, game);
if(i+2 < temp.length && temp[i] == '-' && temp[i+1] == 'o' && temp[i+2] == 'o'){//move pebble backwards
temp[i+1] = temp[i+2] = '-';
temp[i] = 'o';
result = Math.min(result, solve(temp));
}
}
to:
for (int i = 0; i < game.length; i++ ){
char[] temp = null;
if (i-2 >= 0 && game[i] == '-' && game[i-2] == 'o' && game[i-1] == 'o'){//move pebble forwards
temp = new char[game.length];
copyArray(temp, game);
temp[i-1] = temp[i-2] = '-';
temp[i] = 'o';
result = Math.min(result, solve(temp));
}
if(i+2 < game.length && game[i] == '-' && game[i+1] == 'o' && game[i+2] == 'o'){//move pebble backwards
if(temp == null) temp = new char[game.length];
copyArray(temp, game);
temp[i+1] = temp[i+2] = '-';
temp[i] = 'o';
result = Math.min(result, solve(temp));
}
}
Basically, only creating and "copyArray(temp, game);" when strictly necessary.

Entering an if statement

In this segment of code, from everything I'm seeing, it should be entering the for loop and then the if statement as long as you enter 1's and 0's, which is what I'm doing. It's not entering it, as I've seen from my print statements.
I don't see a reason why.
If it did enter the if statement, I also am unsure what to do because my suspicion is that it will only set true if the last bit is not a 1 or 0: my intention being for zeroesAndOnes to be false if anything except 1's and 0's are entered. However, as it stands, it's false all the time.
System.out.println("Please enter a 32 bit number consisting of "
+ "1's and 0's.");
String number = kb.nextLine();
int count = 0;
boolean zeroesAndOnes = false;
for(int i = 0; i < number.length(); i++){
if(number.charAt(i) == '0' || number.charAt(i) == '1'){
zeroesAndOnes = true;
System.out.println("If boolean " + zeroesAndOnes);
}
else{
zeroesAndOnes = false;
count++;
}
}
System.out.println("If boolean end " + zeroesAndOnes);
if(number.length() == 32 && count > 1){
if(number.charAt(0) + number.charAt(1) % 2 == 1){
symmDiff = 1;
}
else{
symmDiff = 0;
}
for(int i = 2; i < number.length(); i++){
if((symmDiff + number.charAt(i)) % 2 == 1){
symmDiff = 1;
}
else{
symmDiff = 0;
}
}
System.out.println("The parity bit for this number is " + symmDiff);
}
else{
System.out.println("These numbers do not match the specification.");
}
When checking for char equality, be sure the comparison is what you need. For instance
if(number.charAt(i) == 0)
checks for decimal value equality. To check for an actual '0' char, compare the char value
if ( number.charAt(i) == '0' )
for comparing a char you should use
if(number.chartAt(i) == '0')
another issue is number.charAt(0) will give you char not int. so when you are doing
number.charAt(0)+number.charAt(1) //you are concatenating character at index 0 and index 1
// do this
int first = Integer.parseInt(number.substring(0,1));
int second = Integer.parseInt(number.substring(1,2));
if( (first+second)%2 == 1){
// your statement
}

Binary to Decimal - java

I want to write a program which receive a string value and print the decimal number.
In addition, if the string value is not 1 or 0, I need to print a message.
I wrote this code but it is always getting inside the if command.
I Would appreciate your support!
Thank you
import java.util.Random;
public class Decimal {
public static void main(String[] args) {
String input = (args[0]);
int sum = 0;
for (int i = 0; i <= input.length(); i++) {
if (!(input.charAt(i) == '0') || (input.charAt(i) == '1')) {
System.out.println("wrong string");
break;
}
char a = input.charAt(i);
if (a == '1') {
sum |= 0x01;
}
sum <<= 1;
sum >>= 1;
System.out.println(sum);
}
}
}
The ! (not) operator of the if statement only applies to the first part:
if ( ! (input.charAt(i) == '0')
||
(input.charAt(i) == '1')
) {
So that is the same as:
if ((input.charAt(i) != '0') || (input.charAt(i) == '1')) {
When you actually meant to do:
if (input.charAt(i) != '0' && input.charAt(i) != '1') {
It's a good thing though, because once that works, you're going to get an IndexOutOfBoundsException when i == input.length(). Change the loop to:
for (int i = 0; i < input.length(); i++) {
And for performance, move variable a up and use it in that first if statement. Rename to c or ch is more descriptive/common.
Doing both sum <<= 1 and sum >>= 1 leaves you where you started. Is that what you wanted? You should also do the left-shift before setting the right-most bit.
Applying all that, I believe you meant to do this:
String input = args[0];
int sum = 0;
for (int i = 0; i < input.length(); i++) {
char c = input.charAt(i);
if (c != '0' && c != '1') {
System.out.println("wrong string");
break;
}
sum <<= 1;
if (c == '1')
sum |= 1;
}
System.out.println(sum);

Cant compare using If Statement in Java wild error Markers Undefined for Arguments?

Why does it tell me that I can't compare Ints? I am trying to compare this line here and it wont let me all I get is :
if (counter1 = 0 || counter2 = 0)
{
return false;
}
Here is the rest of my code for reference.
public static boolean checkPassword(String password){
int length;
length = password.length();
if (length < 6 || length > 11){
System.out.println("Password must be 6 - 10 characters long!");
return false;
}
int counter1 = 0;
for (int i = 0; i < password.length(); i++){
if (Character.isLetter(password.charAt(i)))
counter1++;
}
int counter2 = 0;
for (int i = 0; i < password.length(); i++){
if(Character.isDigit(password.charAt(i)))
counter2++;
}
if (counter1 = 0 || counter2 = 0)
{
return false;
}
return true;
}
I keep getting Markers Undefined help me :)
You are not using the equality test == but the assignment operator =. It is a very common beginners mistake.
if (counter1 == 0 || counter2 == 0) {
return false;
}
The statement counter1 = 0 is an assignment, so you're ultimately trying if (0 || 0) but the || operator expects booleans, not integers. Use == instead.
Because in Java = isn't used for comparison. You need to use == This should be
if (counter1 == 0 || counter2 == 0)
{
return false;
}

Categories