Java for loop is hard to understand - java

May someone explain to me why the following blocks of code generate such different outputs?
public class hello
{
public static void main(String args[])
{
int a,b,c;
for (a = 0; a < 5; a++)
{
for (b = 4; b >= a; b--)
{
System.out.print(" ");
}
for (c = 0; c <= a - b; c++)
{
System.out.print("*");
}
System.out.println();
}
}
}
Output:
public class hello
{
public static void main(String args[])
{
int a,b,c;
for (a = 0; a < 5; a++)
{
for (b = 4; b >= 0; b--)
{
System.out.print(" ");
}
for (c = 0; c <= a - b; c++)
{
System.out.print("*");
}
System.out.println();
}
}
}
Output:
Shouldnt the outputs be the same since b >= a is equivalent to b >= 0 as b's value will be deducted by 1 for every loop?

No, the outputs cannot be the same, since every time you are executing
for (a = 0; a < 5; a++)
this gets executed as well (5 times)
for (b = 4; b >= a; b--)
{
System.out.print(" ");
}
But the value of a is changing with every iteration: a will be initially 0, then 1, 2, 3 and finally 4.
Hence, the number of spaces that you are printing in the first scenario will decrease with every iteration of a.
For a = 0 we have:
b = 4,
b = 3,
b = 2,
b = 1,
b = 0 (for loop stops since b=-1 is not >= a=0)
For a = 1 we have:
b = 4,
b = 3,
b = 2,
b = 1 (for loop stops since b=0 is not >= a=1)
For a = 2 we have:
b = 4,
b = 3,
b = 2 (for loop stops since b=1 is not >= a=2)
For a = 3 we have:
b = 4,
b = 3 (for loop stops since b=2 is not >= a=3)
For a = 4 we have:
b = 4 (for loop stops since b=3 is not >= a=4)

