Why is the result of my int multiplication wrong? - java

I have the the following code where the results exceeds the limit an integer type variable can store and need to understand why I am getting this result (268,435,456=2^28)
public static void main(String[] args) {
int x = 16+256;
for( int i =0; i<6; i++) {
x*=16;
}
System.out.println(x);
}
}

Consider how this looks with all the values expressed in binary.
Initially, x = 00000000000000000000000100010000. Then every time you multiply by 16, you add 4 zeroes to the right, and remove 4 digits from the left.
So you get results like
00000000000000000001000100000000
00000000000000010001000000000000
and so on. But once you've done this 6 times, the first 1 disappears off the left end of the number - this is the integer overflow. So you're left with
00010000000000000000000000000000
which is 2 to the 28.

Related

Rotate Array by k

Given an array and a number k we have to rotate array k times.
Sample Input
1 //number of of testcases
5 2 //5(array size) 2(K value)
1 2 3 4 5 /array elements
Sample output
4 5 1 2 3
Here is my code
import java.util.*;
class TestClass {
public static void main(String args[] ) throws Exception {
// Write your code here
Scanner input=new Scanner(System.in);
int testcases=input.nextInt();
for(int i=0;i<testcases;i++)
{
int size=input.nextInt();
int rotationNo=input.nextInt();
rotateArray(size, rotationNo, input);
}
}
public static void rotateArray(int size, int rotationNo, Scanner input)
{
int[] arr=new int[size];
int[] result=new int[size];
rotationNo=rotationNo%size;
for(int i=0;i<size;i++)
{
arr[i]=input.nextInt();
}
int resultIndex=0;
int index=size-rotationNo;
int k=index,t=0,track=0;
while(true)
{
if(k<size)
{
System.out.print(arr[k++]+" ");
++track;
if(track==size)
{
break;
}
else
{
continue;
}
}
if(t<index)
{
if(t==(index-1))
{
System.out.print(arr[t++]);
}
else
{
System.out.print(arr[t++]+" ");
}
++track;
if(track==size)
{
break;
}
else
{
continue;
}
}
}
System.out.println();
}
}
This question was asked in a programming competition. My all testcases were passing except one which showed time limit exceeded. But I am not understanding what is the cause of time limit exceed. Loops will always halt whatever be the testcase.
Time Complexity of my code is O(n).
Is there another better and efficient solution?
Start outputting the input directly (i.e. without storing it) as soon as k values have been read and stored.
Then output the k initially read and stored values.
The shifting inside the array, is the relevant operation here.
The fewer shifts are done (the distance of shifting is not really relevant here, if implemented correctly), the better. It includes the storing and retrieving to/from an array. I consider the reading and outputting, if done without any processing in between, to be negligible. I.e. I focus on the shifting.
Strictly speaking, the reading and outputting is processing and that would mean that no improvement of O() can be calculated.
But allow me to ignore the reading and outputting for an O() estimation of the improvement:
The proposed recommendation will improve the number of array-accesses during shifting from O(n) to O(k). Admittedly the reading and outputting is ignored here. Storing and retrieving from an array and especially the shifting inside the array is avoided here and that is the O(k) part which is relevant here.
So the relevant operations are O(k), ignoring n-k values in O(1).
A test case like
1
10000 1
1 2 3 4 5 6 7 8 ...
will easily eliminate programs which after reading and before outputting, do O(4*10000), i.e. store all, read and write all for shifting and then read all for outputting. Compared to O(2*1) for only storing a single value and reading again for outputting at the end.
(Yes, I know clean O() analysis does not use factors, or any digits. You stil get the point, I hope. ;-)
Here is a code proposal (simplified to a single testcase):
import java.util.*;
public class Test {
public static void main(String[] args)
{
Scanner input = new Scanner(System.in);
int testcases= input.nextInt(); //ignored, assuming 1
int size = input.nextInt();
int rotation = input.nextInt();
int i=0;
int[] newArr = new int[rotation%size]; //small array
// based on the nice idea by User-Upvotedon'tsayThanks
for(; i<rotation%size; i++)
{
newArr[i] = input.nextInt(); // few write accesses
}
for(; i<size; i++)
{
System.out.println( input.nextInt()); //many direct outpots
}
for(i=0; i<rotation%size; i++)
{
System.out.println(newArr[i]); // few outputs from array
}
return;
}
}
For an input of:
1
5 2
1 2 3 4 5
It gets you an output of:
3
4
5
1
2
Same output for a modulo-requiring input of:
1
5 7
1 2 3 4 5
I have provided a solution below which will directly output the scanner input up until the size of input has been met. It has a constant time o(n) for input, however it only touches each item once. and avoids the use of a while loop that may otherwise increase the multiplier of the iterations.
public class Test {
public static void main(String[] args) {
int rotation = new Scanner(System.in).nextInt();
int size = new Scanner(System.in).nextInt();
int[] values = rotate(rotation, size, new Scanner(System.in));
for(int i : values){
System.out.println(i);
}
}
public static int[] rotate(int rotation, int size, Scanner input){
int[] newArr = new int[size];
for(int i = 0; i<size; i++){
int newPosition = i + rotation;
newPosition = newPosition >= size ? newPosition - size : newPosition;
newArr[newPosition] = input.nextInt();
}
return newArr;
}
}

