This program take lot of time for execution - java

public class Solution {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int t = in.nextInt();
if(t<1 || t>100){System.exit(0);}
ArrayList a=new ArrayList<>();
for(int i=0;i<t;i++){
String s=in.next().toString();
String s2=in.next().toString();
int count=0;
int first=Integer.parseInt(s);
int last=Integer.parseInt(s2);
if(first<1 || last>1000000000){System.exit(0);}
for(int k=first;k<=last;k++){
int sqrt =(int)Math.sqrt(k);
if(sqrt*sqrt==k){count++;}
}
a.add(count);
}
Iterator it=a.iterator();
while(it.hasNext()){
System.out.println(it.next());
}
}
}
In this program when i give big input, it takes lots of time to give output. Can someone tell me how to optimize this program.
this program is for finding square root number.
Input: The first line contains , the number of test cases T. T test cases follow, each in a new line.
Each test case contains two space-separated integers denoting s and s2.
Sample Input
2
3 9
17 24
Sample output
2
0
big input:
35
465868129 988379794
181510012 293922871
395151610 407596310
481403421 520201871
309804254 776824625
304742289 566848910
267554756 828997506
387224568 926504395
244571677 871603971
444567315 582147918
334350264 342469009
400474096 410940967
488907300 943628573
26441071 801576263
182001128 267557939
115732998 974318256
192538332 862327048
45429427 307805497
358658006 842644090
92930998 431601473
231163983 893672132
275221547 298953978
351237326 981399371
484598992 985428966
103405553 529324202
37393469 768655346
30179914 482808626
208821550 538302223
154654533 791652309
68424067 854065374
246956110 517538724
51395253 876949418
57778758 368742600
227566632 606529208

This method compute the number of square between two bounds:
public static int squaredNumberInRange(int lowerBound, int upperBound){
double lowerRoot = Math.sqrt(lowerBound);
double upperRoot = Math.sqrt(upperBound);
lowerRoot = Math.ceil(lowerRoot);
upperRoot = Math.floor(upperRoot);
int spread = (int)upperRoot - (int)lowerRoot + 1;
return spread;
}
Complexity is O(1)

Related

Issues with Kattis "0-1 Sequences" Solution

