While loop code output - java

int x = 13;
while(x >= 4) {
if (x % 2 == 1) {
System.out.println(x);
}
x = x - 3;
}
I know the output of this, it is 13 and 7, would someone care to explain as how it came to be 13 and 7.

13 % 2 = 1 therefore, you print 13.
Now x = 10.
10 % 2 = 0, so you dont print out 10.
Now x = 7.
7 % 2 = 1, so you print 7.
Now x = 4.
4 % 2 = 0;
Now x = 1 and the loop stops.
The % operator is the modulo operator. This prints the remainder when dividing two numbers. For example 14/3 = 4 remainder 2, so 13 % 4 = 2.

First x is 13, is it >= then 4? Yes. Enter the while loop. Is 13%2==1. Yes. Print x (print 13). Then x = x-13, x becomes 10. Is 10 >=4? Yes. .... So on.

What don't you understand?
At the first iteration, x=13, 13%2=1 so it prints 13. The seconds iteration, x=10 (x=x-3) 10%2=0, nothing is printed. The third iteration x=7 (10-3), 7%2=1 so 7 is printed.
After that, x=4 so nothing is printed and x=1 quits the loop.

case 1:
---> x = 13;
while(true) // 13 >= 4
if(true) // 13%2 = 1 which is 1==1 is true
then print x
reduce x by 3 // now x ==10
case 2 :
---> x = 10;
while(true) // 10 > =4
if(false) // 10 % 2 = 0, 0 == 1 is false
skip
reduce x by 3// now x == 7
case 3:
---> x =7;
while(true) // 7 > = 4
if(true) //7 % 2 ,1==1 is true
print x;
reduce x by 3 // x == 4
case 4:
---> x =4;
while(true) // 4 > = 4
if(false) //4 % 2 ,0==1 is false
skip
reduce x by 3 // x == 4
case 5:
---> x =1;
while(false) // 7 > = 4
skip
operator summary :
**%** finds remainder // result is undefined if RHS operand is 0
**>=** greater than or equals

Related

For-loop output explanation needed?

I need an explanation of how the output prints 9(S), 7(S), 5(S) and 3(S).
10 > 3 is correct and goes to y 1 <= 2 which is correct so 2 x 10 - 2 = 18 but the output prints 9. I don't understand the logic here. Why does it print 9(s) instead of 18(s)?
public class Q2{
public static void main(String args[]) {
int x,y;
for(x= 10; x > 3; x = x - 2) {
for(y = 1; y <= 2 * x - 2; y = y + 2)
System.out.print("S");
System.out.print("\n");
}
}
}
Its correct Y <= 18 , but you are incrementing Y by 2, so it gets printed 9 times.
To understand, write down on a piece of paper what the values of your variables will be.
First, write down the values of x:
x: 10 8 6 4
Next, write down the calculated upper boundary value for y, i.e. the result of expression 2 * x - 2:
x : 10 8 6 4
yMax: 18 14 10 6
Last, write down the values of y:
x : 10 8 6 4
yMax: 18 14 10 6
y : 1 1 1 1
3 3 3 3
5 5 5 5
7 7 7
9 9 9
11 11
13 13
15
17
Finally, count the number of y values for each x value, i.e. the number of times S is printed:
x : 10 8 6 4
count: 9 7 5 3
Then realize that the code would have been much easier to understand if it had just been written like this:
for (int count = 9; count >= 3; count -= 2) {
for (int i = 0; i < count; i++) {
System.out.println("S");
}
}
Of course, that wouldn't have taught you what they were trying to teach you, which is:
Conclusion: If you don't understand what the code is doing, follow the logic step by step, and write down what it is doing.

Get the consecutive numbers whose sum matches with given number

