So my NumberOperations class can't be found? - java

Here's the code (number operations class is the second listed):
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
// declare and instantiate ArrayList with generic type <NumberOperations>
ArrayList<NumberOperations> numOpsList
= new ArrayList<NumberOperations>();
// prompt user for set of numbers
System.out.println("Enter a list of positive integers separated "
+ "with a space followed by 0:");
// get first user input using in.nextInt()
int number = in.nextInt();
// add a while loop as described below:
// while the input is not equal to 0
// add a new NumberOperations object to numOpsList based on user
input
// get the next user input using in.nextInt()
while (number != 0) {
numOpsList.add(new NumberOperations(number));
number = in.nextInt();
}
int index = 0;
while (index < numOpsList.size()) {
NumberOperations num = numOpsList.get(index);
System.out.println("For: " + num);
// add print statement for odds under num
// add print statement for powers of 2 under num
index++;
}
public class NumberOperations {
// instance variables
private int number;
// constructor
/**
* #param numberIn is number
*/
public NumberOperations (int numberIn) {
number = numberIn;
}
// methods
/**
* #return value
*/
public int getValue()
{
return number;
}
public String oddsUnder()
{
String output = "";
int i = 0;
while (i < number) {
if(i % 2 != 0) {
output += i + "\t";
}
i++;
}
return output;
}
public String powersTwoUnder()
{
String output = "";
int powers = 1;
while (powers < number) {
output += powers + "\t";
powers = powers * 2;
}
return output;
}
public int isGreater (int compareNumber)
{
if (number > compareNumber)
{
return 1;
}
else if (number < compareNumber)
{
return -1;
}
else
{
return 0;
}
}
public String toString()
{
String output = "";
return number + "";
}
}
The error I'm getting is that the compiler can't find "NumberOperations" anywhere. Its probably a very rudimentary issue I have, but I'm lost.
Edit: I added the class for numberoperations in case it helps. I thought I did everything right as far as this goes though.