Since last night I have been working very hard trying to write a solution to the problem "0-1 Sequences" (https://open.kattis.com/problems/sequences) on Kattis. At this point, I am at my wits end. I keep getting the wrong answer on the third test case, and I've tried everything I can possibly think of to fix my code. I'm fairly certain that the formula I am using to compute the result is correct, and I haven't been able to find an example where it gives the wrong answer. I suspect the issue is something to do with how I am calculating the modulus, but I've written and rewritten the relevant parts of the code and I am still failing each time. Below is my code (sorry in advance, I've been working like a madman with not much regard for writing "nice" code).
import java.util.*;
import java.util.ArrayList;
public class oneZeroSequences {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String s = sc.nextLine();
//leading zero's have no effect on the number of inversions,
//and we therefore get rid of them all right off the bat.
while(s.charAt(0)=='0'){
s=s.substring(1);
if(s.length()==0){
System.out.println(0);
System.exit(0);
}
}
System.out.println(findSum(s));
System.exit(0);
}
public static long findSum(String s) {
int m=1000000007;
long res = 0;
//if passed an empty string, the sum of inversions is obviously 0
if(s.length()==0){
return 0;
}
while(s.charAt(0)=='0'){
s=s.substring(1);
if(s.length()==0){
return 0;
}
}
//if the first character of the string is a question mark, we handle the case
//where that question mark is 1 first, and then remove the question mark since
//leading 0's have no effect on inversions.
while(s.charAt(0)=='?'){
res+=findSum("1"+s.substring(1))%m;
s=s.substring(1);
if(s.length()==0){
return res%m;
}
}
ArrayList<Integer> qArray = new ArrayList<Integer>();
int start=0;
int found;
//here we construct an array of the indices of question marks in the string
while(true){
found=s.indexOf('?', start);
if(found==-1){
break;
}
qArray.add(found);
start=found+1;
}
ArrayList<Integer> zeroArray = new ArrayList<Integer>();
start=0;
found=0;
//here we construct an array of the indices of 0's in the string
while(true){
found=s.indexOf('0', start);
if(found==-1){
break;
}
zeroArray.add(found);
start=found+1;
}
long k = qArray.size();
long a = zeroArray.size();
long zeroSum = sumArrayList(zeroArray);
long qSum = sumArrayList(qArray);
Double dres = 0.0;
//the formula for sum of inversions is as follows:
//2^k*(zeroSum) + 2^(k-1)*(qSum) - (a^2-a)*2^(k-1) - (2a-1)*2^(k-2) - (k^2+k)*2^(k-3)
//the following lines of code apply this formula, taking the modulus at each step.
if(k>=3){
res += (expBySquaringMod(2, k)*(zeroSum%m))%m;
//res=(res%m+m)%m;
res +=((expBySquaringMod(2, k-1))*(qSum%m))%m;
//res=(res%m+m)%m;
res -= ((((((a%m)*(a%m))%m)-a%m)%m)*expBySquaringMod(2,k-1))%m;
//res=(res%m+m)%m;
res -= (((((2*a-1)%m)*(k%m))%m)*expBySquaringMod(2,k-2))%m;
//res=(res%m+m)%m;
res-= (((((k%m)*(k%m))%m+k%m)%m)*expBySquaringMod(2, k-3))%m;
//res=(res%m+m)%m;
return res%m;
}
//the expBySquaringMod function will give incorrect
//results for negative exponents, hence the following code.
dres += ((Math.pow(2,k))*(zeroSum%m))%m;
dres=(dres%m+m)%m;
dres +=((Math.pow(2,k-1))*(qSum%m))%m;
dres=(dres%m+m)%m;
dres -= (((((a%m)*(a%m))%m-a%m)%m)*(Math.pow(2,k-1)))%m;
dres=(dres%m+m)%m;
dres -=((((2*a-1)%m*(k%m)%m)*(Math.pow(2,k-2))))%m;
dres=(dres%m+m)%m;
dres-=((((k%m)*(k%m)%m+k%m))%m*(Math.pow(2,k-3)))%m;
dres=(dres%m+m)%m;
res+=dres.intValue()%m;
return res%m;
}
public static int sumArrayList(ArrayList<Integer> list) {
int res = 0;
for(int d : list) {
res+=d;
}
return res;
}
//this function was written to deal with the massive powers of two required for the solution
public static long expBySquaringMod(int base, long exp) {
int m=1000000007;
long res=1;
if(exp%2==0) {
for(int i=0; i<exp/2;i++) {
res=(res*base*base)%m;
}
} else{
res=base;
for(int i=0; i<exp/2;i++) {
res=(res*base*base)%m;
}
}
return res;
}
}
Any help will be greatly appreciated. This problem has been causing me a lot of distress.

Identify the failed test cases