Getting Time limit exceeded error in java

class Check {
static void countOddEven(int a[], int n) {
int countEven = 0, countOdd = 0;
for (int item : a) {
if (item % 2 == 0) {
countEven++;
}
}
countOdd = n - countEven;
System.out.println(countOdd + " " + countEven);
}
}
Code is to calculate even and odd numbers in an array. Please help to optimise the code.
You’re code is not correct.
If you were meant to count the even and odd numbers in a, then you are counting the even numbers correctly. If n is not equal to the length of a, then your calculation of the count of odd numbers is incorrect.
If on the other hand — and I’m just guessing — you were meant to count the even and odd numbers among the first n elements, then you are counting the even numbers incorrectly since you are iterating over all of a. Also in this case, if n is much smaller than the length of a, there is an optimization in only iterating over the first n elements as you should.
Finally you may try the following version. I doubt that it buys you anything, but I am leaving the measurements to you.
int countOdd = 0;
for (int ix = 0; ix < n; ix++) {
countOdd += a[ix] & 1;
}
int countEven = n - countOdd;
The trick is: a[ix] & 1 gives you the last bit of a[ix]. This is 1 for odd numbers and 0 for even numbers (positive or negative). So we are really adding a 1 for each odd number.
You should try running code with for loop instead of for each loop
Because ,
When accessing arrays, at least with primitive data for loop is dramatically faster.
however
When accessing collections, a foreach is significantly faster than the basic for loop’s array access.
but if you are getting some another errors , so might have done something wrong while calling the method (make sure n=length of your array)
here is the whole code with main method.
class Check{
static void countOddEven(int a[], int n){
int countEven=0,countOdd=0;
for(int i=0;i<n;i++)
if(a[i]%2==0)
{
countEven++;
}
countOdd=n-countEven;
System.out.println(countOdd+" "+countEven);
}
public static void main(String[] arg){
int a[]={2,3,4,5,6};
int n = 5;
countOddEven(a,n);
}
}

product of the numbers in list in java