Enter a list of positive integers separated with a space followed by 0:
1 2 3 4 0
For: 1
For: 2
For: 3
For: 4
I decorated the main method with a class
import java.util.*;
public class NumberOperationsTest {
yes, import was left to the helping User, too.
Closed the class just before the class NumberOperations, which I freed from the public declaration, to have it compilable in a single file.
In a different file, the public keyword is fine.
On compilation, you have to tell the classpath, to look in the current directory:
javac -cp . NumberOperationsTest.java

Related

Implementation of Radix sort in Java using Nodes instead of integers

I have a final project for my Data Structures class that I can't figure out how to do. I need to implement Radix sort and I understand the concept for the most part. But all the implementations I found online so far are using it strictly with integers and I need to use it with the other Type that I have created called Note which is a string with ID parameter.
Here is what I have so far but unfortunately it does not pass any JUnit test.
package edu.drew.note;
public class RadixSort implements SortInterface {
public static void Radix(Note[] note){
// Largest place for a 32-bit int is the 1 billion's place
for(int place=1; place <= 1000000000; place *= 10){
// Use counting sort at each digit's place
note = countingSort(note, place);
}
//return note;
}
private static Note[] countingSort(Note[] note, long place){ //Where the sorting actually happens
Note[] output = new Note[note.length]; //Creating a new note that would be our output.
int[] count = new int[10]; //Creating a counter
for(int i=0; i < note.length; i++){ //For loop that calculates
int digit = getDigit(note[i].getID(), place);
count[digit] += 1;
}
for(int i=1; i < count.length; i++){
count[i] += count[i-1];
}
for(int i = note.length-1; i >= 0; i--){
int digit = getDigit((note[i].getID()), place);
output[count[digit]-1] = note[i];
count[digit]--;
}
return output;
}
private static int getDigit(long value, long digitPlace){ //Takes value of Note[i] and i. Returns digit.
return (int) ((value/digitPlace ) % 10);
}
public Note[] sort(Note[] s) { //
Radix(s);
return s;
}
//Main Method
public static void main(String[] args) {
// make an array of notes
Note q = new Note(" ", " ");
Note n = new Note("CSCI 230 Project Plan",
"Each person will number their top 5 choices.\n" +
"By next week, Dr. Hill will assign which piece\n" +
"everyone will work on.\n");
n.tag("CSCI 230");
n.tag("final project");
Note[] Note = {q,n};
//print out not id's
System.out.println(Note + " Worked");
//call radix
Radix(Note);
System.out.println(Note);
//print out note_id's
}
}
Instead of
public Note[] sort(Note[] s) { //
Radix(s);
return s;
}
I should have used
public Note[] sort(Note[] s) { //
s = Radix(s);
return s;
}
and change the variable type of Radix from void to Note[].

IndexOutOfBoundsException error adding long numbers

I am trying to wrtie java application that adds up to 5 long numbers using LinkedLists. At the end of the run I get this:
Exception in thread "main" java.lang.IndexOutOfBoundsException: Index:
0, Size: 0
at java.util.LinkedList.checkElementIndex(LinkedList.java:555) at java.util.LinkedList.remove(LinkedList.java:525) at
Assignment1.LongNumbers.remove(LongNumbers.java:33) at
Assignment1.LongNumbers.main(LongNumbers.java:92)
Here is the code:
import java.util.*;
/**
*
* #author .....
*/
public class LongNumbers
{
private List<Integer> [] theLists;
public LongNumbers() {
this.theLists = new LinkedList[6];
for (int i=0; i<6; i++)
this.theLists[i]= new LinkedList<>();
}
public void add(int location, int digit) {
//add digit at head of LinkedList given by location
theLists[location].add(digit);
}
public int remove(int location) {
//remove a digit from LinkedList given by location
return theLists[location].remove(location); //LongNumbers.java:33
}
public boolean isEmpty(int location) {
//check for an empty LinkedList given by location
return theLists[location].isEmpty();
}
public static void main(String[] args) {
Scanner stdIn = new Scanner(System.in);
//Local Variables
int digit;
int carry = 0;
int numberAt = 0;
int largestNumLength = 0;
char[] digits;
String number;
boolean userWantstoQuit = false;
LongNumbers Lists = new LongNumbers();
System.out.println("The program will enter up to 5 numbers and add them up.");
System.out.println();
while(!userWantstoQuit && numberAt != 5){
System.out.print("Enter a number, enter -1 to quit entry phase: ");
number = stdIn.nextLine();
if((number.compareTo("-1")) == 0)
userWantstoQuit = true;
else{
digits = new char[number.length()];
for(int i=0;i<number.length();i++)
digits[i] = number.charAt(i);
for(int i=0;i<number.length();i++){
int tempValue = digits[i] - 48;
try{
Lists.add(numberAt, tempValue);
}
catch(NumberFormatException nfe){
System.out.println("Invalid Input. Please try again.");
break;
}
if(i == (number.length() - 1))
numberAt++;
if(number.length() > largestNumLength)
largestNumLength = number.length();
}
}
}
for(int j=0;j<largestNumLength;j++){
int tempDigit = 0;
int index = 0;
while(index < numberAt){
if(Lists.theLists[index].get(0) != null){
tempDigit += Lists.theLists[index].get(0);
Lists.remove(0); //LongNumbers.java:99
}
index++;
}
digit = carry + tempDigit;
if(j < numberAt){
carry = digit/10;
digit = digit%10;
}
Lists.add(5, digit);
}
System.out.print("The sum of the numbers is: ");
for(int i=0;i<Lists.theLists[5].size();i++){
System.out.print(Lists.theLists[5].get(i));
}
System.out.println();
System.out.println();
System.out.println();
}//end main
}//end class
For starters, I don't think you can have an array of List<E> objects...
You should also make sure your list is initialized and has an item at the given location.
So your method might look something like this:
public int remove(int location)
{
if(theLists != null)
if(theLists.size() > location)
return theLists.remove(location);
return 0;
}
If you need 2 dimensions of lists, you could try using List<List<E>>
Treat all E as Integer.
Look at the code here:
while(index < numberAt){
if(Lists.theLists[index].get(0) != null){
tempDigit += Lists.theLists[index].get(0);
Lists.remove(0); //LongNumbers.java:99
}
index++;
}
You are checking whether the first element of the index'th list is not null. If that is true, you are adding it and call the remove method. However, what if you already processed the first list and index'th value is 1? In that case theLists[1].get(0) != null is true, but Lists.remove(0) passes 0 as location. Take a look at this code:
public int remove(int location) {
//remove a digit from LinkedList given by location
return theLists[location].remove(location); //LongNumbers.java:33
}
In the scenario I have described, location is 0. But your 0'th list is already empty...
EDIT: Rewrite the remove method, like this:
public int remove(int location, int index) {
//remove a digit from LinkedList given by location
return theLists[index].remove(location); //LongNumbers.java:33
}
And whenever you call this method, pass the index of the list to work with. Example:
while(index < numberAt){
if(Lists.theLists[index].get(0) != null){
tempDigit += Lists.theLists[index].get(0);
Lists.remove(0, index); //LongNumbers.java:99
}
index++;
}
Finally: In the future, please, structure your code, it was a real pain to read it in this, unstructured state, read about how to code.

Recursive method return values in asterisks

I'm trying to create a recursive method that returns a value, and prints the value in my main method. I'm confused on how to return and print in main() a row of X asterisks (**..)
X being a integer on the commandline.
For example the commandline argument is 5.
It should output to: *****
My code so far:
public static void main(String[] commandlineArguments){
if(commandlineArguments.length == 0){
System.out.println("Please enter a least one commandline!");
}
else{
Integer number = new Integer(0); //initialize number
try{
Integer x = Integer.parseInt(commandlineArguments[0]);
}
catch(NumberFormatException exception){ //NumberFormatException
System.out.println(exception+" is not a integer!");
System.exit(1); //end program
}
Integer num1 = recursiveMethods.asterisks(number); //A (return address)
System.out.println(num1);
}
}
public static Integer asterisks(Integer number){
String asterisks1 = "*";
for(int i = 0; i < number; i++){
return i;
}
return number;
}
}
A recursive method have two characteristics:
It calls to itself to provide the solution
It has a base case that contains where the recursive call must stop.
Your asterisks method does not fulfill any of these. Since this looks like homework, I would only provide an explanation about how this method should be, the implementation will be yours:
Since your method needs to return asterisks, it would be better returning a String instead of an Integer. This String will contain all the *s needed.
Define a base case. This can be where number have a value of 1.
If number is greater than 1, then you should return an asterisk and the result of calling to asterisks method using the rest of asterisks the whole result needs.
The problem is here:
for(int i = 0; i < number; i++){
return i;
}
This loop will only run one time, and it will immediately return i = 0. You don't want that. Make it append a * to your asterisks1 variable each iteration, then after the loop is finished, return asterisks1 to the caller and print it.
Also, just FYI, this method is not recursive. A recursive method by definition calls itself at some point.
You probably want to call the asterisk function recursively, and return the built up String of asterisks, something like this:
public static void main(String[] commandlineArguments) {
if (commandlineArguments.length == 0) {
System.out.println("Please enter a least one commandline!");
} else {
Integer number = new Integer(0); // initialize number
try {
number = Integer.parseInt(commandlineArguments[0]);
} catch (NumberFormatException exception) { // NumberFormatException
System.out.println(exception + " is not a integer!");
System.exit(1); // end program
}
String asterisk = asterisks(number); // A (return address)
System.out.println(asterisk);
}
}
public static String asterisks(Integer number) {
if (number == 0) {
return "";
} else {
return "*" + asterisks(number - 1);
}
}
to do it recursively you must call itself in itself. for example :
public static void main(String[] commandlineArguments){
if(commandlineArguments.length == 0){
System.out.println("Please enter a least one commandline!");
}
else{
Integer number = new Integer(0); //initialize number
try{
Integer x = Integer.parseInt(commandlineArguments[0]);
}
catch(NumberFormatException exception){ //NumberFormatException
System.out.println(exception+" is not a integer!");
System.exit(1); //end program
}
recursiveMethods.asterisks(number); //A (return address)
}
}
public static void asterisks(Integer number) {
if(number == 0)
return;
else {
System.out.print("*");
asterisks(number - 1);
}
}
}
Can be done as,
public static String asterisks(int n){
return (n==1)?"*":asterisks(n-1)+"*";
}
Note : return Type is String
EDIT: For n <= 0 it prints nothing
public static String asterisks(int n){
return (n<=0)?"":asterisks(n-1)+"*";
}

