public class Program {
public static void main(String[] args) {
int x = 1;
for (int i = 1; i < 31; i++) {
x = x + 2 * x;
}
System.out.println(x);
}
}
It prints -1010140999 and I don't know why it is negative number.
Final output is a very long number which will exceed the max integer capaxity. Hence we need to use long data type. Please check the correct code below with x value at each iteration
public class Program {
public static void main(String[] args) {
long x = 1;
for (int i = 1; i < 31; i++) {
x = x + 2l * x;
System.out.println(i+ " " +x);
}
}
}
Output
1 3
2 9
3 27
4 81
5 243
6 729
7 2187
8 6561
9 19683
10 59049
11 177147
12 531441
13 1594323
14 4782969
15 14348907
16 43046721
17 129140163
18 387420489
19 1162261467
20 3486784401
21 10460353203
22 31381059609
23 94143178827
24 282429536481
25 847288609443
26 2541865828329
27 7625597484987
28 22876792454961
29 68630377364883
30 205891132094649
An integer in Java is stored with 32 bits, of which one is used to indicate whether the value is positive or negative. This means an int's value is between -2^31 and 2ˆ31 - 1.
Once you add or subtract past those limits, you wrap around in the corresponding direction since an overflow/underflow occurs.
public class OverflowExample {
public static void main(String args[]) {
int largest_int = Integer.MAX_VALUE;
int smallest_int = Integer.MIN_VALUE;
System.out.println(largest_int); // 2ˆ31 - 1 = 2147483647
System.out.println(largest_int + 1); // -2147483648
System.out.println(smallest_int); // -2^31, same as above
}
}
Related
I'm new to programming and it's my first ever question here.
I've been trying to solve this challenge https://www.hackerrank.com/challenges/picking-numbers/problem?isFullScreen=true for three consecutive days but still got 3/10 test cases failed.
Here the algorithm I use:
For each element in the main array create a subarray where all elements are equal or no more or less by 1
Resulting number of subarrays (which equals to the number of elements in the first array) are checked for validity meaning that each element is equal or no more or less by 1
Find the longest valid subarray and return it's size
Here is the code for the solution:
import java.io.*;
import java.util.*;
import java.util.stream.Stream;
import static java.util.stream.Collectors.joining;
import static java.util.stream.Collectors.toList;
class Result {
/*
* Complete the 'pickingNumbers' function below.
*
* The function is expected to return an INTEGER.
* The function accepts INTEGER_ARRAY a as parameter.
*/
public static int pickingNumbers(List<Integer> a) {
int maxLength = 0;
boolean isValidArray = false;
List<Integer> subarray = new ArrayList<Integer>();
for (int i = 0; i < a.size(); i++) {
subarray = findValidSubarray(a, a.get(i));
isValidArray = arrayValidityCheck(subarray);
if ((isValidArray) && (subarray.size() > maxLength)) {
maxLength = subarray.size();
}
}
return maxLength;
}
private static List<Integer> findValidSubarray(List<Integer> array, Integer integer) {
List<Integer> subarray = new ArrayList<Integer>();
for (int elem : array) {
if ((elem == integer) || (elem + 1 == integer) || (elem == integer + 1)) {
subarray.add(elem);
}
}
return subarray;
}
//check that all elements are equal or not more or less than 1 to each other
private static boolean arrayValidityCheck(List<Integer> subarray) {
boolean isValid = false;
for (int i = 0; i < subarray.size(); i++) {
for (int j = 0; j < subarray.size(); j++) {
if ((subarray.get(i) == subarray.get(j)) || (subarray.get(i) + 1 == subarray.get(j)) || (subarray.get(i) == subarray.get(j) + 1)) {
isValid = true;
} else {
isValid = false;
break;
}
}
if (!isValid) {
break;
}
}
return isValid;
}
}
public class Solution {
public static void main(String[] args) throws IOException {
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
String[] firstMultipleInput = bufferedReader.readLine().replaceAll("\\s+$", "").split(" ");
int n = Integer.parseInt(firstMultipleInput[0]);
List<Integer> a = Stream.of(bufferedReader.readLine().replaceAll("\\s+$", "").split(" "))
.map(Integer::parseInt)
.collect(toList());
bufferedReader.close();
int result = Result.pickingNumbers(a);
System.out.println(result);
}
}
Sample test case data which is failing:
100
and
14 18 17 10 9 20 4 13 19 19 8 15 15 17 6 5 15 12 18 2 18 7 20 8 2 8 11
2 16 2 12 9 3 6 9 9 13 7 4 6 19 7 2 4 3 4 14 3 4 9 17 9 4 20 10 16 12
1 16 4 15 15 9 13 6 3 8 4 7 14 16 18 20 11 20 14 20 12 15 4 5 10 10 20
11 18 5 20 13 4 18 1 14 3 20 19 14 2 5 13
Valid answer:
15
My answer:
13
I'm out of ideas where the bug is here.
Could you please help me?
PS: I'm aware that this algorithm is not optimal. Any optimization tips would be much appreciated.
Edit: As pointed out in the comments it is sufficient to do one type of check and only check if the other elements are 1 larger than the first element in the check. Answer modified accordingly
Your problem is that when you build your subarray, you allow numbers in it that are both 1 higher and 1 lower than the first element you start with.
You then later try to clean up your results by re-validating your generated arrays, but this will not fix the problem that you will not generate any all possible valid subarrays with your method.
My proposal to fix your code would be:
Modify your findValidSubarray method so that only allows elements that are 1 higher in it. (The cases where lower numbers would be allowed in will be handled in other iteration when that lower number is the starting element for the iteration)
remove the arrayValidityCheck as this one will no longer be needed as the above will directly only produce valid subarrays.
Modified findValidSubarray method:
private static List<Integer> findValidSubarray(final List<Integer> array, final Integer integer) {
final List<Integer> subarray = new ArrayList<Integer>();
for (final int elem : array) {
if ((elem == integer) || (elem + 1 == integer)) {
subarray.add(elem);
}
}
return subarray;
}
Calling that method:
public static int pickingNumbers(final List<Integer> a) {
int maxLength = 0;
List<Integer> subarray = new ArrayList<Integer>();
for (int i = 0; i < a.size(); i++) {
subarray = findValidSubarray(a, a.get(i));
if ((subarray.size() > maxLength)) {
maxLength = subarray.size();
}
}
return maxLength;
}
I am using binary search to find a balance point between the planets. The method binaryBalance takes in Arraylist of planets which is an object with displacement and mass property. It also takes in the displacement of two planets between which I am trying to find a balance point of. Double x is the inital starting point of the search and I am setting the average displacement of p1 and p2 here. The code runs smoothly but it is off the answer for a minute amount. I try to increase the precision by setting the error interval to more than 1e-10, but I keep getting Stack Overflow error. How do I solve this problem with higher precision?
import java.util.*;
import java.lang.*;
public class Solution {
public static void main(String[] arg) {
Scanner sc = new Scanner(System.in);
int numCase = sc.nextInt();
for (int k = 1; k <= numCase; k++) {
//Initializing Space...
int numPlanets = sc.nextInt();
ArrayList<Planet> space = new ArrayList<>();
int[] weights = new int[numPlanets];
int[] displacements = new int[numPlanets];
for (int i = 0; i < numPlanets; i++) {
displacements[i] = sc.nextInt();
}
for (int i = 0; i < numPlanets;i++) {
weights[i] = sc.nextInt();
}
for (int i = 0; i < numPlanets;i++) {
Planet p = new Planet(displacements[i],weights[i]);
space.add(p);
}
System.out.print("#" + k + " ");
for (int i = 0; i < numPlanets-1; i++) {
double init = (double) (space.get(i).getDisplacement() + space.get(i+1).getDisplacement()) /2;
binaryBalance(space,space.get(i).getDisplacement(),space.get(i+1).getDisplacement(),init);
}
System.out.println();
}
}
public static class Planet {
private int d;
private int m;
public Planet(int d,int m) {
this.d = d;
this.m = m;
}
public void setDisplacement(int d) {
this.d = d;
}
public void setMass(int m) {
this.m = m;
}
public double getG(double dPlanet) {
double betweenDistance = this.d - dPlanet;
return this.m/(betweenDistance*betweenDistance);
}
public int getDisplacement() {
return d;
}
public int getMass() {
return m;
}
}
public static void binaryBalance(ArrayList<Planet> space, double p1, double p2, double x) {
double leftg = 0;
double rightg = 0;
for (int i = 0; i < space.size(); i++) {
if (space.get(i).getDisplacement() < x) {
leftg = leftg + space.get(i).getG(x);
} else {
rightg = rightg + space.get(i).getG(x);
}
}
if (Math.abs(leftg - rightg) < 1e-10) {
System.out.print(String.format("%.10f",x) + " ");
return;
}
if (leftg < rightg) {
binaryBalance(space, p1, x, (p1 + x) / 2);
} else {
binaryBalance(space, x, p2, (p2 + x) / 2);
}
}
Test Cases are:
10
2
1 2 1 1
2
1 2 1 1000
2
457 468 333 321
3
1 2 3 1 2 1
4
2 3 5 7 3 2 7 5
5
3 11 12 19 29 542 661 450 521 366
6
42 75 88 94 113 144 669 551 355 344 294 155
7
62 86 279 323 363 516 579 810 749 736 297 136 107 52
8
10 34 64 73 93 97 101 122 466 463 441 373 315 292 225 83
10
9 14 38 39 48 73 179 190 207 302 560 497 640 722 437 259 449 470 709 520
And the expected answer is:
#1 1.5000000000
#2 1.0306534300
#3 462.5504629633
#4 1.4060952085 2.5939047915
#5 2.5328594461 3.7271944335 6.0999536409
#6 6.3428568767 11.5477377494 15.9641592998 24.9267991615
#7 57.8805685415 81.8651598883 91.0573691382 105.0835650491 133.2934094881
#8 74.2211477711 190.6837563313 305.8269181686 348.3304429927 470.2694219293 555.4943093854
#9 21.5171374463 47.9890597763 68.6536668433 82.9131954023 95.0052272762 99.1999097770 116.4978330953
#10 11.5573600056 24.0238341337 38.4847676134 44.6137453708 64.7500445424 126.9908128982 184.3221650927 197.9760596291 266.0574653677
With the leftg-rightg tolerance of 1e-10, the greatest number of iterations is 47, on the second case where the masses are so different. That won't overflow any stacks, but of course you asked about increasing the accuracy. Unfortunately, it's impossible to even reach 1e-11 on case 6, because of the scale of the numbers involved (as I mentioned in a comment). So you get infinite recursion if you change the tolerance exponent at all.
But maybe a fixed balance tolerance isn't what you're expected to do for this exercise! I get exactly the expected answers (to their given precision) if I instead refine until the interval has "zero" width. (p1 and p2 need not be equal, but there are no floating-point numbers between them. You detect this by noticing that x==p1 || x==p2; x will be whichever ends in a 0 in binary.) This takes at most 53 bisections for these cases: a number which should be familiar to any numerical analyst since it is the effective number of bits in the significand of a double. I didn't check whether a larger p2-p1 tolerance might give the correct answers.
Since it's useless to get (much) above 53 levels deep, the choice of recursion here is harmless (although tail recursion with a void function looks very odd), and changing to iteration won't help at all. Either way, you do have to make sure that it terminates!
Try to use iteration instead of recursion. I also added line with logging of data on each iteration.
public static void binaryBalance(ArrayList<Planet> space, double p1, double p2, double x) {
while(true) {
//You can use this line to log evolution of your data
System.out.println(String.format("p1=%s p2=%s x=%s", p1, p2, x));
double leftg = 0;
double rightg = 0;
for (int i = 0; i < space.size(); i++) {
if (space.get(i).getDisplacement() < x) {
leftg = leftg + space.get(i).getG(x);
} else {
rightg = rightg + space.get(i).getG(x);
}
}
if (Math.abs(leftg - rightg) < 1e-10) {
System.out.print(String.format("%.10f",x) + " ");
return;
}
double p1Tmp = p1;
double p2Tmp = p2;
double xTmp = x;
if (leftg < rightg) {
p1 = p1Tmp;
p2 = xTmp;
x = (p1Tmp + xTmp) / 2;
} else {
p1 = xTmp;
p2 = p2Tmp;
x = (p2Tmp + xTmp) / 2;
}
}
}
This is the same person who had trouble with the last array problem just one or two days ago.
We've a new assignment which asks us to find and replace duplicates in an array of randomly generated numbers. I wrote a code and sent it to my teacher for feedback; she responded with this solution:
So, take the first random num and store into the first slot (this can be done before the loop). Then, start a loop that creates the second random num and tests backwards to see if there are duplicates from the ones already stored. So, a backwards loops that tests for duplicates and counts down to 0 from the current location and replaces duplicates. Once that test passes, then you'll go to the next element, create a new random number, and then test the ones before it for duplicates.
I've done this here, and it's reduced the number of randomly generated numbers, but I still run into the stray duplicate:
import java.lang.Object;
import java.util.Random;
public class Prog433a {
public static void main(String[]args) {
Random randslct = new Random();
int[] list = new int[20];
int counter = 0;
int index = 0;
int min2 = 0;
System.out.println("\nAfter");
for (int k = 0; k < list.length - 1; k++) {
list [k] = randslct.nextInt(30) + 1;
for (int z = list.length - 1; z >= 0; z--) {
if (list[k] == list[z] && z!=k) {
while (list[k] == list[z]) {
list [k] = randslct.nextInt(30) + 1;
}
}
}
}
int min = list[0];
while (counter < list.length - 1) {
for (int x = 0; x < list.length - 1; x++) { // scroll through the indexes.
if (list[x] < min) {
min = list[x];
index = x; // keep the index of the biggest number.
}
}
System.out.println(list[index]);
min = 100 * (list[index]);
list[index] = 100 * (list[index]); // change the value in the original array so it won't find the same max again
counter++;
}
}
}
System Output:
After
2
5
6
10
11
12
13
15
16
17
19
22
22
24
25
27
28
29
29
After
1
2
2
4
5
7
8
9
10
13
15
16
21
24
25
26
28
29
30
After
1
2
3
5
6
7
11
12
13
14
15
16
18
21
22
25
26
27
29
After
2
3
3
4
6
10
12
14
15
16
17
20
22
23
24
25
26
27
30
After
7
8
11
12
13
14
15
16
17
17
18
19
20
21
23
24
27
29
30
I posted my output towards the bottom.
Because this is an introductory coding class, I'd prefer if the solution did not involve Sets or any of the like. But alas, beggars cannot be choosers.
Is there something I have forgotten to add?
Your problem is that when you detect a duplicate you generate a new number, but you never go back and check that the the newly generated number is not a duplicate of the numbers you already checked. When you run into a duplicate you'll need to reset the checking loop through some mechanism.
I fixed up the code to work around the problem, but it's not the prettiest solution. I also did some minor optimisation as you were looping through unnecessary indices.
import java.util.Random;
public class Prog433a {
public static void main(String[] args) {
Random randslct = new Random();
int[] list = new int[20];
int counter = 0;
int index = 0;
int min2 = 0;
System.out.println("\nAfter");
for(int k = 0; k < list.length - 1; k++) {
list[k] = randslct.nextInt(30) + 1;
boolean unique = true;
for(int z = k - 1; z >= 0; z--) {
if(list[k] == list[z]) {
if(list[k] == list[z]) {
unique = false;
break;
}
}
}
if(!unique) {
// Repeat last index
--k;
}
}
int min = list[0];
while(counter < list.length - 1) {
for(int x = 0; x < list.length - 1; x++) { // scroll through the indexes.
if(list[x] < min) {
min = list[x];
index = x; // keep the index of the biggest number.
}
}
System.out.println(list[index]);
min = 100 * (list[index]);
list[index] = 100 * (list[index]); // change the value in the original array so it won't find the same max again
counter++;
}
}
}
Your mistake is when you try to add a new number. You just check, if it isn't the same as the one before, but not if it is the same as twice before. You can do this as follow:
boolean isDuplicate(int index, int[] list){
for(int i=index-1; i>=0;i--){
if(int[i]==int[index])
return false
}
return true;
}
instead of your inner of the for-loop you can now write:
do{
list[k] = randslct.nextInt(30) + 1;
}while(isDuplicate(k, list));
Also you should change your output, e.g. give the already written output a negative value and ignore negative values. If you want to change the numbers up to e.g. 200 your code now won't work.
Lets take this by example. Consider that the current list that has been generated is:
list = [5, 7, 9, 3, 8, 9]
where 9 is the current number.
Now in the for-loop, you iterate from list[6] to list[0]. Here, in comparision, you come to 2nd index (list[2]) where the condition
list[k] == list[z] && z != k
turns out to be true and a new random number is generated. Lets assume that here the new random number that you generated is '8'. The loop terminates successfully and your array now has a duplicate.
This code is meant to find 100 factorial and the sum the digits in the number. However, it returns 0.
Why does this happen?
public class Problem20 {
public static void main(String[] args){
int num = 100;
for(int i = 1; i< 100; i++){
num = num * i;
}
String numstring = Integer.toString(num);
int sum = 0;
for(int j = 0; j < numstring.length(); j++){
sum += numstring.charAt(j) - '0';
}
System.out.print(sum);
}
}
Every time you multiply by 2, you add a 0 to the low bits of binary representation of the number.
According to the JLS §15.17.1:
If an integer multiplication overflows, then the result is the low-order bits of the mathematical product as represented in some sufficiently large two's-complement format. As a result, if overflow occurs, then the sign of the result may not be the same as the sign of the mathematical product of the two operand values.
Here's some code to demonstrate this point. As you can see, the number of 0 at the end of the number slowly increases; soon as we get to 32, the low order bits become all 0. See: Why does this multiplication integer overflow result in zero?
public class Problem20 {
public static void main(String[] args) {
int num = 100;
for (int i = 1; i < 33; i++) {
num = num * i;
System.out.println(i + "\t" + Integer.toBinaryString(num));
}
}
}
Output:
1 1100100
2 11001000
3 1001011000
4 100101100000
5 10111011100000
6 10001100101000000
7 1111011000011000000
8 1111011000011000000000
9 10001010011011011000000000
10 10101101000010001110000000000
11 11101101111011000011010000000000
12 100111000100100111000000000000
13 11111011111011111011000000000000
14 11000111000110111010000000000000
15 10101010100111100110000000000000
16 10101001111001100000000000000000
17 1001000010001100000000000000000
18 10100111011000000000000000000
19 10001101100001000000000000000000
20 1110010100000000000000000000
21 101100100100000000000000000000
22 11010100011000000000000000000000
23 10100101000000000000000000000
24 11101111000000000000000000000000
25 1010111000000000000000000000000
26 11010110000000000000000000000000
27 10010010000000000000000000000000
28 11111000000000000000000000000000
29 11000000000000000000000000000
30 11010000000000000000000000000000
31 110000000000000000000000000000
32 0
You can solve this problem by using BigInteger instead of int, e.g.
import java.math.BigInteger;
public class Problem20 {
public static void main(String[] args) {
BigInteger num = BigInteger.valueOf(100);
for (int i = 1; i < 100; i++) {
num = num.multiply(BigInteger.valueOf(i));
System.out.println(num);
}
}
}
Alright.
1! = 1
2! = 2
3! = 6
4! = 24
.
.
.
10! = 3628800
.
.
100! = 93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000
Do you think this fits in any of those data-types?
What happens once a number crosses the limit? It overflows. And hence you get a wrong answer.
So what do I do?
Use BigInteger.
I need help doing a program to add up even integers to 1
I need the computer to work out 1 + 3 + 7 + 13 + 21.... + n
n is whatever the user wants it to be
The sequence is adding up each even number, so for example, you start from 1 and add 2, which gets 3, then to 3 add 4, which gets 7, then to 7 add 6, which gets 13 and so on until you get to n.
I had a complete guess
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class Odd4 extends JFrame implements ActionListener {
private JButton button;
private JPanel panel;
public static void main(String [] args) {
Odd4 frame = new Odd4();
frame.setSize(100, 100);
frame.createLine();
frame.show();
}
private void createLine() {
setDefaultCloseOperation(EXIT_ON_CLOSE);
Container window=getContentPane();
window.setLayout (new FlowLayout());
button = new JButton("OK");
window.add(button);
button.addActionListener(this);
}
public void actionPerformed(ActionEvent event) {
int n;
int sum = 0;
int i;
int s = 1;
String nString;
nString = JOptionPane.showInputDialog("n:");
n = Integer.parseInt(nString);
for (i = 1; i <= n; i ++){
if (i%2 == 0)
do {
j=j+i;
sum = sum + j;
}
while (j <= n);
}
JOptionPane.showMessageDialog(null, "Total is: " + sum);
}
Pretty sure you want something like this:
public static void main(final String[] args) {
long total = 1;
for( int i = 0; i < 10; i++ ) {
total += (2*i);
System.out.println(total);
}
}
In my test it prints out:
1
3
7
13
21
31
43
57
73
91
EDIT: solution to add the terms up
public static void main(final String[] args) {
long total = 0;
long term = 1;
for( int i = 0; i < 5; i++ ) {
term += (2*i);
total += term;
System.out.println("Term " + i + " is " + term);
System.out.println("Current Total is " + total);
}
}
Term 0 is 1
Current Total is 1
Term 1 is 3
Current Total is 4
Term 2 is 7
Current Total is 11
Term 3 is 13
Current Total is 24
Term 4 is 21
Current Total is 45
EDIT: Added complete solution on Ideone
As per the request fo the OP in the comments, I threw together a complete solution in Ideone. It's here!
will this help?
int a[];
int i=0,f=1,a=2.sum=0;
while(f<=n)
{
a[i]=f;
f=f+a;
a=a+2;
i++;
}
for(int j=0;j<a.length;j++)
{
sum+=a[j];
}
You don't actually need a loop to solve this.
Each term is 1 plus the sum of even number e.g. 1, 1 + 2, 1 + 2 + 4, 1 + 2 + 4 + 6.
The sum of even numbers is x*(x+1) and plus 1 makes n^2 + n + 1.
Then you want to sum these terms.
The sum of squares is n*(n+1)*(2*n+1)/6
The sum of numbers is n*(n+1)/2
The sum of 1, (n+1) times is n+1
The solution is
n*(n+1)*(2*n+1)/6 + n*(n+1)/2 + n + 1
or
(2*n^3 + 7*n^2 + 10*n + 6)/6
e.g
1 + 3 + 7 + 13 + 21 = 45
21 is the 4th term so
(2*4^3 + 7*4^2 + 10*4 + 6)/6 = 45
Using the formula and looking at the differences, and differences of differences
term sum value even
0 1 1
1 4 3 2
2 11 7 4 2
3 24 13 6 2
4 45 21 8 2
5 76 31 10 2
6 119 43 12 2
7 176 57 14 2
8 249 73 16 2
9 340 91 18 2
10 451 111 20 2
And even number can be written 2i and an odd number 2i+1.
So i am not sure about your problem but for doing the sum you make a loop increasing i and sum until your number reach n :
Edit : correct (sum start to 1 and add even):
i = 0;
sum = 1;
while (2*i <= n){ // or 2*i +1 for odd
sum += 2*i;
i++;
}
Edit2: the correct answer
public class HelloWorld{
public static void main(String []args){
int i=0;
int n=7;
int sum=1;
int total = 0;
while (sum < n){ // or 2*i +1 for odd
sum += 2*i;
total += sum;
i++;
}
System.out.println(total);
}
}
This is what you want I think:-
sumofEven will give you the sum of numbers at even places.
public class Sample {
/**
* #param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
long n =21 ;
int i= 0;
long sumofEven =0;
long sumofAll =1;
while(sumofAll <= n){
sumofAll = (long) (sumofAll + 2*i);
System.out.println("->"+sumofAll);
if((i+1) % 2 == 0){
sumofEven = sumofEven + sumofAll;
}
i++;
}
System.out.println("sumofAll Numbers : "+sumofAll +"\nSum of no at event place : "+sumofEven);
}
}
Terms can be written like that :
...
So you need to sum these terms while they are less than user input n:
int i=0, n = userInput, term;
int sum=0;
while((term = (i*(i+1)+1)) < n) {
sum+=term;
i++;
}
You can see it working in this ideone