My task here is to find the minimal positive integer number say 'A' so that the product of digits of 'A' is exactly equal to N.
example: lets say my N = 32
so my A would be 48 coz the divisors of 32 would be 1,2,4,8,16,32 and the minimum numbers that would make 32 is 4 and 8. so output is 48.
what i did is first read N, then found the divisors and stored them in a list. and used
if(l.get(i)*l.get(i+1)==N) {
sysout.print(l.get(i));
sysout.print(l.get(i+1));
but im not able to make the numbers as minimum. and also i need to print as -1 if no match is found.
for that i did:
if (l.get(i)*l.get(i+1)!=N) {
System.out.print(-1);
break;
}
but it is printing -1 initially only and breaking off. now im stuck here. please find my code below:
my code:
int N=1;
Scanner in = new Scanner(System.in);
List<Integer> l = new ArrayList<Integer>();
System.out.println("Enter N: ");
if (N>=0 && N<=Math.pow(10, 9)) {
N = in.nextInt();
}
for (int i=1; i<=N;i++) {
if (N%i==0) {
l.add(i);
}
}
System.out.println(l);
for (int i=0; i<l.size()-1;i++) {
if (l.get(i)*l.get(i+1)==N) {
System.out.print(l.get(i));
System.out.print(l.get(i+1));
}
}
in.close();
kindly help. thanks.
You're on the right track with finding the divisors on N. I'm not going to code it for you(you'll learn more by doing) but here's what you do: The divisors will be sorted already so loop the arraylist adding first to last and finding the min.
So for 1,2,4,8,16,32: Find 1+32, 2+16, 4+8; And then fin the max among these.
This is to get you started:
int first = 0;
int last = l.size()-1;
while(first<last){
//Find min using Math.min;
++first;
--last;
}
Happy Coding!
Could not resist. Below is a quick way to do what you want. Tested it here
(https://ideone.com/E0f4X9):
public class Test {
static ArrayList<Integer> nums = new ArrayList<>();
public static void main(String[] args){
int N =32;
findDivisors(N);
int first = 0, a = 0, b = 0;
int last = nums.size()-1;
int results = Integer.MAX_VALUE;
while(first < last){
int sum = nums.get(first) + nums.get(last);
results = Math.min(sum,results);
a = nums.get(first);
b = nums.get(last);
first++;
last--;
}
System.out.println(a+" "+b);
}
private static void findDivisors(int n){
for(int i=1; i<=n; i++){
if(n%i == 0){
nums.add(i);
}
}
}
}
Obviously if N<10 then A=N.
Otherwise A has to consist of more than one digit. Every digit of A is a divisor of N. The more significant digits of A always have to be less or equal than the lesser significant digits. Otherwise the order of digits could be changed to produce a smaller number.
For example A could not be 523 because the digits could be rearranged into 235 which is a smaller number. In this example we have 2 < 3 < 5.
Observation #1: when looking at A the smallest digits are at the front, the digits get higher towards the end.
Observation #2, A can never contain two digits a and b if the product of a and b is also a digit. For example, there can never be a 2 and a 3, there would have to be a 6 instead. There could never be three 2s, it would have to be an 8 instead.
This suggests that when building A we should start with the highest possible divisors of N (because a 9 is always better than two 3s, and so on). Then we should put that digit at the end of A.
So, while N > 10, find the highest divisor x of N that is a single digit (2<=x<=9). Add this value x to the end of A. Divide N by x and proceed with the loop.
Example:
N=126, A=?
Highest possible divisor x that is less or equal to 9 is 9. So 9 is going to be the last digit of A.
Divide N by 9 and repeat the process. N=126/9=14.
Now N=14, A=?9
Highest possible divisor x that is less or equal to 9 is 7. We have found the second to last digit of A.
Divide N by 7 and repeat the process. N=14/7=2.
Now N=2, A=?79
N<10. So 2 is the first digit of A.
The solution is A=279

Generate random numbers increasing by multiples of N in Java

I need to write a short randomizer which generates a random number between 1 to N where the random number is increasing by multiples of M.
For example: generate numbers between 1 and (N=30) increasing by multiples of (M=5). The only possible generated numbers can be then: 1,5,10,15,20,25 and 30. Hope you get what I mean :)
Normally if you use new Random().nextInt(30)+1, you get numbers increasing by multiples of 1 (1,2,3,4,5,6,7,etc.). That is not what I want.
Any help, links, or directions are very appreciated?
EDIT:
That the sequence of generated random numbers could include 1 not zero is one of the requirements of the method. Precisely, the sequence always starts with the lower bound (min). In the example the lower bound is 1 and therefore there can't be zero in the sequence. It's odd I know, but those are the requirements I have to follow ;)
You could multiply the random value by 5. Since you want to have 1 instead of 0 just look for that value and alter it specifically:
static final Random random = new Random(System.currentTimeMillis());
public int random(int range, int multiple) {
int value = random.nextInt(range / multiple) * multiple;
return value == 0 ? 1 : value;
}
I think that your example is a little bit flawed: the sequence should be (0, 5, 10, 15, 20, 25, 30)
If I'm correct, you can then use:
new Random().nextInt(7) * 5; // will generate a number between 0 and 7 not included then multiply by 5 which should give what you want
If you want to start by 1, then just add it to the previous statement
Try this..
public static void main(String[] args){
int N = 50;
int M = 5;
System.out.println(getRandomNumber(N, M));
}
static int getRandomNumber(int n, int m){
Random r = new Random();
int rnd = r.nextInt(n);
return rnd%m == 0?rnd:getRandomNumber(n, m);
}
int n=Random.range(1,10);
n=n*100;

Use of integers and doubles give different answers when they shouldn't

I'm solving a Project Euler Problem 14 using java. I am NOT asking for help solving the problem. I have already solved it, but I ran into something I can't figure out.
The problem is like this:
The following iterative sequence is defined for the set of positive
integers:
n = n/2, if n is even
n = 3n + 1, if n is odd
Using the rule above and starting with 13, we generate the following
sequence:
13 -> 40 -> 20 -> 10 -> 5 -> 16 -> 8 -> 4 -> 2 -> 1. Here, the length of the chain is 10 numbers.
Find the starting number below 1,000,000 that produces the longest chain.
So I wrote this code:
public class Euler014 {
public static void main(String[] args){
int maxChainCount = 0;
int answer = 0;
int n;
int chainCount = 1;
for(int i = 0; i < 1000000; i++){
n = i;
while(n > 1){
if(n%2 == 0){ //check if even
n /= 2;
}else{ //else: odd
n = 3*n + 1;
}
chainCount++;
}
if(chainCount > maxChainCount){ //check if it's the longest chain so far
maxChainCount = chainCount;
answer = i;
}
chainCount = 1;
}
System.out.println("\n\nLongest chain: i = " + answer);
}
}
This gives me the answer 910107, which is wrong.
HOWEVER, if i change the type of my n variable to double n it runs and gives me the answer 837799, which is right!
This really confuses me, as I can't see what the difference would be at all. I understand that if we use int and do divisions we can end up rounding numbers when we don't intend to. But in this case, we always check to see if the n is divisble by 2, BEFORE dividing by 2. So I thought that it would be totally safe to use integers. What am I not seeing?
This is the code in its entirety, copy, paste and run it if you'd like to see for yourself. It runs in a couple of seconds despite much iteration. =)
Your problem is overflow. If you change int n to long n, you'll get the right answer.
Remember: The numbers in the sequence can be really big. So big they overflow int's range. But not (in this case) double's, or long's.
At one point in the chain, n is 827,370,449 and you follow the 3n + 1 branch. That value wants to be 2,482,111,348, but it overflows the capacity of int (which is 2,147,483,647 in the positive realm) and takes you to -1,812,855,948. And things go south from there. :-)
So your theory that you'd be fine with integer (I should say integral) numbers is correct. But they have to have the capacity for the task.

Categories

Resources