variable a will go from 0 to 4, so for each iteration you will have:
for (b = 4; b >= 0; b--)
{ [...]
for (b = 4; b >= 1; b--)
{ [...]
for (b = 4; b >= 2; b--)
{ [...]

Please read the comments in the code and you will se the difference!
int a, b, c;
for (a = 0; a < 5; a++)
{
for (b = 4; b >= a; b--) // Print every time b-a + 1 underscores... since you start every time with b=4 you have for each a one space fewer
{
System.out.print(" ");
}
for (c = 0; c <= a - b; c++) // and then print (a-b)-c +1 stars (b is every time a-1)...
// (first a=0 -b=-1)+1=2 and any time it will prit 2 stars scince
{
System.out.print("*");
}
System.out.println();
}
for (a = 0; a < 5; a++)
{
for (b = 4; b >= 0; b--) // Print every time b-a + 1=4 underscores
{
System.out.print(" ");
}
for (c = 0; c <= a - b; c++) // and then print (a-b)-c +1 stars (b is every time -1)...
// first time ( a=0 -b=-1)+1 =2 , second time (a=1 - b=-1)+1=3
{
System.out.print("*");
}
System.out.println();
}

Related

Finding value for ABC

class Main {
public static void main(String[] args) {
int abc;
int total = 1000;
for (abc = 220000000; abc < 240000000; abc++) {
String string1 = Integer.toString(abc);
int a, b, c;
a = 0;
b = 0;
c = 0;
int a2 = squared(a);
int b2 = squared(b);
int c2 = squared(c);
a = Integer.parseInt(string1.substring(0, 3));
b = Integer.parseInt(string1.substring(3, 6));
c = Integer.parseInt(string1.substring(6, 9));
if (a < b && a < c && b < c && a2 < b2 && b2 < c2 && a + b + c == total) {
System.out.println("The answer is " + abc);
} else {
System.exit(0); // testing
}
}
}
public static int squared(int x) {
return (x * x);
}
}
This is my code. I am trying to have the program print the value of abc so that a is less than b which is less than c. And where a squared is less than b squared which is less than c squared. Also, a+b+c must equal 1000. I tried making abc one whole value and using substrings to differ between a, b, and c. An example would be like 224,356,446. An with the substrings it would make a=224, b=356, and c=446. When I run the program, nothing is being printed. The else statement is being invoked because the system exits. Can anyone help?
You print nothing because you do not have a match on your first iteration. The lack of a match fires System.exit(0) so the program exits without another iteration.
You have appeared to make the assumption that that a, b, c are non-negative integers so I'll adopt that same assumption. As such, if a < b < c then a^2 < b^2 < c^2 so we do not have to test for the latter condition.
If a + b + c == 1000 and a < b < c then if a==0 and b==1 (their minimum values) then c == 999. So we know we do not have to iterate beyond 999 in any case. This bound could be further optimized a bit but doing so is pointless since he output operation far outweighs the iteration cost.
public static void main(String[] args) {
int count = 0;
for (int a = 0 ; a < 999 ; ++a) {
for (int b = a+1 ; b < 999 ; ++b) { // a < b
int c = 1000 - a - b;
if (c <= b) {
break;
}
System.out.printf("%d %d, %d, %d", ++count, a, b, c).println();
}
}
}

Java Fibonacci for loop variable

This is a program which takes a command line variable, parses it into an int and the output is the fibonacci number equal to that cmd line argument. So if i enter 7, the output will be 13. since: 1 1 2 3 5 8 13
Can someone explain the b = a; inside the for loop? Since they're both already equal to 1, why do they need to be set equal to eachother?
int a,b,c;
int n = Integer.parseInt(args[0]);
a = 1;
b = 1;
c = 0;
if (n == 1 || n == 2)
System.out.println(1);
else
{
for (int i = 3; i<=n; i++)
{
c = a + b;
b = a;
a = c;
}
System.out.println(c);
}
}
a and b are equal to 1 initially, so on the first iteration of the loop, this statement does nothing. But let's look at what happens on later iterations:
Initial state:
a = 1
b = 1
c = 0
Iteration 1:
c = 1 + 1 = 2
b = a = 1
a = c = 2
Iteration 2:
c = 1 + 2 = 3
b = a = 2
a = c = 3
Iteration 3:
c = 2 + 3 = 5
b = a = 3
a = c = 5
Essentially, a stores the previous number in the sequence, while b stores the second to last. Since the first 2 numbers of the sequence are 1, 1, b will stay as 1 for two iterations, but then change later on.
Fn = Fn-1 + Fn-2, i.e. for starting from a = 1 and b = 1, you have to calculate next fibonacci number and move a and b to the one position right.
public static long fibonacci(int n) {
n = Math.abs(n);
if (n == 0)
return 0;
if (n < 3)
return 1;
long a = 1;
long b = 1;
long c = 0;
for (int i = 3; i <= n; i++) {
c = a + b;
b = a;
a = c;
}
return c;
}

Array Index out of bounds think there is a specfic line

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 100 at ham.main(ham.java:34)
line 34 on my console says if (h[c] == 1)
i wrote a code to generate hamming code..i am getting the javaindexoutbounds exception..i even gave absurdly large array sizes to counter tht..still not working!
The array is outbounds even thou there plenty of space for the array
the line 27 might be a mistake...checking for c
import java.util.*;
public class ham {
public static void main(String ar[]) {
Scanner s = new Scanner(System.in);
System.out.println("input no. of bits");
int n = s.nextInt();
int a[] = new int[100]; // user's input
int h[] = new int[100]; // hamming code array
System.out.println("i/p the data");
int i = 1, j = 1, pb = 1;
for (i = 1; i < n + 1; i++)
a[i] = s.nextInt();
i = 1;
while (i < n + 1) {
if (j == pb) // if the index is a parity bit leave it
{
j++;
pb = pb * 2;
} else {
h[j] = a[i];
j++;
i++;
} // else copy the data bits from a[] to h[]
}
int c = 0, counter = 0; // to fill the parity bits(k)
for (int k = 1; k <= j; k = 2 * k) {
c = k;
while (c <= j) // 'j' is position of the last data bit in h[]
{
for (c = k; c < (c + k); c++) {
if (h[c] == 1) // this is line 34
counter++;
}
c = c + k + 1;
}
if (counter % 2 == 0)
h[k] = 0;
else
h[k] = 1;
}
System.out.println("hamming code is");
for (i = 1; i <= j; i++)
System.out.print(h[i] + " ");
}
}
The if (h[c] == 1) test is causing the exception.
Your h array has a fixed size of 100, but the maximum value of c seems to depend on the user's input, n. You will need to figure out how to dynamically determine your array sizes, depending on the user input.

Special Pythagorean Triplet

What's wrong with my code? It prints 2,2 when the correct answer is clearly 6,8
public static void main(String[] args) {
int a = 1;
int b = 1;
int answer = 0;
int j = 4;
while (j == 4) {
for (a = 1; a <= 10; a++) {
for (b = 1; b <= 10; b++) {
answer = a * a + b * b;
if (answer == 100) {
j = 10;
}
}
}
}
System.out.println(a + " " + b);
}
if(answer == 100);
you have an extra semicolon after your if.
This will cause it to execute the j = 10; no matter what answer equals
You are incrementing a and b at the same time. In your code, the two numbers will always be equal. Also, you are not testing for a match when you exit the loop.

Code for finding pythagorean triplets

I am currently attempting this question :
A Pythagorean triplet is a set of three natural numbers, a, b and c, for which
a2 + b2 = c2.
For example, 32 + 42 = 9 + 16 = 25 = 52.
There exists exactly one Pythagorean triplet for which a + b + c = 1000.
Find the product abc.
My code is as follows, I think it should be correct, but the site is telling me my answer is wrong? Can someone help me see the flaws in my logic please?
public class Pythagoras {
public static void main(String[] args) {
int sum = 1000;
int a;
int product=0;
for (a = 1; a <= sum/3; a++)
{
int b;
for (b = a + 1; b <= sum/2; b++)
{
int c = sum - a - b;
if ( c > 0 && (a*a + b*b == c*c) )
System.out.printf("a=%d, b=%d, c=%d\n",a,b,c);
product = a * b * c;
}
}
System.out.println(product);
}
}
Here are 5 solutions (from slow to fast):
1) Trivial implementation - 732857 microseconds (0.7 seconds)
private static void p1(int sum) {
for (int a = 0; a <= sum; a++) {
for (int b = 0; b <= sum; b++) {
for (int c = 0; c <= sum; c++) {
if (a < b && b < c && a + b + c == sum
&& (c * c == a * a + b * b)) {
System.out.print(a * b * c);
return;
}
}
}
}
}
2) Limit the lower bound for b & c (establish the order relation) - 251091 microseconds (0.2 seconds)
private static void p2(int sum) {
for (int a = 0; a <= sum; a++) {
for (int b = a + 1; b <= sum; b++) {
for (int c = b + 1; c <= sum; c++) {
if (a + b + c == sum && (c * c == a * a + b * b)) {
System.out.print(a * b * c);
return;
}
}
}
}
}
3) Limit the lower & upper bounds for b & c - 111220 microseconds (0.1 seconds)
private static void p3(int sum) {
for (int a = 0; a <= sum; a++) {
for (int b = a + 1; b <= sum - a; b++) {
for (int c = b + 1; c <= sum - a - b; c++) {
if (a + b + c == sum && (c * c == a * a + b * b)) {
System.out.print(a * b * c);
return;
}
}
}
}
}
4) Limit lower & upper bounds for b and fix value for c - 2625 microseconds
private static void p4(int sum) {
for (int a = 0; a <= sum; a++) {
for (int b = a + 1; b <= sum - a; b++) {
int c = sum - a - b;
if (c > b && c * c == a * a + b * b) {
System.out.print(a * b * c);
return;
}
}
}
}
5) Use Euclid's formula - 213 microseconds
private static void p5(int sum) {
// a = m^2 - n^2
// b = 2mn
// c = m^2 + n^2
int a, b, c;
int sqrt = (int)Math.sqrt(sum);
for (int n = 1; n <= sqrt; n++) {
for (int m = n+1; m <= sqrt; m++) {
a = m*m - n*n;
b = 2*m*n;
c = m*m + n*n;
if ( a + b + c == 1000 ) {
System.out.print(a * b * c);
return;
}
}
}
}
I think you're missing a set of braces. The indentation leads me to believe the two innermost statements go together but you need curly braces for that to be correct.
if ( c > 0 && (a*a + b*b == c*c) )
{
System.out.printf("a=%d, b=%d, c=%d\n",a,b,c);
product = a * b * c;
}
Without the braces product will always contain the product of the last values of a, b, and c. (333 * 500 * 167 == 27805500).
Though others have already given specific fixes for you code, here's a more general hint that will be useful on other problems as well. Test your code on a simpler version of the problem.
For example, see if your program can find 6,8,10 as a triplet with a sum of 24. With a smaller test you can actually step through the code to see where it's going wrong.
You may try it this way,
public class Pythagoras {
public static void main(String[] args) {
int m = 1, n = 0, a = 0, b = 0, c = 0, sum = 0;
int product = 0;
for (m = 2; m < 100; m++) {
for (n = 1; n < 100; n++) {
while (m > n) {
a = (m * m) - (n * n);
b = (2 * m) * n;
c = (m * m) + (n * n);
sum = a + b + c;
if (sum == 1000) {
product = a * b * c;
System.out.print("a :" + a + "b :" + b + "c : " + c);
System.out.println("Product is" + product);
break;
}
break;
}
}
}
}
}
This implements the Euclid's formula for generating Pythagorean triplet as explained here
Note that in this method we make only triplets hence unwanted repetitions are reduced.
and the output is a :375 b :200 c : 425 Product is 31875000
//
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public javax.swingx.event.*;
public class Triplet extends JApplet implements ActionListener
{
JLabel l1, l2, l3;
JButton b1;
JTextFiel t1, t2;
public void init()
{
Container c = getContentPane();
c.setLayout(new FlowLayout());
l1=new JLabel("Enter the value of a: ");
l2=new JLabel("Enter the value of b: ");
t1 = new JTextField(20);
t2 = new JTextField(20);
b1=new JButton("Ok");
l2=new JLabel(" ");
add(l1);
add(t1);
add(l2);
add(t2);
add(b1);
add(l3);
b1.addActionListener(this);
public void ActionPerformed(ActionEvent e)
{
int a = Integer.parseInt(t1.getText());
int b = Integer.parseInt(t2.getText());
long c = Math.sqrt(a*a + b*b);
l3.setText(" " +c);
}
}
}
public class Pythagorean_Triplets
{
public static void main(long n)
{
long h=1,p=1,b1;
double b;
while(h<=n)
{
while(p<h)
{
b=Math.sqrt((h*h)-(p*p));
if(b%1==0)
{
b1=(long)b;
System.out.println(b1+","+p+","+h);
break;
}
p++;
}
h++;
p=1;
}
}
}

Categories