Changes to be made to make the given code more effecient - java

https://www.hackerrank.com/contests/csindia/challenges/pin-problem-1
The below solution for above problem is not getting submitted, "timeout terminated" message was popping out. For successful submission what changes should be made below code? Please help me out.
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
class Solution
{
public static void main(String args[])
{
try{
BufferedReader br =
new BufferedReader(new InputStreamReader(System.in));
int testcase = Integer.parseInt(br.readLine());
if (testcase > 0 && testcase <= 100000)
{
int outarr[] = new int[testcase];
for (int i = 0; i < testcase; i++)
{
String str = br.readLine();
StringTokenizer st = new StringTokenizer(str," ");
int n = Integer.parseInt(st.nextToken());
int m = Integer.parseInt(st.nextToken());
if (n > 0 && n <= 10000 && m > 0 && m <= 10)
{
int maincounter = 0;
str = br.readLine();
String s[];
s = str.split(" ");
if (s.length == m)
{
for (int k = 1; k <= n; k++)
{
int counter = 0;
for (int l = 0; l < s.length; l++)
{
if (k % (Integer.parseInt(s[l])) == 0)
counter++;
}
if (counter == s.length)
maincounter++;
}
outarr[i] = maincounter;
}
else
{
System.out.println("Enter the specified values of m not more than that");
testcase--;
}
}
else
{
System.out.println("Enter value of n in between 1 to 10^4 and value of m in between 0 to 10");
testcase--;
}
}
for (int i = 0; i < testcase-1; i++)
{
System.out.println(+outarr[i]);
}
System.out.print(+outarr[testcase-1]);
}
else
{
System.out.println("Enter the test value in between 1 to 10^5");
}
}
catch(Exception ae)
{
System.out.println("Exception caught");
}
}
}