I was going through a simple program that takes a number and finds the number of occurrences of consecutive numbers that matches with given number.
For example:
if input is 15, then the consecutive numbers that sum upto 15 are:
1,2,3,4,5
4,5,6
7,8
So the answer is 3 as we have 3 possibilities here.
When I was looking for a solution I found out below answer:
static long process(long input) {
long count = 0;
for (long j = 2; j < input/ 2; j++) {
long temp = (j * (j + 1)) / 2;
if (temp > input) {
break;
}
if ((input- temp) % j == 0) {
count++;
}
}
return count;
}
I am not able to understand how this solves the requirement because this program is using some formula which I am not able to understand properly, below are my doubts:
The for loop starts from 2, what is the reason for this?
long temp = (j * (j + 1)) / 2; What does this logic indicates? How is this helpful to solving the problem?
if ((num - temp) % j == 0) Also what does this indicate?
Please help me in understanding this solution.
I will try to explain this as simple as possible.
If input is 15, then the consecutive numbers that sum upto 15 are:
{1,2,3,4,5} -> 5 numbers
{4,5,6} -> 3 numbers
{7,8} -> 2 numbers
At worst case, this must be less than the Sum of 1st n natural numbers = (n*(n+1) /2.
So for a number 15, there can never be a combination of 6 consecutive numbers summing up to 15 as the sum of 1st 6 numbers =21 which is greater than 15.
Calculate temp: This is (j*(j+1))/2.
Take an example. Let input = 15. Let j =2.
temp = 2*3/2 = 3; #Meaning 1+2 =3
For a 2-number pair, let the 2 terms be 'a+1' and 'a+2'.(Because we know that the numbers are consecutive.)
Now, according to the question, the sum must add up to the number.
This means 2a+3 =15;
And if (15-3) is divisible by 2, 'a' can be found. a=6 -> a+1=7 and a+2=8
Similarly, let a+1 ,a+2 and a+3
a + 1 + a + 2 + a + 3 = 15
3a + 6 = 15
(15-6) must be divisible by 3.
Finally, for 5 consecutive numbers a+1,a+2,a+3,a+4,a+5 , we have
5a + 15 = 15;
(15-15) must be divisible by 5.
So, the count will be changed for j =2,3 and 5 when the input is 15
If the loop were to start from 1, then we would be counting 1 number set too -> {15} which is not needed
To summarize:
1) The for loop starts from 2, what is the reason for this?
We are not worried about 1-number set here.
2) long temp = (j * (j + 1)) / 2; What does this logic indicates? How is this helpful to solving the problem?
This is because of the sum of 1st n natural numbers property as I have
explained the above by taking a+1 and a+2 as 2 consecutive
numbers.
3) if ((num - temp) % j == 0) Also what does this indicate?
This indicates the logic that the input subtracted from the sum of 1st
j natural numbers must be divisible by j.
We need to find all as and ns, that for given b the following is true:
a + (a + 1) + (a + 2) + ... (a + (n - 1)) = b
The left side is an arithmetic progression and can be written as:
(a + (n - 1) / 2) * n = b (*)
To find the limit value of n, we know, that a > 0, so:
(1 + (n - 1) / 2) * n = n(n + 1) / 2 <= b
n(n + 1) <= 2b
n^2 + n + 1/4 <= 2b + 1/4
(n + 1/2)^2 <= 2b + 1/4
n <= sqrt(2b + 1/4) - 1/2
Now we can rewrite (*) to get formula for a:
a = b / n - (n - 1) / 2
Example for b = 15 and n = 3:
15 / 3 - (3 - 1) / 2 = 4 => 4 + 5 + 6 = 15
And now the code:
double b = 15;
for (double n = 2; n <= Math.ceil(Math.sqrt(2 * b + .25) - .5); n++) {
double candidate = b / n - (n - 1) / 2;
if (candidate == (int) candidate) {
System.out.println("" + candidate + IntStream.range(1, (int) n).mapToObj(i -> " + " + (candidate + i)).reduce((s1, s2) -> s1 + s2).get() + " = " + b);
}
}
The result is:
7.0 + 8.0 = 15.0
4.0 + 5.0 + 6.0 = 15.0
1.0 + 2.0 + 3.0 + 4.0 + 5.0 = 15.0
We are looking for consecutive numbers that sum up to the given number.
It's quite obvious that there could be at most one series with a given length, so basically we are looking for those values witch could be the length of such a series.
variable 'j' is the tested length. It starts from 2 because the series must be at least 2 long.
variable 'temp' is the sum of a arithmetic progression from 1 to 'j'.
If there is a proper series then let X the first element. In this case 'input' = j*(X-1) + temp.
(So if temp> input then we finished)
At the last line it checks if there is an integer solution of the equation. If there is, then increase the counter, because there is a series with j element which is a solution.
Actually the solution is wrong, because it won't find solution if input = 3. (It will terminate immediately.) the cycle should be:
for(long j=2;;j++)
The other condition terminates the cycle faster anyway.
NB: loop is starting from 2 because=> (1*(1+1))/2 == 1, which doesn't make sense, i.e, it doesn't effect on the progress;
let, k = 21;
so loop will iterate upto (k/2) => 10 times;
temp = (j*(j+1))/2 => which is, 3 when j =2, 6 when j = 3, and so on (it calculates sum of N natural numbers)
temp > k => will break the loop because, we don't need to iterate the loop when we got 'sum' which is more than 'K'
((k-temp)%j) == 0 => it is basically true when the input subtracted from the sum of first j natural numbers are be divisible by j, if so then increment the count to get total numbers of such equation!
public static long process(long input) {
long count = 0, rest_of_sum;
for (long length = 2; length < input / 2; length++) {
long partial_sum = (length * (length + 1)) / 2;
if (partial_sum > input) {
break;
}
rest_of_sum = input - partial_sum
if (rest_of_sum % length == 0)
count++;
}
return count;
}
input - given input number here it is 15
length - consecutive numbers length this is at-least 2 at max input/2
partial_sum = sum of numbers from 1 to length (which is a*(a+1)/2 for 1 to a numbers) assume this is a partial sequence
rest_of_sum = indicates the balance left in input
if rest of sum is multiple of length meaning is that we can add (rest_of_sum/length) to our partial sequence
lets call (rest_of_sum/length) as k
this only means we can build a sequence here that sums up to our input number
starting with (k+1) , (k+2), ... (k+length)
this can validated now
(k+1) + (k+2) + ... (k+length)
we can reduce this as k+k+k+.. length times + (1+2+3..length)
can be reduced as => k* length + partial_sum
can be reduced as => input (since we verified this now)
So idea here is to increment count every-time we find a length which satisfies this case here
If you put this tweak in it may fix code. I have not extensively tested it. It's an odd one but it puts the code through an extra iteration to fix the early miscalculations. Even 1/20000 would work! Had this been done with floats that got rounded down and 1 added to them I think that would have worked too:
for (long j = 2; j < input+ (1/2); j++) {
In essence you need to only know one formula:
The sum of the numbers m..n (or m to n) (and where n>m in code)
This is ((n-m+1)*(n+m))/2
As I have commented already the code in the original question was bugged.
See here.
Trying feeding it 3. That has 1 occurrence of the consecutive numbers 1,2. It yields 0.
Or 5. That has 2,3 - should yield 1 too - gives 0.
Or 6. This has 1,2,3 - should yield 1 too - gives 0.
In your original code, temp or (j * (j + 1)) / 2 represented the sum of the numbers 1 to j.
1 2 3 4 5
5 4 3 2 1
=======
6 6 6 6 6 => (5 x 6) /2 => 30/2 => 15
As I have shown in the code below - use System.out.println(); to spew out debugging info.
If you want to perfect it make sure m and n's upper limits are half i, and i+1 respectively, rounding down if odd. e.g: (i=15 -> m=7 & n=8)
The code:
class Playground {
private static class CountRes {
String ranges;
long count;
CountRes(String ranges, long count) {
this.ranges = ranges;
this.count = count;
}
String getRanges() {
return this.ranges;
}
long getCount() {
return this.count;
}
}
static long sumMtoN(long m, long n) {
return ((n-m+1)* (n+m))/2;
}
static Playground.CountRes countConsecutiveSums(long i, boolean d) {
long count = 0;
StringBuilder res = new StringBuilder("[");
for (long m = 1; m< 10; m++) {
for (long n = m+1; n<=10; n++) {
long r = Playground.sumMtoN(m,n);
if (d) {
System.out.println(String.format("%d..%d %d",m,n, r));
}
if (i == r) {
count++;
StringBuilder s = new StringBuilder(String.format("[%d..%d], ",m,n));
res.append(s);
}
}
}
if (res.length() > 2) {
res = new StringBuilder(res.substring(0,res.length()-2));
}
res.append("]");
return new CountRes(res.toString(), count);
}
public static void main(String[ ] args) {
Playground.CountRes o = countConsecutiveSums(3, true);
for (long i=3; i<=15; i++) {
o = Playground.countConsecutiveSums(i,false);
System.out.println(String.format("i: %d Count: %d Instances: %s", i, o.getCount(), o.getRanges()));
}
}
}
You can try running it here
The output:
1..2 3
1..3 6
1..4 10
1..5 15
1..6 21
1..7 28
1..8 36
1..9 45
1..10 55
2..3 5
2..4 9
2..5 14
2..6 20
2..7 27
2..8 35
2..9 44
2..10 54
3..4 7
3..5 12
3..6 18
3..7 25
3..8 33
3..9 42
3..10 52
4..5 9
4..6 15
4..7 22
4..8 30
4..9 39
4..10 49
5..6 11
5..7 18
5..8 26
5..9 35
5..10 45
6..7 13
6..8 21
6..9 30
6..10 40
7..8 15
7..9 24
7..10 34
8..9 17
8..10 27
9..10 19
i: 3 Count: 1 Instances: [[1..2]]
i: 4 Count: 0 Instances: []
i: 5 Count: 1 Instances: [[2..3]]
i: 6 Count: 1 Instances: [[1..3]]
i: 7 Count: 1 Instances: [[3..4]]
i: 8 Count: 0 Instances: []
i: 9 Count: 2 Instances: [[2..4], [4..5]]
i: 10 Count: 1 Instances: [[1..4]]
i: 11 Count: 1 Instances: [[5..6]]
i: 12 Count: 1 Instances: [[3..5]]
i: 13 Count: 1 Instances: [[6..7]]
i: 14 Count: 1 Instances: [[2..5]]
i: 15 Count: 3 Instances: [[1..5], [4..6], [7..8]]

Printing out a multiplication table

I'm going through the Java Tutorial on HackerRank using Java 8. The goal is to print out a multiplication table of 2 from 1 - 10.
Here is what I came up with
public static void main(String[] args) {
int x = 2;
int y = 0;
int z;
while (y < 10) {
z = x * y;
y++;
System.out.println(x + " x " + y + " = " + z);
}
Here is the output I get from the code above
2 x 1 = 0
2 x 2 = 2
2 x 3 = 4
2 x 4 = 6
2 x 5 = 8
2 x 6 = 10
2 x 7 = 12
2 x 8 = 14
2 x 9 = 16
2 x 10 = 18
I've also tried while <= 10 instead of while < 10 as shown in my code above and for that my result was:
2 x 1 = 0
2 x 2 = 2
2 x 3 = 4
2 x 4 = 6
2 x 5 = 8
2 x 6 = 10
2 x 7 = 12
2 x 8 = 14
2 x 9 = 16
2 x 10 = 18
2 x 11 = 20
Neither of this outputs is what I'm looking for. Logically I am confident my code makes sense and should work so I'm looking for someone to give me tips as to something I may have missed or maybe I've made a mistake and I'm not aware of it. I am not looking for the code to the right answer, but rather advice and/or pointers which will allow to come up with a working solution on my own.
Start your y value at 1
Don't increment your y value until after the print statement
public static void main(String[] args) {
int x = 2;
int y = 1; //starts at 1
int z;
while (y < 10) {
z = x * y;
System.out.println(x + " x " + y + " = " + z);
y++; // increment y after the print statement
}
}
Assign value of y = 1 and increment it after your system.out.println();

Java Loop to go Through Numbers and Adding 5

I am writing Java code that needs to print these numbers: "0 5 10 3 8 1 6 11 4 9 2 7" in that order. I am new to Java, and am not very good at Loops yet. I am finding the points of a 12 point star, starting at 0, and trying to find the points that need to be touched by a line to make the star..
How do I do a loop that starts at 0, and adds 5 to each number.. so 0 + 5 = 5, 5+5=10, 10+5=3 (this is where my problem is.. How do I make it go back from 11 to 0?
I know this might seem confusing... or it might be extremely easy.. but any help would be greatly appreciated.
Increment by 5 until you pass 60, display the result of modulo 12. Something like,
for (int i = 0; i < 60; i += 5) {
System.out.println(i % 12);
}
This is called modulus, and java has the modulo operator % which gives the remainder of integer division.
15 / 12 == 1
15 % 12 == 3
as
(15 / 12) * 12 + (15 % 12) == 15
See the wikipedia.
Of course in your case you could also do
n += 5;
if (n >= 12) {
n -= 12;
}
instead of using modulo:
n = (n + 5) % 12;
Just iterate from 0 to 12, multiplying your number by 5, and applying modulus 12:
for (int i = 0; i < 12; i++) {
System.out.println(i * 5 % 12);
}
I believe the operator you are looking for is the modulus operator. The modulus gives you the remainder from a division problem. In this case you are using 12 as the denominator.
0 + 5 % 12 = 5 (0, remainder 5)
5 + 5 % 12 = 10 (0, remainder 10)
10 + 5 % 12 = 3 (1, remainder 3)
15 + 5 % 12 = 8 (1, remainder 8)
20 + 5 % 12 = 1 (2, remainder 1)
try this :
for(int i=0; ; i = (i+5)%12){
System.out.println(i);
if(i==7)break;
}

Division by subtration - dividing the remainder by subtration?

We can divide a number by subtraction and stop at the remainder as shown here.
But how do we continue to divide the remainder by subtraction ? I looked on google and could not find such answers. They don't go beyond the remainder.
For example, lets say we have
7/3.
7-3 = 4
4-3 = 1
So, we have 2 & (1/3). How do we do the 1/3
division using only subtraction or addition ?
REPEAT -
Please note that I dont want to use multiplication or division operators to do this.
You can get additional "digits", up to any arbitrary precision (in any base you desire, I'll use base 10 for simplicity but if you're trying to implement an algorithm you'll probably choose base 2)
1) Perform division as you've illustrated, giving you a quotient (Q=2), a divisor (D=3), and a remainder (R=1)
2) If R=0, you're done
3) Multiply R by your base (10, R now =10)
4) Perform division by subtraction again to find R/D (10/3 = 3+1/3).
5) Divide the resulting quotient by your base (3/10 = 0.3) and add this to what you got from step 1 (now your result is 2.3)
6) Repeat from step 2, dividing the new remainder (1) by 10 again
While it sounds an awful lot like I just said division quite a few times, we're dividing by your base. I used 10 for simplicity, but you'd really use base 2, so step 3 is really a left shift (by 1 bit every time) and step 5 is really a right shift (by 1 bit the first time through, 2 bits the second, and so on).
7/3.
7-3 = 4
4-3 = 1
7/3 = 2 R 1
1*10 = 10
10-3 = 7
7-3 = 4
4-3 = 1
10/3 = 3 R 1
7/3 = 2 + 3/10 R 1
7/3 = 2.3 R 1
1*10 = 10
10-3 = 7
7-3 = 4
4-3 = 1
10/3 = 3 R 1
7/3 = 2.3 + 3/100 R 1
7/3 = 2.33 R 1
And so on until you reach any arbitrary precision.
If you want to keep going to get decimal digits, multiply the remainder by a power of 10.
E.g. if you want 2.333, then you can multiply remainder by 1000, and then repeat the algorithm.
It depends on what you are asking.
If you are asking how to get the end fraction and simply it, let's take a different example.
26 / 6.
26 - 6 = 20 count 1
20 - 6 = 14 count 2
14 - 6 = 8 count 3
8 - 6 = 2 count 4
(In code, this would be accomplished with a for loop)
Afterwards, we would have 4 2/6. To simplify, switch the dividend and divisor:
6 / 2.
6 - 2 = 4 count 1
4 - 2 = 2 count 2
2 - 2 = 0 count 3
If this finishes without a remainder, show as 1 over the count.
In pseudo-code:
int a = 26;
int b = 6;
int tempb = 6;
int left = 26;
int count = 0;
int count2 = 0;
left = a - b;
for(count; left > b; count++){
left -= b;
}
if(left > 0){
for(count2; tempb > left; count2++){
tempb -= left;
}
console.log("The answer is " + count + " and 1/" + count2);
I hope this answers your question!
Here is a complete program that uses only + and -, translate to your language of choice:
module Q where
infixl 14 `÷` `×`
a × 0 = 0
a × 1 = a
a × n = a + a×(n-1)
data Fraction = F Int [Int]
a ÷ 0 = error "division by zero"
a ÷ 1 = F a []
0 ÷ n = F 0 []
a ÷ n
| a >= n = case (a-n) ÷ n of
F r xs -> F (r+1) xs
| otherwise = F 0 (decimals a n)
where
decimals a n = case (a × 10) ÷ n of
F d rest = (d:rest)
instance Show Fraction where
show (F n []) = show n
show (F n xs) = show n ++ "." ++ concatMap show (take 10 xs)
main _ = println (100 ÷ 3)
It is easy to extend this in such a way that the periodic part of the fraction is detected, if any. For this, the decimals should be tuples, where not only the fractional digit itself but also the dividend that gave rise to it is kept.
The printing function could then be adjusted to print infinite fractions like 5.1(43), where 43 would be the periodic part.

Categories