Getting wrong answer from Uva judge for the 3n+1problem - java

I tried to submit the 3n+1 problem several time but failed to get it accepted on the Uva judge.I wrote the program in java.Can anyone point out the mistake in my program.
Problem statement:-
https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=29&page=show_problem&problem=36
My program:-
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;
while((input=Main.ReadLn(255))!=null){
StringTokenizer str=new StringTokenizer(input);
int n1=Integer.parseInt(str.nextToken());
int n2=Integer.parseInt(str.nextToken());
int max=0;
for(int i=n1;i<=n2;i++)
{
int no=calculate(i,0);
if(max<no){
max=no;
}
}
System.out.println(n1+" "+n2+" "+max);
}
}
static int calculate(int a,int sum){
if(a==1)
{
return sum+1;
}
else if(a%2==0)
{
sum+=1;
return calculate(a/2,sum);
}
else
{
sum+=1;
return calculate((3*a+1),sum);
}
}
}
I am very sorry for bad indentation of my code.

I think the problem is with the input/output. The code in your question reads one line and then prints one line. The input/ouput on the UVa page specifies to use a "series" for input and use "for each" as ouput. In other words: read all the input lines, calculate, and then write all the output lines.
Here is some code to help you read all the input-lines (the ReadLn method in your question looks overly complicated):
public static List<int[]> readCycleRanges() throws Exception {
List<int[]> cycleRanges = new ArrayList<>();
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String line = br.readLine();
while (!(line == null || line.trim().length() == 0)) {
StringTokenizer st = new StringTokenizer(line, " ");
int i = Integer.valueOf(st.nextToken());
int j = Integer.valueOf(st.nextToken());
cycleRanges.add(new int[] { i, j, 0 });
line = br.readLine();
}
return cycleRanges;
}

I got it accepted by UVa judge. The problem was didn't considered that the second number can be smaller than the first number. You have to consider that case in which the second number is the starting of the series.

Related

use a method to read numbers from a text file and return the prime numbers

the question says: Create a class named HW09. In this class implement a method named primeCounter
with the following signature, that takes a file name as string (for example “numbers.txt”) and returns the number of prime numbers in the text file. Assume the text file only contains integer numbers.
I tried to build the code for the program But I keep getting these error messages and I'm not sure how to fix them and get the program running again. My knowledge of the file access concept is very weak and my professor is horrible. I hope someone can help me understand what went wrong
import java.io.*;
import java.util.Scanner;
class HW09 {
public static int primeCounter(String fileName) throws IOException {
int count= 0;
int number;
String x= null;
File filename= new File("C:/Users/black/Desktop/file.txt");
Scanner s = new Scanner(filename);
BufferedReader data= null;
data= new BufferedReader (new FileReader(filename));
while (s.hasNextInt()) {
number= Integer.parseInt(x);
int see=0;
for (int i =1; i<=number; i++) {
if (number%i==0) {
see = see+1;
}
if (see>2) {
break;
}
}
if (see==2) {
count = count+1;
}
}
return count;
}
public static void main (String args []) {
try {
String file= ("C:/Users/black/Desktop/file.txt");
System.out.println(HW09.primeCounter(file));
}
catch (IOException e) {
System.out.println("Couldn't find file! ");
}
}
}
I see a number of issues with your current code, first and foremost is the lack of separation of concerns. I would start with a simple method to determine if a single number is prime. I wrote such a method here, and that looks like
private static boolean isPrime(int n) {
if (n == 2) {
return true;
} else if (n == 1 || n % 2 == 0) {
return false;
}
for (int i = 3; i * i <= n; i += 2) {
if (n % i == 0) {
return false;
}
}
return true;
}
Then you want to read numbers with your Scanner. And check if they are prime. And don't forget to close the Scanner when you're done. Using a try-with-resources takes care of that. Like,
public static int primeCounter(String fileName) throws IOException {
int count = 0;
try (Scanner s = new Scanner(new File(fileName))) {
while (s.hasNextInt()) {
int v = s.nextInt();
if (isPrime(v)) {
count++;
}
}
}
return count;
}
Finally, when constructing a path, it's better to use the system properties to get the home folder. That way, it can work on other people's machines more easily,
public static void main(String args[]) {
try {
String file = new File(
System.getProperty("user.home"), "Desktop/file.txt").getPath();
System.out.println(primeCounter(file));
} catch (IOException e) {
System.out.println("Couldn't find file! ");
}
}
And I created a file to test against,
$ cat ~/Desktop/file.txt
13
11
7
5
3
2
4
After running the program I get, as expected,
6

Find test-case for which code does't work