You have a lot of unnecessary checks in your code that are slowing it down a little, but honestly not enough to make it not finish. Hackerrank tells you what the bounds will be for the input, so you don't need to verify it for these purposes.
I've gone through the code and added comments for you where this could be improved:
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
class Solution
{
public static void main(String args[])
{
try{
BufferedReader br =
new BufferedReader(new InputStreamReader(System.in));
int testcase = Integer.parseInt(br.readLine());
// This check is unnecessary, hackerrank told you testcase would be in these
// bounds.
if (testcase > 0 && testcase <= 100000)
{
int outarr[] = new int[testcase];
for (int i = 0; i < testcase; i++)
{
String str = br.readLine();
StringTokenizer st = new StringTokenizer(str," ");
int n = Integer.parseInt(st.nextToken());
int m = Integer.parseInt(st.nextToken());
// This check is unnecessary, hackerrank told you m and n would be in these
// bounds.
if (n > 0 && n <= 10000 && m > 0 && m <= 10)
{
int maincounter = 0;
str = br.readLine();
String s[];
s = str.split(" ");
// This check is unnecessary, hackerrank told you the next line
// would have m numbers
if (s.length == m)
{
for (int k = 1; k <= n; k++)
{
int counter = 0;
for (int l = 0; l < s.length; l++)
{
// Here, instead of checking every number to see
// if it is divisible, you can check and see if
// it isn't. If it isn't, then you shouldn't bother
// checking the rest of the possible numbers because
// you know that k isn't a possible pin number.
// Add a flag that indicates if the pin is still valid,
// if it isn't, move on to the next pin.
if (k % (Integer.parseInt(s[l])) == 0)
counter++;
}
if (counter == s.length)
maincounter++;
}
outarr[i] = maincounter;
}
else
{
System.out.println("Enter the specified values of m not more than that");
testcase--;
}
}
else
{
System.out.println("Enter value of n in between 1 to 10^4 and value of m in between 0 to 10");
testcase--;
}
}
// Why the -1? You can just do i < testcase and print it all here
// instead of on multiple lines.
for (int i = 0; i < testcase-1; i++)
{
System.out.println(+outarr[i]);
}
System.out.print(+outarr[testcase-1]);
}
else
{
System.out.println("Enter the test value in between 1 to 10^5");
}
}
catch(Exception ae)
{
System.out.println("Exception caught");
}
}
Code after changes:
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
class Solution
{
public static void main(String args[])
{
try{
BufferedReader br =
new BufferedReader(new InputStreamReader(System.in));
int testcase = Integer.parseInt(br.readLine());
int outarr[] = new int[testcase];
for (int i = 0; i < testcase; i++)
{
String str = br.readLine();
StringTokenizer st = new StringTokenizer(str," ");
int n = Integer.parseInt(st.nextToken());
int m = Integer.parseInt(st.nextToken());
int maincounter = 0;
str = br.readLine();
String[] s = str.split(" ");
for (int k = 1; k <= n; k++)
{
boolean stillValid = true;
for (int l = 0; l < m && stillValid; l++)
{
if (k % (Integer.parseInt(s[l])) != 0)
{
stillValid = false;
}
}
if (stillValid)
{
maincounter++;
}
}
outarr[i] = maincounter;
}
for (int i = 0; i < testcase; i++)
{
System.out.println(outarr[i]);
}
}
catch(Exception ae)
{
System.out.println("Exception caught " + ae.getMessage());
}
}

Related

how to insert in two dimensional array?

i'am new injava , in this problem i will insert a numbers of strings in a array , but the compiler give me this probleme :
PhoneNumber.java:29: error: incompatible types: String cannot be converted to boolean
while(test[i][j])
^
1 error
public class PhoneNumber{
public static void check_number(String[][] numbers, int n)
{
int i,j;
for(i = 0; i < n; i++)
{
for(j = 0; j < numbers[i].length; j++)
{
if(numbers[i][j] == "4" || numbers[i][j] == "5")
{
System.out.println("Done");
}
}
}
}
public static void main(String[] args)
{
String[][] test = new String[100][100];
Scanner number = new Scanner(System.in);
int n,i,j;
System.out.println("enter the number of numbers");
n = number.nextInt();
for(i = 0 ; i < n; i++)
{
System.out.println("enter the number " + i + 1);
j = 0;
while(test[i][j])
{
test[i][j] = number.nextLine();
j++;
}
}
check_number(test,n);
}
}
Here's the basic approach for a 1D String array with notes included:
import java.util.Scanner;
public class PhoneNumber{
public static void check_number(String[] numbers, int n)
{
for(int i = 0; i < n; i++)
{
System.out.println(numbers[i]);
//the String class method equals is best for comparison:
if(numbers[i].equals("4") || numbers[i].equals("5"))
{
System.out.println("Done");
}
}
}
public static void main(String[] args)
{
Scanner number = new Scanner(System.in);
int n;
System.out.println("enter the number of numbers");
n = number.nextInt();
//clean the scanner buffer after input especially with Int -> Line
number.nextLine();
//size your array after getting user input
String[] test = new String[n];
for(int i = 0 ; i < n; i++)
{
//parenthesis needed to get correct output for i + 1
System.out.println("enter the number " + (i + 1));
test[i] = number.nextLine();
}
check_number(test,n);
}
}

How to find a number with no digit occurring more than once (J3 CCC 2013 from 1987 to 2013)

I'm a grade 11 student and have been given the task to complete this question for homework:
Problem J3/S1: From 1987 to 2013
You might be surprised to know that 2013 is the first year since 1987
with distinct digits.
The years 2014, 2015, 2016, 2017, 2018, 2019
each have distinct digits.
2012 does not have distinct digits,
since the digit 2 is repeated.
Given a year, what is the next year with distinct digits?
Input
The input consists of one integer Y (0 ≤ Y ≤ 10000),
representing the starting year.
Output
The output will be the single integer D,
which is the next year after Y with distinct digits.
Sample Input 1
1987
Sample Output 1
2013
Sample Input 2
999
Sample Output 2
1023
I usually answer these types of questions rather quickly but I am stumped when it comes to this one. I have spent several hours and cannot figure it out. I found out How to identify if a number is distinct or not, but I can't figure out how to add on years and check again, I keep getting errors. I would really appreciate someone's help.
Please keep in mind that I am in grade 11 and this is my first year of working with Java, so please do not use advanced coding, and methods because I won't understand. If you can, please answer it in a class and not the main method.
here is what I tried:
import java.util.*;
import java.io.*;
public class Leavemealone
{
public static void main(String[] args) throws IOException
{
BufferedReader objReader = new BufferedReader(new InputStreamReader(System.in));
int ctr = 0;
String inputStr = "";
int input = 0;
int inputCheck = 0;
System.out.println("Enter somthin: ");
input = Integer.parseInt (objReader.readLine ());
while(ctr == 0)
{
inputStr += input;
Scanner sc = new Scanner(inputStr);
int n = sc.nextInt(); // get year
String s = String.valueOf(n);
int[] num = new int[4];
for (int i = 0; i < s.length(); i++)
{
int x = Integer.parseInt(s.substring(i, i + 1)); // integer at this part in the string
num[i] += x;
}
String apple = (num[0] + "" + num[1] + "" + num[2] + "" + num[3]);
if (num[0] != num[1] &&
num[1] != num[2] &&
num[2] != num[3] &&
num[0] != num[2] &&
num[0] != num[3] &&
num[1] != num[3])
{
ctr++;
//distinct
}
else
{
input++;
//not distinct
}
}
}
}
Thanks in advance!
this is the other code I found online, I just don't know how to put it in a class
import java.util.Scanner;
import java.io.*;
public class Thegoodone
{
public static void main(String[] args) throws IOException
{
BufferedReader objReader = new BufferedReader(new InputStreamReader (System.in));
int ctr = 0;
String input = "";
int inputCheck = 0;
while (ctr == 0)
{
System.out.println("Enter somthin: ");
inputCheck = Integer.parseInt (objReader.readLine ());
if (inputCheck > 0 && inputCheck < 10000)
{
input += inputCheck;
ctr += 1;
}
else
{
System.out.println("invalid input ");
}
}
Scanner sc = new Scanner(input);
int n = sc.nextInt(); // get year
n++; // start from the next year
while (!hasDistinctDidgets(n)) //if there is repeating digits
{
n++;// next year
}
System.out.println(n);// prints year
}
public static boolean hasDistinctDidgets(int n)
{
//System.out.println("a" + n);
String s = String.valueOf(n); // converts the year from int to String
int[] numbers = new int[10]; // index position represents number, element value represents occurrence of that number
for (int i = 0; i < s.length(); i++)
{
int x = Integer.parseInt(s.substring(i, i + 1)); // integer at this part in the string
numbers[x]++; //increase occurrence of this integer in the array
}
//check if any digit occurred more than once in the array
for (int i = 0; i < numbers.length; i ++)
{
if (numbers[i] > 1) //digit occurred more than once
{
return false; //not distinct
}
}
return true; // hasn't returned false yet, so the integer has distinct digits
}
}
so this is how I tried to put it in a class:
import java.util.Scanner;
import java.io.*;
public class Danny3
{
public static void main(String[] args) throws IOException
{
BufferedReader objReader = new BufferedReader(new InputStreamReader (System.in));
int ctr = 0;
String input = "";
int inputCheck = 0;
while (ctr == 0)
{
System.out.println("Enter somthin: ");
inputCheck = Integer.parseInt (objReader.readLine ());
if (inputCheck > 0 && inputCheck < 10000)
{
input += inputCheck;
ctr += 1;
}
else
{
System.out.println("invalid input ");
}
}
Scanner sc = new Scanner(input);
// System.out.println(output);
int n = sc.nextInt(); // get year
n++; // start from the next year
DistinctCheck processing = new DistinctCheck(n);
int output = processing.getSum();
System.out.println(output);
}
}
class DistinctCheck
{
//private int year = 0;
private boolean hasDistinctDidgets;
private int b = 0;
DistinctCheck(int temp)
{
hasDistinctDidgets(temp);
}
private void yearAdd(int b)
{
while(!hasDistinctDidgets(b)) //if there is repeating digits
{
b++;// next year
}
}
private boolean hasDistinctDidgets(int year)
{
String s = String.valueOf(year); // converts the year from int to String
int[] numbers = new int[10]; // index position represents number, element value represents occurrence of that number
for (int i = 0; i < s.length(); i++)
{
int x = Integer.parseInt(s.substring(i, i + 1)); // integer at this part in the string
numbers[x]++; //increase occurrence of this integer in the array
}
//check if any digit occurred more than once in the array
for (int i = 0; i < numbers.length; i ++)
{
if (numbers[i] > 1) //digit occurred more than once
{
return false; //not distinct
}
}
return true; // hasn't returned false yet, so the integer has distinct digits
}
int getSum()
{
return b;// prints year
}
}
I would start with a method to determine if a given int consists of distinct digits. You could use a Set<Character> and add each character from the String to the Set. You will get false on a duplicate. Like,
static boolean distinctDigits(int i) {
String s = String.valueOf(i);
Set<Character> set = new HashSet<>();
for (char c : s.toCharArray()) {
if (!set.add(c)) {
return false;
}
}
return true;
}
Then your main just needs to invoke that. Like,
public static void main(String[] args) {
Scanner s = new Scanner(System.in);
int v = s.nextInt();
while (v < 10000) {
v++;
if (distinctDigits(v)) {
break;
}
}
System.out.println(v);
}
i figured it out:
import java.util.*;
public class Apple
{
public static void main(String[] args)
{
Scanner input = new Scanner(System.in);
int num = input.nextInt();
Distinct findDistinct = new Distinct(num); // objecct
String output = findDistinct.getDistinctYear();
System.out.println(output);
}
} // end of main
class Distinct
{
private int ctr = 0;
private String yearStr = "";
private String distinctYear = "";
private int year = 0;
Distinct(int n)
{
year = n;
makeDistinct();
}
private void makeDistinct()
{
while(ctr == 0)
{
year += 1; // year will keep increasing until it is distinct
yearStr = Integer.toString(year);
if(isDistinct(yearStr) == true) // if the number is distinct
{
distinctYear = yearStr;
ctr++;
}
}
}
private boolean isDistinct(String yearStr)
{
String eachNum[] = yearStr.split(""); // breaks up each number (char) of yearStr
for(int i = 0; i < eachNum.length; i++)
{
for(int j = 0; j < i; j++)
{
if (eachNum[i].equals(eachNum[j])) // not distinct
{
return false;
}
}
}
return true; // is distinct
}
String getDistinctYear()
{
return distinctYear;
}
}

TimeLimitExceeded upon submission

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;
class Main {
public static void main(String[] args) throws NumberFormatException, IOException {
BufferedReader input = new BufferedReader(new InputStreamReader(System.in));
int t = Integer.parseInt(input.readLine());
for (int i = 0; i < t; i++) {
String[] arrayData = input.readLine().split(" ");
int[] cardsi = new int[arrayData.length];
int e = 0;
for(int a = 0; a < arrayData.length; a++){
cardsi[e] = Integer.parseInt(arrayData[a]);
e++;
}
int X = cardsi[0];
int N = cardsi[1];
long count = 0;
for (int j = 2; j < cardsi.length; j++) {
for (int l = 3; l <= (cardsi.length - 1); l++) {
if ((cardsi[j] + cardsi[l]) == X &&(j != l)) {
count++;
}
}
}
System.out.println((i + 1) + ". " + count);
}
}
}
Time limit exceeded error is appearing upon submitting this LCPC12F problem on spoj.. what might be a solution? Is scanner a major trouble for such error to appear?
Have you ever run those codes on IDE?
When I give the number to t element then arrayData (in this case, we should enter int type not String, because of the java.lang.NumberFormatException), it shows Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 1 and int N = cardsi[1]; is the main problem on your code I think. This is because String[] arrayData = input.readLine().split(" "); size is 1 so you do not have cardsi[1] element on your int array

NZEC error on Hackerearth in java

I am getting NZEC exception in java for below code on hackerearth. Can anyone please help?
Added the try catch block as well
import java.util.HashMap;
import java.util.Scanner;
class TestClass {
public static void main(String args[]) throws Exception {
try {
Scanner sc = new Scanner(System.in);
String S = new String();
HashMap<Long, String> hm = new HashMap<>();
S = sc.nextLine();
int len = sc.nextInt();
long[] q = new long[len];
for (int i = 0; i < len; i++) {
q[i] = sc.nextLong();
}
Long key = (long) 1;
for (int i = 0; i < S.length(); i++) {
for (int j = i + 1; j <= S.length(); j++) {
hm.put(key++, S.substring(i, j));
}
}
for (int i = 0; i < len; i++) {
if (q[i] <= hm.size())
System.out.println(hm.get(q[i]));
else {
System.out.println(-1);
}
}
} catch (Exception e) {
}
}
}
It mostly occurs when negative array index is accesed or the program which we have written takes up more space than the allocated memory for our program to run.

String compression algorithm in Java

I am looking to implement a method to perform basic string compression in the form of:
aabcccccaaa -> a2b1c5a3
I have this program:
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String str = sc.nextLine();
System.out.println(compress(str));
}
public static String compress(String str) {
char[] chars = str.toCharArray();
int count = 0;
String result = "";
for (int i = 0; i < chars.length; i++) {
char curr = chars[i];
result += curr;
for (int j = i; j < chars.length; j++) {
if (chars[j] == curr) {
count++;
}
else {
i += count;
break;
}
}
result += count;
count = 0;
}
return result;
}
}
But in my tests I am always missing the last character count.
I assume this is because the program gets out of the inner for loop before it should, but why is this the case?
Thanks a lot
You don't need two for loops for this and can do it in one go like so
String str = "aaabbbbccccca";
char[] chars = str.toCharArray();
char currentChar = str.length() > 0 ? chars[0] : ' ';
char prevChar = ' ';
int count = 1;
StringBuilder finalString = new StringBuilder();
if(str.length() > 0)
for(int i = 1; i < chars.length; i++)
{
if(currentChar == chars[i])
{
count++;
}else{
finalString.append(currentChar + "" + count);
prevChar = currentChar;
currentChar = chars[i];
count = 1;
}
}
if(str.length() > 0 && prevChar != currentChar)
finalString.append(currentChar + "" + count);
System.out.println(finalString.toString());
Output is: a3b4c5a1 for aaabbbbccccca
Keep a track of character that you are reading and compare it with next character of the string. If it is different, reset the count.
public static void stringCompression (String compression) {
String finalCompressedString = "";
char current = '1';
int count = 0;
compression = compression + '1';
for (int i = 0; i < compression.length(); i++) {
if (compression.charAt(i) == current) {
count = count + 1;
} else {
if (current != '1')
finalCompressedString = finalCompressedString + (current + Integer.toString(count));
count = 1;
current = compression.charAt(i);
}
}
System.out.println(finalCompressedString);
}
My answer for String Compression in java.
In this what i have done is and what you should have done is that , Keep a record of the characters that that are coming for a specific number of times, do so by comparing the current character with the next character , and when the current and the next character become unequal reset the value of count and repeat the whole process again for the next different character.
Hope it helps!
import java.util.*;
public class Main {
public static void main(String args[]) {
Scanner sc = new Scanner(System.in);
String str = sc.nextLine();
int count = 0;
for (int i=0; i<str.length(); ++i) {
int j=i+1;
count=1;
while (j!=str.length() && str.charAt(i) == str.charAt(j)) {
count += 1;
j += 1;
i += 1;
}
System.out.print(str.charAt(i));
if (count > 1) {
System.out.print(count);
}
}
}
}

Categories

Resources