I have participated in coding contest, where I have attempt the given problem, so I am supposed to come up with solution which should not only passing all the test cases, also well optimized in terms of time and space complexity, I have passed 3 out of 7 but I am still not able to identify the rest of the test cases, it is possible that I might be missing something, please help me to rectify the below problem statement.
PROBLEM STATEMENT:
The Powerpuff Girls (100 Marks)
Professor Utonium is restless because of the increasing crime in the world. The number of villains and their activities has increased to a great extent. The current trio of Powerpuff Girls is not well to fight the evils of the whole world. Professor has decided to create the maximum number of Powerpuff Girls with the ingredients he has.
There are N ingredients required in a certain quantity to create a Powerpuff Girl. Professor has all the N ingredients in his laboratory and knows the quantity of each available ingredient. He also knows the quantity of a particular ingredient required to create a Powerpuff Girl. Professor is busy with the preparations and wants to start asap.
The villains, on the other hand, want to destroy the laboratory and stop Professor Utonium from creating more Powerpuff girls. Mojo Jojo is coming prepared with ammunition and Him is leading other villains like Princess, Amoeba Boys, Sedusa, Gangreen Gang etc.
Professor does not have much time as villains will reach the laboratory soon. He is starting the process but does not know the number of Powerpuff Girls which will be created. He needs your help in determining the maximum number of Powerpuff Girls which will be created with the current quantity of ingredients.
Example:
Professor Utonium requires 3 ingredients to make Powerpuff Girls. The 3 ingredients are present in the laboratory in the given quantity:
To make a Powerpuff Girl, Professor Utonium requires:
3 units of Ingredient A
6 units of Ingredient B
10 units of Ingredient C
The maximum number of Powerpuff Girls that can be created is 3 as, after 3, Professor will run out of Ingredient C.
Can you determine the maximum number?
Input Format
The first line of input consists of the number of ingredients, N
The second line of input consists of the N space-separated integers representing the quantity of each ingredient required to create a Powerpuff Girl.
The third line of input consists of the N space-separated integers representing the quantity of each ingredient present in the laboratory.
Constraints
1<= N <=10000000 (1e7)
0<= Quantity_of_ingredient <= LLONG_MAX
Output Format
Print the required output in a separate line.
Sample TestCase 1
Input
4
2 5 6 3
20 40 90 50
Output
8
SOLUTION CODE
package com.mzk.poi;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Scanner;
public class PowerPuffGirls {
private static final String SPACE = " ";
private static final Integer INITAL_IDX = 0;
private static final Integer LOWER_IDX = 1;
private static final Integer SECOND_IDX = 2;
private static final Integer MAX_LINES = 3;
private static final Integer UPPER_IDX = 1000000;
private static String[] UnitsArr = null;
private static String[] totIngrdientsArr = null;
private static int size = 0;
public static void main(String[] args) {
List<Integer> maxPowerPuffGirlsCreationList = new ArrayList<Integer>();
Scanner stdin = new Scanner(System.in);
String[] input = new String[MAX_LINES];
try {
for (int i = 0; i < input.length; i++) {
input[i] = stdin.nextLine();
if (validateIngredienInput(input[INITAL_IDX])) {
System.exit(INITAL_IDX);
}
}
} finally {
stdin.close();
}
int numOfIngredients = Integer.parseInt(input[INITAL_IDX]);
String units = input[LOWER_IDX];
UnitsArr = units.split(SPACE);
String ingredients = input[SECOND_IDX];
totIngrdientsArr = ingredients.split(SPACE);
size = UnitsArr.length;
int[] specifiedArrayOfUnits = convertToIntegerArray(UnitsArr);
int[] totIngredientInLabArray = convertToIntegerArray(totIngrdientsArr);
for (int i = 0; i < size; i++) {
totIngredientInLabArray[i] = Integer.parseInt(totIngrdientsArr[i]);
}
for (int i = 0; i < numOfIngredients; i++) {
maxPowerPuffGirlsCreationList.add(totIngredientInLabArray[i] / specifiedArrayOfUnits[i]);
}
System.out.println(Collections.min(maxPowerPuffGirlsCreationList));
}
/**
* This method validates the first input
* #param noOfIngredients
* #return boolean
*/
private static boolean validateIngredienInput(String noOfIngredients) {
int numOfIngredients = Integer.parseInt(noOfIngredients);
boolean result = false;
if (numOfIngredients <= LOWER_IDX && numOfIngredients <= UPPER_IDX) {
result = true;
return result;
}
return result;
}
/**
* This utility method convert the String array to Integer array
* #param size
* #param specifiedArrayOfUnits
* #return int[]
*/
private static int[] convertToIntegerArray(String[] arrayToBeParsed) {
int array[] = new int[size];
for (int i = INITAL_IDX; i < size; i++) {
array[i] = Integer.parseInt(arrayToBeParsed[i]);
}
return array;
}
}
The above solution has passed 3 test cases, remaining 7 are un identfied,Please help me to rectify or improve this code.
There are several issues with your code:
try {
for (int i = 0; i < input.length; i++) {
input[i] = stdin.nextLine();
if (validateIngredienInput(input[INITAL_IDX])) {
System.exit(INITAL_IDX);
}
}
} finally {
stdin.close();
}
You don't need to check the first row each time you read one line from the input. Instead you run the test only once. You can run it once you read the first line or after you read the whole input. The code can be look like this:
for (int i = 0; i < input.length; i++) {
input[i] = stdin.nextLine();
}
if (!validateIngredienInput(input[INITAL_IDX])) {
System.exit(...);
}
Also, it is not clear what the return value of validateIngredienInput() means. Is true a correct input or is false? Your if() statements checks for the return value being true and quits if it is.
private static boolean validateIngredienInput(String noOfIngredients)
{
int numOfIngredients = Integer.parseInt(noOfIngredients);
boolean result = false;
if (numOfIngredients <= LOWER_IDX && numOfIngredients <= UPPER_IDX) {
result = true;
return result;
}
return result;
}
Your if() condition doesn't make any sense. You are checking if the number of different ingredients is <= 0 and <= 1. This also means that you could rewrite is as just if (numOfIngredients <= 0). But with the description above it is unclear if the validation should return true or false. Depending on what this method should do it can be written as:
private static boolean validateIngredienInput(String noOfIngredients)
{
int numOfIngredients = Integer.parseInt(noOfIngredients);
return numOfIngredients > 0;
}
This will return true if the value is greater than 0.
UnitsArr = units.split(SPACE);
Variable and field names should begin in lowercase, so they don't get confused with class names, which start in uppercase. It looks like UnitsArr is a class, but it is actually a field. So you should rename your field to unitsArr:
unitsArr = units.split(SPACE);
Also check the requirement/format of the input and the limits:
Constraints
1<= N <=10000000 (1e7)
0<= Quantity_of_ingredient <= LLONG_MAX
As you see the quantity of ingredient can be a long value, but you are using Integer.parseInt() and int[] arrays for storing the quantity. You must change this to long to read long values from the input.
int[] totIngredientInLabArray = convertToIntegerArray(totIngrdientsArr);
for (int i = 0; i < size; i++) {
totIngredientInLabArray[i] = Integer.parseInt(totIngrdientsArr[i]);
}
You are converting the String array to an int array with your helper method convertToIntegerArray(), but then you are doing it again with the for loop. You can skip one of the two.
You might also want to check at: What is a debugger and how can it help me diagnose problems?