I submitted one code in code chef but it's giving wrong answer even if it's correct
can anybody help me to identify that please.
I have tried so many inputs and calculated manually and they are correct so why they gave me wrong answer.
so,anybody who can find the TEST Case which give incorrect output by this code ?.
Here is Problem definition.
import java.util.Scanner;
import java.lang.Math;
class Codechef {
static int get(int n,int i,int digit)
{
int p;
p=(int)Math.pow(10,i-1);
n=n/p;
return n%10;
}
static boolean check_pal(int n)
{
int digit;
digit=(int) (Math.log10(n)+1);
int a=0,b=0,i,j,p;
int sum=0;
for(i=1,j=digit-1 ; i<=digit ; i++,j-- )
{
a=get(n,i,digit);
sum+=a*Math.pow(10,j);
}
if(sum==n)
return true;
else
return false;
}
static int reverse(int n)
{
int digit;
digit=(int) (Math.log10(n)+1);
int a=0,b=0,i,j,p;
int sum=0;
for(i=1,j=digit-1 ; i<=digit ; i++,j-- )
{
a=get(n,i,digit);
sum+=a*Math.pow(10,j);
}
return n+sum;
}
public static void main(String[] args) {
try{
Scanner sc=new Scanner(System.in);
int n=sc.nextInt();
if(n<10 || n>999){
System.out.println("NONE");
return;
}
boolean c;
for(int i=1 ; i<=100 ; i++)
{
c=check_pal(n);
if(c==true)
{
System.out.println(n);
return;
}
n=reverse(n);
}
System.out.println("NONE");
}
catch(Exception e)
{
System.out.println("NONE");
}
}
}
Here is one more output.
for 99 it gives 99 and which is correct as it's palindrome.
For 89 (or 98 for that matter), your code returns "NONE", although you reach the answer 8813200023188 after only 24 steps.
Another case is that for 177 and 276 you should get 8836886388 instead of NONE
I didn't debug your code, I just wrote a program that does the same, and compared the output my program gave to the one your program gave. Since you just requested a testcase, that should suffice :) My gutfeeling is that you overflow... an int is not large enough to hold the answer in all cases.
Happy bughunting.
Edit (on Request) with my code.
I didn't change your code, except that I extracted your logic into a getResult(integer) methode so that I could bypass the scanning of the input and simply return a string as result. It prints out all the differences between our versions. I used BigInteger as the type to hold my results.
public class Main {
public static void main(String[] args) {
Main m = new Main();
for (int i=10; i < 1000; i++) {
String myResult = null;
String hisResult = null;
try {
myResult = m.getResultAsString(i);
} catch (Exception e){
System.out.println("Your code threw an exception for " + i);
}
try{
hisResult = Codechef.getResult(i);
} catch (Exception e){
System.out.println("His code threw an exception for " + i);
}
if (myResult != null && hisResult != null && ! myResult.equals(hisResult)) {
System.out.println("For " + i + " you have " + myResult + " but he has " + hisResult);
}
}
}
public String getResultAsString(int inputNumber) {
BigInteger res = getResultAsBigInteger(new BigInteger(""+inputNumber));
if (res != null) {
return res.toString();
} else {
return "NONE";
}
}
public BigInteger getResultAsBigInteger(BigInteger inputNumber) {
int numberOfSteps = 0;
BigInteger currentValue = inputNumber;
while (numberOfSteps < 101 && ! isPalindrome(currentValue)) {
numberOfSteps++;
currentValue = currentValue.add(reverseDigits(currentValue));
}
return numberOfSteps < 101 ? currentValue : null;
}
public boolean isPalindrome(BigInteger number) {
return number.equals(reverseDigits(number));
}
public BigInteger reverseDigits(BigInteger input) {
String inputString = input.toString();
String output = "";
for (int i = inputString.length() - 1; i >= 0; i--)
{
output += inputString.charAt(i);
}
return new BigInteger(output);
}
}
There is an overflow error in your code.
for input 89 it's not working as #Yves V. said
Suggestion is to use BigInteger class of lang.Match it will be useful to eliminate this overflow error.

How to back up a line after a new line submitted by a user? Java