Loop in Credit Card Validation in java

I am a high school student in an introductory Computer Science course. Our assignment was the following:
The last digit of a credit card number is the check digit, which protects against transcription errors such as an error in a single digit or switching two digits. the following method is used to verify actual credit card numbers but, for simplicity, we will describe it for numbers with 8 digits instead of 16:
Starting from the rightmost digit, form the sum of every other digit. For example, if the credit card number is 4358 9795, then you form the sum 5+7+8+3 = 23.
Double each of the digits that were not included in the preceding step. Add all the digits of the resulting numbers. For example, with the numbers given above, doubling the digits, starting with the next-to-last one, yields 18 18 10 8. Adding all the digits in these values yields 1+8+1+8+1+0+8=27.
Add the sums of the two preceding steps. If the last digit of the result is 0, the number is valid. In our case, 23 + 27 = 50, so the number is valid.
Write a program that implements this algorithm. The user should supply an 8-digit number, and you should print out whether the number is valid or not. If it is not valid, you should print out the value of the check digit that would make the number valid.
I have everything done except for the part in bold. My code is listed below:
public class CreditCard
{
private String creditCardNumber;
private boolean valid;
private int checkDigit;
int totalSum;
/**
* Constructor for objects of class CreditCard
*/
public CreditCard(String pCreditCardNumber)
{
creditCardNumber = pCreditCardNumber;
checkDigit = Integer.parseInt(pCreditCardNumber.substring(creditCardNumber.length() - 1));
int sumOfDigits = checkDigit + Integer.parseInt(pCreditCardNumber.substring(6,7)) + Integer.parseInt(pCreditCardNumber.substring(3,4)) + Integer.parseInt(pCreditCardNumber.substring(1,2));
int dig7 = Integer.parseInt(pCreditCardNumber.substring(7,8));
int dig5 = Integer.parseInt(pCreditCardNumber.substring(5,6));
int dig3 = Integer.parseInt(pCreditCardNumber.substring(2,3));
int dig1 = Integer.parseInt(pCreditCardNumber.substring(0,1));
String string7 = Integer.toString(dig7);
int doubledDig7a = Integer.parseInt(string7.substring(0));
int doubledDig7b = 0;
if (dig7 * 2 >= 10)
{
doubledDig7a = Integer.parseInt(string7.substring(0));
doubledDig7b = 0;
}
String string5 = Integer.toString(dig5);
int doubledDig5a = Integer.parseInt(string7.substring(0));
int doubledDig5b = 0;
if (dig5 * 2 >= 10)
{
doubledDig5a = Integer.parseInt(string5.substring(0));
doubledDig5b = 0;
}
String string3 = Integer.toString(dig3);
int doubledDig3a = Integer.parseInt(string3.substring(0));
int doubledDig3b = 0;
if (dig3 * 2 >= 10)
{
doubledDig3a = Integer.parseInt(string3.substring(0));
doubledDig3b = 0;
}
String string1 = Integer.toString(dig1);
int doubledDig1a = Integer.parseInt(string1.substring(0));
int doubledDig1b = 0;
if (dig1 * 2 >= 10)
{
doubledDig1a = Integer.parseInt(string1.substring(0));
doubledDig1b = 0;
}
int doubleDigits = doubledDig1a + doubledDig1b + doubledDig3a + doubledDig3b + doubledDig5a + doubledDig5b + doubledDig7a + doubledDig7b;
totalSum = sumOfDigits + doubleDigits;
if (totalSum % 10 == 0)
{
valid = true;
}
else
{
valid = false;
}
}
public void makeItValid()
{
while (totalSum % 10 != 0)
{
checkDigit--;
if (totalSum % 10 == 0)
{
break;
}
}
}
public boolean isItValid()
{
return valid;
}
}
The loop is what I am having issues with. I always end up in an infinite loop whenever it compiles. It looks like everything should work, though. It's supposed to decrease the value of the check Digit (not increase so I don't end up with a check digit of 10 or higher), and then add that number back into the total sum until the total sum is divisible by 10, and then the loop would end. Is the type of loop I'm using wrong? Any advice would be appreciated.
Your problem is that both of your loop conditions involve totalSum but you only change checkDigit.
while (totalSum % 10 != 0)
{
checkDigit--;
if (totalSum % 10 == 0)
{
break;
}
}
You either need to recalculate totalSum or change the condition to be based on checkDigit. If you want to loop and decrement like you are doing you will need to add a method that performs the algorithm and call it every time. The way you have your class outlined makes this very inconvenient because you don't convert the numbers.
public static int[] cardToNumbers(String cardText) {
// \D is regex for non-digits
cardText = cardText.replaceAll("\\D", "");
int[] cardNumbers = new int[cardText.length()];
// convert unicode to corresponding integers
for (int i = 0; i < cardText.length(); i++)
cardNumbers[i] = cardText.charAt(i) - '0';
return cardNumbers;
}
public static int calcTotalSum(int[] cardNumbers) {
int sum = 0;
/* "every other one" loops
*
* I recommend against the "mod 2 index" scheme
* i % 2 relies on the card number being even
* you can't have your code blow up with unusual inputs
*
*/
for (int i = cardNumbers.length - 1; i >= 0; i -= 2) {
sum += cardNumbers[i];
}
for (int i = cardNumbers.length - 2; i >= 0; i -= 2) {
int dig = cardNumbers[i] * 2;
while (dig > 0) {
sum += dig % 10;
dig /= 10;
}
}
return sum;
}
Now you can do something like:
public void makeItValid() {
int[] invalidNumbers = cardToNumbers(creditCardNumber);
int sum = calcTotalSum(invalidNumbers);
while ((sum = calcTotalSum(invalidNumbers)) % 10 != 0)
invalidNumbers[invalidNumbers.length - 1]--;
totalSum = sum;
checkDigit = invalidNumbers[invalidNumbers.length - 1];
}
But you should be able to just subtract the difference to find the valid check digit:
if (totalSum % 10 != 0) checkDigit -= totalSum % 10;
Or something like:
public void makeItValid() {
int[] invalidNumbers = cardToNumbers(creditCardNumber);
checkDigit = invalidNumbers[invalidNumbers.length - 1] -= totalSum % 10;
totalSum = calcTotalSum(invalidNumbers);
valid = true;
}
Some asides,
I would recommend storing the digits as a field and have checkDigit represent an index in the array. This would simplify some of the operations you are doing.
I would also suggest not to be "silently" changing fields internally IE like in your makeItValid method unless this is a specification of the assignment. I think a better form is to let the "owning" code make the changes itself which is more clear externally. A somewhat complete implementation would look like this:
public class CreditCard {
public static void main(String[] args) {
if (args.length == 0) return;
CreditCard card = new CreditCard(args[0]);
if (!card.isValidNumber()) {
card.setCheckDigit(card.getValidCheckDigit());
}
}
private final String cardText;
private final int[] cardDigits;
private final int cdIndex;
public CreditCard(String ct) {
cardDigits = cardToNumbers(cardText = ct);
if ((cdIndex = cardDigits.length - 1) < 0) {
throw new IllegalArgumentException("# had no digits");
}
}
public boolean isValidNumber() {
return calcTotalSum(cardDigits) % 10 == 0;
}
public void setCheckDigit(int dig) {
cardDigits[cdIndex] = dig;
}
public int getValidCheckDigit() {
int sum = calcTotalSum(cardDigits);
if (sum % 10 != 0) {
return cardNumbers[cdIndex] - sum % 10;
} else {
return cardNumbers[cdIndex];
}
}
// above static methods
}
The best form IMO would be to disallow creation of a credit card object at all unless the check digit is valid. As an OOP principle it should not make sense to create invalid credit cards. The constructor should throw an exception if the card is invalid and have a static method to correct the number.
I would do something like the following (shortened):
public class CreditCard {
public CreditCard(String number) {
if (!validateCheckDigit(number)) {
throw new IllegalArgumentException("check digit failure");
}
}
}
public static void main(String[] args) {
String number = args[0];
CreditCard card = null;
boolean valid = false;
do {
try {
card = new CreditCard(number);
valid = true;
} catch (IllegalArgumentException e) {
number = CreditCard.correctCheckDigit(number);
}
} while (!valid);
}
I guess that's more or less doing your homework for you but I'm sure you can learn from it.
Unless I'm missing something major on how the validation works your makeitvalid method wont work in the way you are approaching it.
It makes more sense (at least to me) to extract everything you have in your constructor into a method ie.
boolean isValid(String cardNumber);
which would do everything that your constructor does except set the valid flag. your constructor then becomes
public CreditCard(String pCreditCardNumber){
valid = isValid(pCreditCardNumber);
}
and then to find what change would make it valid your check valid method does something like
change the value of check digit
if (isValid(Changed String))
return checkdigit
else
continue
repeat until you either find one that works or until you determine that it can't work.
Something along these lines should do. You'll still need to implement a few methods on your own.
public static void main(String[] args) {
String creditCardNumber = readCreditCardNumber();
String correctCreditCardNumber = getCorrectCreditCardNumber(creditCardNumber);
if (creditCardNumber.equals(correctCreditCardNumber)) {
System.out.println("Credit Card Valid");
} else {
System.out.println("Credit Card Invalid. Did you mean " + correctCreditCardNumber + "?");
}
}
public static String getCorrectCreditCardNumber(String creditCardNumber) {
int[] creditCardDigits = getCreditCardDigits(creditCardNumber);
int sum = 0;
for (int i = creditCardDigits.length - 2; i >= 0; i--) {
if (isOdd(i)) {
sum += creditCardDigits[i];
} else {
sum += digitSum(creditCardDigits[i] * 2);
}
}
int last = creditCardDigits.length - 1;
int remainder = sum % 10;
if (remainder != 0) {
creditCardDigits[last] = 10 - remainder;
}
return getCreditCardNumberAsString(creditCardDigits);
}
This program is very dynamic. I did not add too much error handling. You can enter any number that is divisible by 8.
Code in action:
Enter a card number: 4358 9795
Number is valid?: true
Continue? (y/n): y
Enter a card number: 4358 9796
Number is valid?: false
Continue? (y/n): y
Enter a card number: 43-58 97-95
Number is valid?: true
Continue? (y/n): n
Exiting...
CreditCardValidator.java
import java.text.ParseException;
import java.util.Scanner;
public class CreditCardValidator {
Integer[] digits;
public CreditCardValidator(String numberSequence) {
parseNumber(numberSequence);
}
private void parseNumber(String numberSequence) {
try {
String sequence = numberSequence.replaceAll("[\\s-]+", "");
int length = sequence.length();
if (length % 8 != 0) {
throw new IllegalArgumentException("Number length invalid.");
}
digits = new Integer[length];
int pos = 0;
for (Character c : sequence.toCharArray()) {
if (Character.isDigit(c)) {
digits[pos++] = Character.getNumericValue(c);
} else {
throw new ParseException("Invalid digit.", pos);
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
private boolean validateNumber() {
int sum = 0;
for (int i = digits.length - 1; i >= 0; i--) {
if (i % 2 == 1) {
sum += digits[i];
} else {
sum += NumberUtils.sumDigits(digits[i] * 2);
}
}
return sum % 10 == 0;
}
public static void main(String[] args) {
boolean stop = false;
CreditCardValidator c;
while (!stop) {
System.out.print("Enter a card number: ");
c = new CreditCardValidator(new Scanner(System.in).nextLine());
System.out.println("Number is valid?: " + c.validateNumber());
System.out.print("\nContinue? (y/n): ");
if (new Scanner(System.in).next().charAt(0) == 'n') {
stop = true;
}
System.out.println();
}
System.out.println("Exiting...");
System.exit(0);
}
}
I wrote a separate digit summation utility:
public class NumberUtils {
public static void main(String[] args) {
for(int i = 0; i < 2000; i+=75) {
System.out.printf("%04d: %02d\n", i, sumDigits(i));
}
}
public static int sumDigits(int n) {
if (n < 0)
return 0;
return sumDigitsRecursive(n, 0);
}
private static int sumDigitsRecursive(int n, int total) {
if (n < 10)
return total + n;
else {
return sumDigitsRecursive(n / 10, total + (n % 10));
}
}
}

Uva's 3n+1 problem

I'm solving Uva's 3n+1 problem and I don't get why the judge is rejecting my answer. The time limit hasn't been exceeded and the all test cases I've tried have run correctly so far.
import java.io.*;
public class NewClass{
/**
* #param args the command line arguments
*/
public static void main(String[] args) throws IOException {
int maxCounter= 0;
int input;
int lowerBound;
int upperBound;
int counter;
int numberOfCycles;
int maxCycles= 0;
int lowerInt;
BufferedReader consoleInput = new BufferedReader(new InputStreamReader(System.in));
String line = consoleInput.readLine();
String [] splitted = line.split(" ");
lowerBound = Integer.parseInt(splitted[0]);
upperBound = Integer.parseInt(splitted[1]);
int [] recentlyused = new int[1000001];
if (lowerBound > upperBound )
{
int h = upperBound;
upperBound = lowerBound;
lowerBound = h;
}
lowerInt = lowerBound;
while (lowerBound <= upperBound)
{
counter = lowerBound;
numberOfCycles = 0;
if (recentlyused[counter] == 0)
{
while ( counter != 1 )
{
if (recentlyused[counter] != 0)
{
numberOfCycles = recentlyused[counter] + numberOfCycles;
counter = 1;
}
else
{
if (counter % 2 == 0)
{
counter = counter /2;
}
else
{
counter = 3*counter + 1;
}
numberOfCycles++;
}
}
}
else
{
numberOfCycles = recentlyused[counter] + numberOfCycles;
counter = 1;
}
recentlyused[lowerBound] = numberOfCycles;
if (numberOfCycles > maxCycles)
{
maxCycles = numberOfCycles;
}
lowerBound++;
}
System.out.println(lowerInt +" "+ upperBound+ " "+ (maxCycles+1));
}
}
Are you making sure to accept the entire input? It looks like your program terminates after reading only one line, and then processing one line. You need to be able to accept the entire sample input at once.
I faced the same problem. The following changes worked for me:
Changed the class name to Main.
Removed the public modifier from the class name.
The following code gave a compilation error:
public class Optimal_Parking_11364 {
public static void main(String[] args) {
...
}
}
Whereas after the changes, the following code was accepted:
class Main {
public static void main(String[] args) {
...
}
}
This was a very very simple program. Hopefully, the same trick will also work for more complex programs.
If I understand correctly you are using a memoizing approach. You create a table where you store full results for all the elements you have already calculated so that you do not need to re-calculate results that you already know (calculated before).
The approach itself is not wrong, but there are a couple of things you must take into account. First, the input consists of a list of pairs, you are only processing the first pair. Then, you must take care of your memoizing table limits. You are assuming that all numbers you will hit fall in the range [1...1000001), but that is not true. For the input number 999999 (first odd number below the upper limit) the first operation will turn it into 3*n+1, which is way beyond the upper limit of the memoization table.
Some other things you may want to consider are halving the memoization table and only memorize odd numbers, since you can implement the divide by two operation almost free with bit operations (and checking for even-ness is also just one bit operation).
Did you make sure that the output was in the same order specified in the input. I see where you are swapping the input if the first input was higher than the second, but you also need to make sure that you don't alter the order it appears in the input when you print the results out.
ex.
Input
10 1
Output
10 1 20
If possible Please use this Java specification : to read input lines
http://online-judge.uva.es/problemset/data/p100.java.html
I think the most important thing in UVA judge is 1) Get the output Exactly same , No Extra Lines at the end or anywhere . 2) I am assuming , Never throw exception just return or break with No output for Outside boundary parameters.
3)Output is case sensitive 4)Output Parameters should Maintain Space as shown in problem
One possible solution based on above patterns is here
https://gist.github.com/4676999
/*
Problem URL: http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=36
Home>Online Judge > submission Specifications
Sample code to read input is from : http://online-judge.uva.es/problemset/data/p100.java.html
Runtime : 1.068
*/
import java.io.*;
import java.util.*;
class Main
{
static String ReadLn (int maxLg) // utility function to read from stdin
{
byte lin[] = new byte [maxLg];
int lg = 0, car = -1;
String line = "";
try
{
while (lg < maxLg)
{
car = System.in.read();
if ((car < 0) || (car == '\n')) break;
lin [lg++] += car;
}
}
catch (IOException e)
{
return (null);
}
if ((car < 0) && (lg == 0)) return (null); // eof
return (new String (lin, 0, lg));
}
public static void main (String args[]) // entry point from OS
{
Main myWork = new Main(); // create a dinamic instance
myWork.Begin(); // the true entry point
}
void Begin()
{
String input;
StringTokenizer idata;
int a, b,max;
while ((input = Main.ReadLn (255)) != null)
{
idata = new StringTokenizer (input);
a = Integer.parseInt (idata.nextToken());
b = Integer.parseInt (idata.nextToken());
if (a<b){
max=work(a,b);
}else{
max=work(b,a);
}
System.out.println (a + " " + b + " " +max);
}
}
int work( int a , int b){
int max=0;
for ( int i=a;i<=b;i++){
int temp=process(i);
if (temp>max) max=temp;
}
return max;
}
int process (long n){
int count=1;
while(n!=1){
count++;
if (n%2==1){
n=n*3+1;
}else{
n=n>>1;
}
}
return count;
}
}
Please consider that the integers i and j must appear in the output in the same order in which they appeared in the input, so for:
10 1
You should print
10 1 20
package pandarium.java.preparing2topcoder;/*
* Main.java
* java program model for www.programming-challenges.com
*/
import java.io.*;
import java.util.*;
class Main implements Runnable{
static String ReadLn(int maxLg){ // utility function to read from stdin,
// Provided by Programming-challenges, edit for style only
byte lin[] = new byte [maxLg];
int lg = 0, car = -1;
String line = "";
try
{
while (lg < maxLg)
{
car = System.in.read();
if ((car < 0) || (car == '\n')) break;
lin [lg++] += car;
}
}
catch (IOException e)
{
return (null);
}
if ((car < 0) && (lg == 0)) return (null); // eof
return (new String (lin, 0, lg));
}
public static void main(String args[]) // entry point from OS
{
Main myWork = new Main(); // Construct the bootloader
myWork.run(); // execute
}
public void run() {
new myStuff().run();
}
}
class myStuff implements Runnable{
private String input;
private StringTokenizer idata;
private List<Integer> maxes;
public void run(){
String input;
StringTokenizer idata;
int a, b,max=Integer.MIN_VALUE;
while ((input = Main.ReadLn (255)) != null)
{
max=Integer.MIN_VALUE;
maxes=new ArrayList<Integer>();
idata = new StringTokenizer (input);
a = Integer.parseInt (idata.nextToken());
b = Integer.parseInt (idata.nextToken());
System.out.println(a + " " + b + " "+max);
}
}
private static int getCyclesCount(long counter){
int cyclesCount=0;
while (counter!=1)
{
if(counter%2==0)
counter=counter>>1;
else
counter=counter*3+1;
cyclesCount++;
}
cyclesCount++;
return cyclesCount;
}
// You can insert more classes here if you want.
}
This solution gets accepted within 0.5s. I had to remove the package modifier.
import java.util.*;
public class Main {
static Map<Integer, Integer> map = new HashMap<>();
private static int f(int N) {
if (N == 1) {
return 1;
}
if (map.containsKey(N)) {
return map.get(N);
}
if (N % 2 == 0) {
N >>= 1;
map.put(N, f(N));
return 1 + map.get(N);
} else {
N = 3*N + 1;
map.put(N, f(N) );
return 1 + map.get(N);
}
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
try {
while(scanner.hasNextLine()) {
int i = scanner.nextInt();
int j = scanner.nextInt();
int maxx = 0;
if (i <= j) {
for(int m = i; m <= j; m++) {
maxx = Math.max(Main.f(m), maxx);
}
} else {
for(int m = j; m <= i; m++) {
maxx = Math.max(Main.f(m), maxx);
}
}
System.out.println(i + " " + j + " " + maxx);
}
System.exit(0);
} catch (Exception e) {
}
}
}

Categories

Resources