Eclipse console apparently bugged calculating factorial of 1,000,000

Doing some tests with a friend about the class BigInteger on Java, he made a code that prints "n: " and receive an given number to find its factorial. After some time, I tried to calculate the factorial of 1,000,000, but then (after several minutes of calculations) the console only showed a a lot of zeros, without even the print "n: " that's printed when I run the program and the "n!: " when the result is shown.
In the tests, until 300k, the code was working fine (except for the time to the calculus, but that's under expectations given the numbers). Obs.: the loop is used to separate the lines, since they only support 4096 chars
public static BigInteger zero = new BigInteger("0");
public static BigInteger one = new BigInteger("1");
public static BigInteger minusOne = new BigInteger("-1");
public static BigInteger fat(BigInteger n) {
if(n.equals(zero)) {
return new BigInteger("1");
}
BigInteger i = new BigInteger(n.toString());
while(!i.equals(one)) {
i = i.add(minusOne);
n = n.multiply(i);
}
return new BigInteger(n.toString());
}
public static void main(String[] args) throws IOException {
Scanner in = new Scanner(System.in);
System.out.print("n: ");
BigInteger bigInt = new BigInteger(in.nextLine());
String bigString = fat(bigInt).toString();
int strSize = bigString.length();
System.out.println("n! = ");
for (int i = 0; i < strSize; i++) {
if((i+1)%4096==0) {
System.out.printf("%c\n",bigString.charAt(i));
}else {
System.out.print(bigString.charAt(i));
}
}
in.close();
}
}
Supposedly there was to happen some output, just not a bunch of zeros and apparently overwriting the first print. Even with large numbers such as 300k, the prints "n: " and "n!: " stayed there. There's no error's messages about Overflow or Stack Overflow. At some point I thought that the console was only showing last part of the number, but asking a friend, he said about some unknown bug of the console or Eclipse (at least for us).