Suppose, you ask user to provide you some input via a console app in Java. They do and hit Enter. You get the string and do something in response. Say, you calculate some value based on the user's input and print it out.
How might I print out a response on the same line as user's input? I'd like to (possibly) delete a new line character and print out a response next to his input.
Please advise how to do this using Java.
Thank you.
You cannot control the Console through basic Java.I think you can use JLine to control the Console.In java 6 u have java.io.Console class through which you can echo asterisk *'s when password has to be read.
http://blogs.oracle.com/alanb/entry/java_io_console_is_finally
I have tried to implement this with the help of jcurses library and here is a demo of something you are looking for
import jcurses.system.CharColor;
import jcurses.system.InputChar;
import jcurses.system.Toolkit;
public class TestClass {
public static void main(String[] args) {
try {
CharColor printColor = new CharColor(CharColor.BLACK, CharColor.WHITE);
int i = 0;
int j = 0;
while (true) {
StringBuilder str = new StringBuilder();
InputChar c = null;
do {
c = Toolkit.readCharacter(); //Read each character
if (c.getCharacter() != 10) { //Do not print character if Return key
str.append(c);
Toolkit.printString(String.valueOf(c), i++, j, printColor); //Print character as you type
}
} while (c.getCharacter() != 10);
Toolkit.printString(processInput(str.toString()), i, j++, printColor);
i = 0;
if (j == Toolkit.getScreenHeight()) {
Toolkit.clearScreen(printColor);
j = 0;
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
public static String processInput(String input) {
return " Input processed";
}
}
You can with ANSI-Codes. In Linux I never had a problem to use them, but on Windows, you have to install ANSI.SYS first.
import java.util.Random;
public class AnsiMove
{
public AnsiMove ()
{
Random random = new Random ();
System.out.print ("ESC[2J");
for (int i = 0; i < 10000; ++i)
{
int y = random.nextInt (23) + 1;
int x = random.nextInt (79) + 1;
char c = (char) (random.nextInt (95) + 32);
gotoXY (x, y);
System.out.print (c);
pause (1);
}
}
void pause (int p)
{
try
{
Thread.sleep (p);
}
catch (InterruptedException e)
{
System.err.println (e);
}
}
void gotoXY (int x, int y)
{
System.out.print ("ESC[" + y + ';' + x + 'H');
}
/** */
public static void main (String args[])
{
new AnsiMove ();
}
}

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) {
}
}
}

How do I adapt this program to comply with the online judge?

I'm solving UVA's Edit Step Ladders on an uva sub-site named programming-challenges.com, but since I didn't get at all the format in which I'm supposed to test-input I simply took their sample input, put it into a text file and tested my code from there. Like this:
import java.io.*;
import java.util.*;
class Levenshtein {
private static int minimum(int a, int b, int c) {
if(a<=b && a<=c)
return a;
if(b<=a && b<=c)
return b;
return c;
}
public static int computeLevenshteinDistance(String str1, String str2) {
return computeLevenshteinDistance(str1.toCharArray(),
str2.toCharArray());
}
private static int computeLevenshteinDistance(char [] str1, char [] str2) {
int [][]distance = new int[str1.length+1][str2.length+1];
for(int i=0;i<=str1.length;i++)
distance[i][0]=i;
for(int j=0;j<=str2.length;j++)
distance[0][j]=j;
for(int i=1;i<=str1.length;i++)
for(int j=1;j<=str2.length;j++)
distance[i][j]= minimum(distance[i-1][j]+1,
distance[i][j-1]+1,
distance[i-1][j-1]+
((str1[i-1]==str2[j-1])?0:1));
return distance[str1.length][str2.length];
}
public static void main(String args[]){
ArrayList<String> theWords = new ArrayList<String>();
try {
String ruta="entradaLevenshtein.txt";
File myFile = new File (ruta);
FileReader fileReader = new FileReader(myFile);
BufferedReader reader = new BufferedReader(fileReader);
String line = null;
while ((line=reader.readLine())!=null){
System.out.println(line);
theWords.add(line);
}
reader.close();
}
catch (IOException ex){
ex.printStackTrace();
}
{}
// todo esto sólo para iniciar el arreglo
// ahora vienen las llamadas a Levenstein y las comparaciones
int maxEdit=0;
int actualEdit=0;
int wordsIndex1 =0, wordsIndex2=0;
while (wordsIndex1<= theWords.size())
{
while (wordsIndex2<= theWords.size()-1){
actualEdit=computeLevenshteinDistance(theWords.get(wordsIndex1),theWords.get(wordsIndex2));
if (actualEdit>maxEdit){maxEdit=actualEdit;}
wordsIndex2++;
}
wordsIndex1++;
}
System.out.println(maxEdit+1);
}
}
my input file being:
cat
dig
dog
fig
fin
fine
fog
log
wine
I'm supposed to make the code comply to the following pattern, thing is..I don't get where this thing is capturing its String:
import java.io.*;
import java.util.*;
class Modelo implements Runnable{
static String ReadLn(int maxLength){ // utility function to read from stdin,
// Provided by Programming-challenges, edit for style only
byte line[] = new byte [maxLength];
int length = 0;
int input = -1;
try{
while (length < maxLength){//Read untill maxlength
input = System.in.read();
if ((input < 0) || (input == '\n')) break; //or untill end of line ninput
line [length++] += input;
}
if ((input < 0) && (length == 0)) return null; // eof
return new String(line, 0, length);
}catch (IOException e){
return null;
}
}
public static void main(String args[]) // entry point from OS
{
Modelo myWork = new Modelo(); // Construct the bootloader
myWork.run(); // execute
}
public void run() {
new myStuff().run();
}
}
class myStuff implements Runnable{
public void run(){
try
{
/// PLACE YOUR JAVA CODE HERE
}catch(Exception e){
System.out.println("A Exception was generated");
}
}
// You can insert more classes here if you want.
}
Why should I place it where it says //place your code here and not here??
try{
while (length < maxLength){//Read untill maxlength
input = System.in.read();
if ((input < 0) || (input == '\n')) break; //or untill end of line input
line [length++] += input;
}
How do I manipulate the input??
I think the idea here is to write your program in the myStuff class, where it will be called in the run() method. From the run() method, you can use Modelo.ReadLn() to get your input.

Categories

Resources