I am trying to solve this problem on hackerrank and it took me a while to get to the trick.
The trick lies in property of xor and the number of times a number appears in a subset of array where a subset is contiguous one (kindly note).
So if we have 1,2,3 the subsets will be:
1
1,2
1,2,3
2
2,3
3
The number of times a value at index i appears in these subsets is (n-i)*(i+1) as it can be seen that 1 appears (3-0)*(0+1) = 3 times. n is the length of the array.
Second trick is XOR of a number is 0 with itself if we take that number even number of times and if it appears odd number of times the answer is the number itself, also the important thing to note is XOR operation is associative.
The problem asks us to xor the subsets and then take XOR of each resultant value.
So rather than brute force approach, I counted the number of times each number appears in array and checked out whether it occurs even number of times or odd number of times but 8 testcases passed and 4 failed. The test case are too long to debug or dry run.
My question is why 4 testcase failed. Here is the Java code.
import java.io.*;
import java.util.*;
import java.text.*;
import java.math.*;
import java.util.regex.*;
public class J {
static int []arr=new int[100000];
static int an;
public static void main(String[] args)throws IOException {
/* Enter your code here. Read input from STDIN. Print output to STDOUT. Your class should be named Solution. */
int t,i,j,n;String []s;
BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
t=Integer.parseInt(br.readLine());
int []ans=new int[t];
for(i=0;i<t;++i)
{
n = Integer.parseInt(br.readLine());
s=br.readLine().split(" ");
j=0; an=0;
for(String str:s)
arr[j++]=Integer.parseInt(str);
for(j=0;j<n;++j)
{
if(((j+1)*(n-j))%2==1)
an=an^arr[j];
}
ans[i]=an;
}
for(i=0;i<t;++i)
System.out.println(ans[i]);
}
}
The reason is overflow in
(j+1)*(n-j)
The product may be ~10^10 cause the total size of array is up to 10^5.
So you need to calculate this product using long.
I tested your code with this dummy change:
long a = j + 1;
long b = (n - j);
if((a*b)%2==1) {
an=an^arr[j];
}
And program passed all tests successfully.
Related
I tried a question from a contest whose exact statement is like this:
Given a number N. The task is to find the unit digit of factorial of given
number N.
Input:
First line of input contains number of testcases T. For each testcase, there
will be a single line containing N.
Output:
For each testcase, print the unit digit of factorial of N.
Constraints:
1 <= T <= 1000
1 <= N <= 1018
and came up with following code:
import java.util.*;
import java.lang.*;
import java.io.*;
class GFG {
public static void main (String[] args) throws IOException{
BufferedReader reader =
new BufferedReader(new InputStreamReader(System.in));
int cases = Integer.parseInt(reader.readLine());
int i=0;
while(i<cases){
fact(Integer.parseInt(reader.readLine()));i++;
}
}
static void fact(int num){
int j,fact=1;
for(j=1;j<=num;j++){
fact=fact*j;
}
System.out.println(fact%10);
}
}
It gives right output when executed with custom inputs but when all test cases are tried it gives:"TIME LIMIT EXCEEDED. Optimise your code". I tried to use bufferedReader instead of Scanner class but to no effect. I could not find out how could I optimise this code further. Is there anything I am missing?
The difference between BufferedReader and Scanner probably won't be noticeable here. If you benchmark your code you'll probably find that the heaviest part of it the factorial calculation. Offhand, I can't think of a faster way to calculate it, but the trick here that you probably don't have to.
Let's examine the first few factorials:
0! = 1 -> Unit digit is 1
1! = 1 -> Unit digit is 1
2! = 2 -> Unit digit is 2
3! = 6 -> Unit digit is 6
4! = 24 -> Unit digit is 4
5! = 120 -> Unit digit is 0
Any factorial of 6 or larger would be some natural integers multiplied by 5!, which is 120. So, no matter what they are, the unit digit will be 0. With such a small data set, you can just create a cache of all the options instead of calculating the factorial each time over. E.g.:
// The index is the factorial to be calculated, the value is the unit digit:
private static final int[] UNITS = new int[] {1, 1, 2, 6, 4};
private static void fact(int f) {
int unit = 0;
if (f <= 4) {
unit = UNITS[f];
}
System.out.println(unit);
}
You don't have to compute factorials for this problem. The units digit of fact(n) is going to be 0 for n > 4. (I'd make a small table for the other possible inputs.)
Project Euler problem 8 involves finding the largest product of 13 consecutive digits in a 1000-digit number. I've tried to solve this problem with the code below, but the results I am getting are too small by a factor of about 10. What have I done wrong?
import java.util.Scanner;
import java.util.*;
public class eight {
public static void main(String[] args) {
String number="7316717653133062491922511967442657474235534919493496983520312774506326239578318016984801869478851843858615607891129494954595017379583319528532088055111254069874715852386305071569329096329522744304355766896648950445244523161731856403098711121722383113622298934233803081353362766142828064444866452387493035890729629049156044077239071381051585930796086670172427121883998797908792274921901699720888093776657273330010533678812202354218097512545405947522435258490771167055601360483958644670632441572215539753697817977846174064955149290862569321978468622482839722413756570560574902614079729686524145351004748216637048440319989000889524345065854122758866688116427171479924442928230863465674813919123162824586178664583591245665294765456828489128831426076900422421902267105562632111110937054421750694165896040807198403850962455444362981230987879927244284909188845801561660979191338754992005240636899125607176060588611646710940507754100225698315520005593572972571636269561882670428252483600823257530420752963450";
String input = "782";
int value = 782;
List<Integer> x = new ArrayList<Integer>();
for (char ch : number.toCharArray()){
int element_add=Character.getNumericValue(ch);
x.add(element_add);
}
int check_count=0;
int multiply_value=0;
int multiply_value_max=0;
while(check_count<986){
multiply_value=(x.get(check_count))*(x.get(check_count+1))*(x.get(check_count+2))*(x.get(check_count+3))*(x.get(check_count+4))*(x.get(check_count+5))*(x.get(check_count+6))*(x.get(check_count+7))*(x.get(check_count+8))*(x.get(check_count+9))*(x.get(check_count+10))*(x.get(check_count+11))*(x.get(check_count+12));
if(multiply_value>multiply_value_max){
multiply_value_max=multiply_value;
}
check_count++;
}
System.out.println(multiply_value_max);
}
}
The problem you have is that the upper bound for the answer can be greater than maximum value of int. Therefore, you need to use the BigInteger class, or at the very least long, to store the result. To ensure that the operations are carried out with sufficient precision, you want to store the individual digits in the same precision or convert them to the precision as you multiply them.
You can also save yourself some typing and boilerplate errors by handling the consecutive multiplication with a for loop.
Hi people I made code to calculate greatest common divisor of 2 number.
It work good but I get many outputs. I want the greatest output but I don't know how to fix it?
What my code do is this here: You enter 2 integer. The first integer must be greater than the second. Now code check second integer first. Is it dividable by 1, 2, 3, 4, 5, .. Then code check all working numbers with first number. In the end we have greatest common divisor.
And before code does all it, it check if second number divide first (in case second is the gcd).
Now my problem: Let's take input 36 and 14. My code will give output
1
2
But how can I avoid code also print all other working numbers? I only want printed the greatest working number but no idea how to implement this in my code? I also don't want copy other code because I did all myself till here and proud:
import java.util.Scanner;
public class Testit{
public static void main(String[] args){
Scanner input = new Scanner(System.in);
double x = input.nextDouble();
double y = input.nextDouble();
double first=0;
first=x/y;
if(first==(int)first){
System.out.println((int)y);
return;
}
else{
for(double i=1; i<x && i<y; i++){
double sum=0;
sum=y/i;
if(sum==(int)sum){
double temp=0;
temp=x/i;
if(temp==(int)temp){
System.out.println((int)i);
}
}
}
}
}
}
Instead of printing, save the result in a temporary variable
double first=0;
int greatestCommonDivisor = 1;
...
if(temp==(int)temp){
greatestCommonDivisor = Double.valueOf(i).intValue();
}
...
System.out.println("Greatest common divisor:" + greatestCommonDivisor);
That said, there are a lot of places your algorithm and code could be improved. For a start you should think about starting at the largest possible number and just stopping when you found the first common divisor (because that would be the greatest) instead of looping through all possible numbers starting from the smallest possible number. And you should have a look at the modulo operation and use integers instead of doubles for your values.
You have to change your code; for example like this:
Currently, your code is simply printing each time it finds a "match".
Instead of printing immediately, you push that value into a helper variable. And in the end; when your loop has ended, you simply print that helper variable!
Then you automatically print the last number that your algorithm computed and stored.
( I am not giving you any code here; just an idea - as you will learn more by writing the code yourself! )
Here is what I have to do...
Input File: dishin.txt
Output File: dishout.txt
Time Limit: 1 second
You do not like statisticians, and statisticians do not like you. Ever since that life actuary kicked sand into your ice cream when you were four, you have waged a slowly escalating war against those number-crunching jerks. But all that is about to change.
After many sleepless nights you have conceived the ultimate revenge: beating them at their own game. Using your computer programming skills, you will write a freeware statistics package so thorough, so complete, that statisticians all around the world will be out of a job. It will be able to predict weather patterns, calculate life expectancies, and even play the perfect poker game.
First, though, you must implement word wrap. However, this task is rather finnicky, not very mathematical in nature, and ultimately not very important. More urgently, you also need to implement some basic data analysis. Specifically, you decide to write a test program that takes a data set (a list of integers) and calculates the following measures of spread:
Minimum - the smallest value in the list. For example, the minimum of the numbers {5, 6, 5, 3} is 3.
Maximum - the largest value in the list. For example, the maximum of the numbers {5, 6, 5, 3} is 6.
Mean (or average) - defined as the sum of everything in the list divided by the number of items in the list. For example, the mean of the numbers {5, 6, 5, 3} is (5+6+5+3)/4 = 19/4 = 4.75. However for simplicity you are asked to round all answers down to the nearest whole number. So the mean of the numbers {5, 6, 3, 3}, rounded down, is 4.
Input:
The first line of input will consist of a single integer n (1 <= n <= 1,000), the size of your data set. The following n lines will describe the data set. Each of these lines contains an integer between 0 and 1,000,000 inclusive.
Output
The output file should consist of three integers separated by spaces: the minimum, maximum and mean of the data set.
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Scanner;
public class Solution {
public static void main(String[] args) throws IOException {
///home/sebastian/workspace/Informatics Competition/src/
Scanner input = new Scanner(new File("/home/sebastian/workspace/Informatics Competition/src/dishin.txt"));
BufferedWriter output = new BufferedWriter(new FileWriter("/home/sebastian/workspace/Informatics Competition/src/dishout.txt"));
ArrayList<Integer> numbers = new ArrayList<Integer>();
while(input.hasNextInt()) {
numbers.add(input.nextInt());
}
numbers.remove(0);
Object max = Collections.max(numbers);
Object min = Collections.min(numbers);
System.out.println(numbers);
int sum = 0;
for (int i = 0; i<=numbers.size(); i++) {
sum += (int)(numbers.get(i));
}
int mean = (int)(sum / numbers.size());
output.write(String.valueOf(min+" "+max+" "+mean));
input.close();
output.close();
}
}
Here is the error:
Exception in thread "main" java.lang.IndexOutOfBoundsException: Index: 4, Size: 4
at java.util.ArrayList.rangeCheck(ArrayList.java:638)
at java.util.ArrayList.get(ArrayList.java:414)
at Solution.main(Solution.java:35)
It should be
for (int i = 0; i<numbers.size(); i++)
instead of
for (int i = 0; i<=numbers.size(); i++)
index must be less than the size of the numbers. Index starts from 0 till (size - 1)
Use The For-Each Loop to avoid such issues if you are interested to iterate each and every item of the array.
For-each loop (Advanced or Enhanced For loop):
The for-each loop introduced in Java5. It is mainly used to traverse array or collection elements. The advantage of for-each loop is that it eliminates the possibility of bugs and makes the code more readable
Syntax of for-each loop:
for(data_type variable : array | collection){}
I'm trying to solve problem #299 - Train Swapping in website UVa Online judge. The code I have works fine for independent test cases. However, when I use the sample input they provide, my program omits one of the test cases, the last one to be more specific:
Here is my code:
import java.util.Scanner;
public class Tester {
void problem(){
Scanner imput = new Scanner(System.in);
int numT =imput.nextInt();
int numL, aux, swaps=0;
int [] train = new int [50];
for (int i =0; i<numT; i++) {
numL = imput.nextInt();
for (int m =0; m< numL; m++) {
train[m]=imput.nextInt();
}
for (int j=0; j<numL; j++) {
if (train[j]>train[j+1]) {
for (int k =j; k<numL-1;k++) {
aux = train[k];
train[k]=train[k+1];
train[k+1]=aux;
swaps++;
}
}
}
System.out.println("Optimal train swapping takes "+swaps+" swaps.");
swaps = 0;
}
}
}
Example Input:
3
3
1 3 2
4
4 3 2 1
2
2 1
Example Output:
Optimal train swapping takes 1 swaps.
Optimal train swapping takes 6 swaps.
Optimal train swapping takes 1 swaps.
My code prints until the second solution, then for some reason stops. I've tried to debug it and check what's going on step by step but it has driven me to a migraine point. Any insight is highly appreciated.
...
To be more precise it stops at the second for loop the third time around without taking anything into the array...and I don't know why!
Another thing I found out is that to solve this problem the number of swaps for the case of the middle is 6, therefore the bubble sort wont be useful here, since it makes over 10 swaps thus yielding a wrong output, this is a separate issue to the original one I presented however. I still haven't figure out why it stops the third time around the loop where I assign values to the array for the third time.
The input consists of:
first line is number of cases.
this line enters the length of a train ex: 4
this line enters the number of the wagons ex: 2 4 3 1
the next following lines correspond to the following test cases whose structure is the same as the example.
They ask you to arrange the train and tell the number of swaps made to make the train in order.