Sorting an array of students by last name alphabetically in Java

I currently have this program read the contents of a text file and calculate the averages and amount of test scores taken and print them out neatly in a small data table. These are the names, amount of quizes taken and average of each student:
James Tiberius Kirk 8 91.63
Buffy Summers 7 83.14
Tom Baker 15 100.00
Malcolm Reynolds 9 84.22
Elizabeth Bennet 9 93.33
John Blutarsky 9 0.00
Dorthy Gale 6 85.83
All of these Students are stored within the Array named Anames[]. I was wondering if it was at all possible to sort these students alphabetically by last name using the code that I have now. When I run the program it gives me the error:
Exception in thread "main" java.lang.StringIndexOutOfBoundsException: String index out of range: -1
at java.lang.String.substring(String.java:1927)
at text.reader.TextReader.compareLastNames(TextReader.java:117)
at text.reader.TextReader.main(TextReader.java:94)
Here is the code of my main class:
public static void main(String[] args)throws IOException{
Double score=0.0;
int b,j;
String tempfirst = "";
String templast = "";
Student Anames[] = new Student[30];
Student Temp[] = new Student [1];
int Stucount = 0;
Scanner reader = new Scanner(new File("quizScores.txt"));
boolean runProgram = true;
PrintWriter writer = new PrintWriter(new File("scoreReport.txt"));
//prints header for report
System.out.println("Name Number Quizes Quiz Socres");
writer.println("Name Number Quizes Quiz Socres");
//check to see if end of file string
while (!reader.hasNext("-10")){
String name="", first="", last="";
//gets the name from file
while(!reader.hasNextDouble()){
last = reader.next();
while (!reader.hasNextDouble()){
first = first+reader.next()+" ";
}
name=first+last;
}
//creates new student with given name
Student newStudent = new Student(first, last);
Anames[Stucount] = newStudent;
Stucount++;
//gets the quiz scores and makes sure does not averge in the end of file string.
while (reader.hasNextDouble()&& !reader.hasNext("-10")){
newStudent.addQuiz(reader.nextDouble());
}
//Prints out the formated data
System.out.printf("%-30s%4.0f%30.2f \n",newStudent.getName(), newStudent.getQuizNumber(), newStudent.getAverage());
writer.printf("%-30s%4.0f%30.2f",newStudent.getName(), newStudent.getQuizNumber(), newStudent.getAverage());
writer.println();
}
System.out.println("\n");
for (b = 0; b < Stucount; b++){
int INTEGERTEMP = b;
for (j= b+1; j < Stucount; j++){
int INTEGERTEMP2 = j;
if ((compareLastNames(Anames[INTEGERTEMP].getLAST(), Anames[INTEGERTEMP2].getLAST()))>0){
Temp[0] = Anames[b];
Anames[b] = Anames[j];
Anames[j] = Temp[0];
}
}
}
System.out.println("Name Number Quizes Quiz Socres");
for (int i = 0; i < Stucount; i++) {
System.out.printf("%-30s%4.0f%30.2f \n", Anames[i].getName(), Anames[i].getQuizNumber(), Anames[i].getAverage());
}
writer.close();
}
private static int compareLastNames(String a, String b){
int index_a = a.lastIndexOf(" ");
String surname_a = a.substring(index_a);
int index_b = b.lastIndexOf(" ");
String surname_b = b.substring(index_b);
int lastNameCmp = surname_a.compareToIgnoreCase(surname_b);
return lastNameCmp;
}
Here is the Student.java which contains most of the methods used:
public Student (String inName, String inLast){
studentName=inName;
studentLast = inLast;
quizAverage = 0;
quizScore=0;
numberQuizes=0;
}
public void addQuiz(double inQuiz){
quizScore += inQuiz;
numberQuizes++;
}
public double getAverage(){
quizAverage = quizScore/numberQuizes;
return quizAverage;
}
public String getName(){
return studentName+studentLast;
}
public double getQuizNumber(){
return numberQuizes;
}
public String getLAST(){
return studentLast;
}
You can use java.util.Arrays.sort(Student [] arr, Comparator<Student> comp) instead of your own compare code. In single line you can achieve it like this:
Student arr[];//considering this array you will populate
Arrays.sort(arr,new java.util.Comparator<Student>(){
public int compare(Student o1, Student o2) {
return o1.studentLast.compareTo(o2.studentLast);
}
});
//then the arr will be sorted with studentLast name
Let's work our way back from your exception to figure out where the problem is. First, it tells us we've got a StringIndexOutOfBoundsException on line 117; that is, the line (it might actually be the surname_b line, you've removed code from the class that means I can't match up the lines properly)
String surname_a = a.substring(index_a);
You'll notice the message from the exception helpfully tells us that the index used was -1. Let's take a look at why a.lastIndexOf(" "); would return -1. We see in the documentation for String that it returns -1 when the character does not occur in the String.
Now, let's work another step back in the Exception's stack trace to figure out why there's no space in that String. The Exception tells us to check line 94, where we see
if ((compareLastNames(Anames[INTEGERTEMP].getLAST(), Anames[INTEGERTEMP2].getLAST()))>0){
So, what's going on here? We're passing in the last names (and just the last names) from each of the students into our comparison function. The last names, for the most part, have no spaces in them.
So, how do we fix this? Well, you'll have to change your function to only take substrings of the surname if there actually is a space in them, i.e. if the index returned isn't -1.
Once you've got the comparison function done, I recommend looking at how to write an Object that implements the Comparable interface. This will allow you to use library sorting functions, which will be faster and less buggy than your own sorting functions (most likely!).

Math.random called from for loop produces continous "random" numbers

im pretty new to java stuff. At the moment i am trying to write a programm dealing with the birthday problem(wikipedia). I want to know how many people have to be asked for their day and month of birth until one is duplicate.
I wrote a class doing the "asking" with the following code:
public class Starter {
static ArrayList<Integer> peeps = new ArrayList<Integer>();
static boolean match = false;
static int counter = 0;
public static int doRand() {
int rand = (1 + (int) (Math.random() * ((365 - 1) + 1)));
return rand;
}
public static int start() {
do {
int buffer = 0;
buffer = doRand();
if (peeps.isEmpty()) {
peeps.add(doRand());
}
counter++;
for (int i = 0; i < peeps.size(); i++) {
if (peeps.get(i) == buffer) {
match = true;
}
}
peeps.add(buffer);
} while (match == false);
return counter;
}
}
This seems to work and produces numbers somewhat between 10 and 50.
But if I run this function from the following for-loop, I get really strange result:
public class BirtdayProblem {
public static void main(String[] args) {
for (int i=0;i< 1000;i++) {
System.out.println(Starter.start());
}
}
}
It produces an output of 1000 continous numbers...why?
If I run the function multiple times manually, i have never gotten any continous number...
Can someone explain that to me?
Example Output:
25
26
27
...
...
1016
1017
1018
1019
1020
1021
1022
1023
1024
Does not look ver yRandom to me...?
Starter.start() returns the static "counter" value which is incremented by 1 after every iteration in the for loop , hence the output shows the output in increments of 1 .
You are using static member variables for counter and match. That means they belong to the class and will not be reset between calls to start().
Since these variables are used only inside the start() method I suggest you put their declarations there as well.
public static int start() {
boolean match = false;
int counter = 0;
And remove the old declarations at the top.

Categories

Resources