For-loop output explanation needed? - java

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.

Related

Is there a best approach to create four times 1 - 12 blocks through a loop

There is a loop that increments the counter 48 times to write certain values to an Excel file.
In the range 1 - 48, 4 blocks from 1 - 12 are to be written.
Expected example:
1 2 3 4 5 6 7 8 9 10 11 12 - 1 2 3 4 5 6 7 ... and so on (4 times).
I have tried different approaches, if/else, switch/case but here I have not come to any result.
My last approach is an if condition with the modolu operator.
for (int i = 1; i <= 48; i++) {
if (i % 12 != 0) {
for (int j = 1; j <= 12; j++) {
workBook.setNumber(HEADLINE_ROW, i + 6, j);
}
} else {
workBook.setNumber(HEADLINE_ROW, i + 6, 12);
}
}
But with this approach I get 12 12 12 12 and so on.
I recognize the error, but currently have no idea how to solve the problem. The part where data is written to the Excel file is rather unimportant. I am concerned with the logic.
I'm stuck in the logic here and can't get any further. Do you have any ideas or suggestions for improvement on how I can generate four 1 - 12 blocks side by side?
do something like that
python
for i in range(48):
index = i % 12 + 1
# do what ever you want here
print(index)
java
for(int i = 0; i < 48; i++) {
int index = i % 12 + 1;
// do something here
}
I think the pseudo code for what you want would be:
for (int i=1; i <= 48; i++) {
int j = i % 12 + 1; // 1 2 3 4 5 6 7 8 9 10 11 12 1 2 3 ...
// do something with i and (j + 1)
}
That is, work with the outer loop counter mod 12, which would give you the sequence 1, 2, ..., 12, four times.

Multiplication Table Pop Up

I have messed around with my code and I still haven't found an answer to it. Format.left is just a class that puts space in between each number. I am trying to have the numbers from 1 through 4 show on the side but it keeps popping up like this:
1 2 3 4 5 6
2 4 6 8 10 12
3 6 9 12 15 18
4 8 12 16 20 24
I hope I am making sense to you guys my English is really bad.
for(cols = 1; cols <= 4; cols++)
{
for (rows = 1; rows <= 6; rows++)
{
System.out.print(Format.right(cols * rows,7));
}
System.out.println();
}
I am looking for something that briefly looks like this:
1 2 3 4 5
1 1 2 3 4 5
2 2 4 6 8 10
3 3 6 9 12 15
4 4 8 12 16 20
5 5 10 15 20 25
Try this:
for(cols = 0; cols <= 4; cols++)
{
for (rows = 0; rows <= 6; rows++)
{
if (rows == 0 || cols == 0) {
System.out.print(Format.right(cols + rows, 7));
}else {
System.out.print(Format.right(cols * rows, 7));
}
}
System.out.println();
}
You wanted each row and column to be shifted by one so I simply started the loop at 0 instead of 1 and added an if statement to handle the special case of the first row / column.

Folding paper strip and generate numbers while unfolding

I have an assignment question that I am struggling with and need some direction to solve.
Suppose i have a strip of paper and i fold it from the center such that the left half goes behind the right half. Then i number the folded peices in sequence i get the numbers when i unfold as follows.
1 : 2
If i fold twice i get the numbers when unfolded as follows
1 : 4 : 3 : 2
if I fold thrice i get as follows
1 8 5 4 3 6 7 2
I want to generate the array of numbers when I fold it n times. so if i fold it for example 25 times i will get 2^25 numbers in similar sequence.
These are the observations i made
the first and last numbers are always 1 and 2.
the middle two numbers are always 4 and 3
the number at index 1 is largest number and number at second last location is second largest number.
It looks like a preorder traversal of binary search tree but I dont know how that helps.
I tried to construct binary tree from the preorder and then convert it to inorder assuming that I can reverse this process to get the same series and I was wrong about it.
EDIT : For searching an element in this generated array I can do a sequential search which will be O(n) efficient. But I realise there has to be a much faster way to search for a number in this series.
I cannot do binary search because this is not sorted and there are over a billion numbers when 25+ foldings are done.
What kind of search tactics can i use to find a number and its index?
This was one of the reasons I wanted to convert it into a binary search tree which will have log(n) search efficiency.
EDIT 2: I tried the table folding algorithm as suggested by one of the answers and it is not memory efficient. I cannot store over a billion numbers in my memory so there has to be a way to find a numbers index without actually creating the array of numbers.
1st fold: 1 2
2nd fold: 1 4 3 2
3rd fold: 1 8 5 4 3 6 7 2
4th fold: 1 16 9 8 5 12 13 4 3 14 11 6 7 10 15 2
Generate table (with example to 4th fold)
Imagine you have a nth fold paper and then unfold it.
Generate a table with size ( column = 1, row = 2^n ) and fill the column from down to up with values in ascending order
16
15
14
13
12
11
10
9
8
7
6
5
4
3
2
1
Resize the table to size (column = org. column*2, row = org. row / 2) recursively by sticking top x row to bottom x row from back to front
8 9
7 10
6 11
5 12
4 13
3 14
2 15
1 16
4 13 12 5
3 14 11 6
2 15 10 7
1 16 9 8
2 15 10 7 6 11 14 3
1 16 9 8 5 12 13 4
1 16 9 8 5 12 13 4 3 14 11 6 7 10 15 2
Read the final 1 row table from front to end as result
1 16 9 8 5 12 13 4 3 14 11 6 7 10 15 2
The remaining work to you is to prove this work and then code it (I only test up to n=4 because I am lazy)
You can calculate the number of a fold without having to calculate the whole sequence by using bit-reversal (which reverses the binary representation of a number, so that e.g. 0001 becomes 1000).
These are the sequences you get with bit reversal:
1 bit: 0 1
2 bits: 0 2 1 3
3 bits: 0 4 2 6 1 5 3 7
4 bits: 0 8 4 12 2 10 6 14 1 9 5 13 3 11 7 15
And these are the paper-folding sequences (counting from 0):
1 fold: 0 1
2 folds: 0 3 2 1
3 folds: 0 7 4 3 2 5 6 1
4 folds: 0 15 8 7 4 11 12 3 2 13 10 5 6 9 14 1
If you split the paper-folding sequences into even and odd numbers, you get:
0
1
0 2
3 1
0 4 2 6
7 3 5 1
0 8 4 12 2 10 6 14
15 7 11 3 13 5 9 1
You'll see that the paper-folding sequences are the same as the bit-reversal sequences, but with the first half (even numbers) interlaced with the reverse of the second half (odd numbers).
You'll also notice that each pair of adjacent even/odd numbers adds up to 2n-1 (where n is the number of folds), which means they are each other's inverse, and you can calculate one from the other using a bit-wise NOT.
So, to get the paper-folding number of fold x (counting from 0) of a strip folded n times:
divide x by 2, perform bitwise NOT if x was odd, then bit-reverse (using n digits)
Example (folding 4 times):
fold x/2 binary inverted bit-reversed from 1
0 0 0000 0000 0 1
1 0 0000 1111 1111 15 16
2 1 0001 1000 8 9
3 1 0001 1110 0111 7 8
4 2 0010 0100 4 5
5 2 0010 1101 1011 11 12
6 3 0011 1100 12 13
7 3 0011 1100 0011 3 4
8 4 0100 0010 2 3
9 4 0100 1011 1101 13 14
10 5 0101 1010 10 11
11 5 0101 1010 0101 5 6
12 6 0110 0110 6 7
13 6 0110 1001 1001 9 10
14 7 0111 1110 14 15
15 7 0111 1000 0001 1 2
Example: billionth fold: (folding 30 times)
fold: 1,000,000,000
counting from 0: 999,999,999 (x is odd)
x/2: 499,999,999
binary: 011101110011010110010011111111 (30 digits)
bitwise NOT: 100010001100101001101100000000 (because x was odd)
bit-reversed: 000000001101100101001100010001
decimal: 3,560,209
counting from 1: 3,560,210
I don't speak Java, but something like this should do the trick:
public static long foldIndex(int n, long x) { // counting from zero
return Long.reverse((x & 1) == 0 ? x >>> 1 : ~(x >>> 1)) >>> (Long.SIZE - n);
}
Here'a an algorithm to find what index a number will be at after the
unfolding.
It keeps track of the coordinates of where your search number is moving to based on the folds. For example, if you are interested in 3 folds (n=3, numFolds) and you want to know where the number 7 will be (searchNumber), the algorithm runs as follows:
Initial State:
8
7
6
5
4
3
2
1
The 7 is at [1,7] - column 1, row 7
Now, when we fold the top half down:
4 5
3 6
2 7
1 8
The 7 is at [2, 1] - column 2, row 2
When we do the next fold the 7 does not move (hence the if (row > half) logic)
2 7 6 3
1 8 5 4
On the last fold:
1 8 5 4 3 6 7 2
The 7 is at [7, 1] - column 7, row 1 and the code will return 7.
public static long getIndexOfAfterFold (long numFolds, long searchNumber)
{
long total = (long) Math.pow(2, numFolds);
long [] coordsOfSearchNumber = new long [] {1, searchNumber};
int iterations = 0;
while (iterations < numFolds)
{
long half = total / 2;
long row = coordsOfSearchNumber[1];
// we are folding down
if (row > half)
{
long newRow = (total - row) + 1;
long col = coordsOfSearchNumber[0];
long newFoldThickness = (long) Math.pow(2, iterations + 1);
long newCol = newFoldThickness - (col - 1);
coordsOfSearchNumber[0] = newCol;
coordsOfSearchNumber[1] = newRow;
}
total = total / 2;
iterations++;
}
return coordsOfSearchNumber[0];
}
EDIT: Converted the above code to use long instead on int.
Notes:
It runs in O(n) time where n is the number of folds.
Usage: System.out.println(getIndexOfAfterFold(4, 13));
This code will give the list of all numbers after the folding
Note: This is based on the answer supplied by #hk6279 (the table folding algorithm)
public static void unFold (int numFolds)
{
int total = (int) Math.pow(2, numFolds);
List<ArrayList<Integer>> table = new ArrayList<ArrayList<Integer>> (total);
// populate the single column table
for (int i = 0; i < total; i++)
{
ArrayList<Integer> list = new ArrayList<Integer>();
list.add(i + 1);
table.add(list);
}
int iterations = 0;
while (iterations < numFolds)
{
int half = table.size() / 2;
// place the fold back on itself
for (int i = 0; i < half; i++)
{
ArrayList<Integer> list = table.get(i);
ArrayList<Integer> foldList = table.get(table.size() - (i + 1));
// reverse the fold
Collections.reverse(foldList);
// add the fold to front
list.addAll(foldList);
}
// remove the part we folded
table.subList(half, table.size()).clear();
iterations++;
}
System.out.println(table);
}
This is what n=5 looks like:
1, 32, 17, 16, 9, 24, 25, 8, 5, 28, 21, 12, 13, 20, 29, 4, 3, 30, 19, 14, 11, 22, 27, 6, 7, 26, 23, 10, 15, 18, 31, 2
I don't know Java, but this should be easy to port and works for arbitrary numbers of folds. Idea's about the same as m69's, so I won't explain the logic myself.
#include <iostream>
size_t reverse(size_t n, int bits)
{
size_t result = 0;
size_t msb_value = 1 << (bits - 1);
while (n)
{
if (n & 1) result |= msb_value;
msb_value >>= 1;
n >>= 1;
}
return result;
}
struct Fold_Sequence
{
Fold_Sequence(size_t folds) : folds_(folds), max_(1 << folds) { }
size_t operator[](size_t i) const
{
size_t x = reverse((i / 2) % max_, folds_);
return i & 1 ? (max_ - x - 1) : x;
}
size_t folds_, max_, i = 0;
};
int main()
{
const size_t folds = 4;
const unsigned num_parts = 1 << folds;
Fold_Sequence seq{folds};
for (unsigned j = 0; j < num_parts; ++j)
std::cout << seq[j] + 1 << '\n';
}
I liked the elegance of hk6279's solution too, so I implemented it (also in C++, and I was too lazy to use a multidimensional array/vector<vector<>> and have to resize things carefully all the time, so it's inefficiently implemented using a map keyed on x,y coordinates):
#include <iostream>
#include <map>
#define DBG(X) do { std::cout << X << '\n'; } while (false)
typedef std::pair<size_t, size_t> Coord;
struct matrix : std::map<Coord, size_t>
{
matrix(size_t n)
: y_size_(n)
{
for (size_t i = 0; i < n; ++i)
(*this)[{0, i}] = i; // bottom left is 0,0; 0,1 is above
}
void fold()
{
size_t x_size_ = x_size();
for (size_t y = y_size_ / 2; y < y_size_; ++y)
for (size_t x = 0; x < x_size_; ++x)
move(x, y, x_size_ * 2 - x - 1, y_size_ - y - 1);
y_size_ /= 2;
}
void move(size_t from_x, size_t from_y, size_t to_x, size_t to_y)
{
DBG("move(" << from_x << ',' << from_y << " -> " << to_x << ',' << to_y
<< ") value " << ((*this)[{from_x, from_y}]));
(*this)[{to_x, to_y}] = (*this)[{from_x, from_y}];
erase({from_x, from_y});
}
size_t operator()(size_t x, size_t y) const
{
auto it = find({x, y});
if (it != end()) return it->second;
std::cerr << "m(" << x << ',' << y << ") doesn't exist\n";
exit(1);
}
size_t x_size() const { return size() / y_size_; }
size_t y_size() const { return y_size_; }
size_t y_size_;
};
std::ostream& operator<<(std::ostream& os, const matrix& m)
{
for (size_t y = m.y_size_ - 1; y <= m.y_size_; --y)
{
for (size_t x = 0; x < m.x_size(); ++x)
os << m(x, y) << ' ';
os << '\n';
}
return os;
}
int main()
{
const size_t n = 4;
matrix m(1 << n);
for (int i = 0; i < n; ++i)
{
m.fold();
std::cout << i+1 << " folds ==> " << m.x_size() << 'x' << m.y_size()
<< " matrix:\n" << m << '\n';
}
}

Outputting values 1 to A, with B values per row (Java)

public static void applicationB(int A, int B) {
int number = 1;
for (int row = 0; row < A; row++) {
for (int col = 0; col < B; col++) {
int output = number + row++;
System.out.printf("% 4d", output);
}
// does it skip because of this?
System.out.println("");
}
}
It outputs with A = 20, B = 5
1 2 3 4 5
7 8 9 10 11
13 14 15 16 17
19 20 21 22 23
The correct output should be
1 2 3 4 5
6 7 8 9 10
11 12 13 14 15
16 17 18 19 20
I cannot figure out how to get it to stop skipping 6, 12, and 18.
Am I just doing this a horrible way? or am I on the right track?
You are incrementing row in two places. Also, it would be easier to just have one loop, and output a line break every B elements (you can use i % B to test for this).
I would suggest the following approach. Iterate over the values you want to print out, from 1 to the maximum value (A). Then, print a newline whenever the remainder of value divided by the number of columns (B) is zero.
for (int value = 1; value <= A; value++) {
System.out.printf("% 4d", value);
if (value % B == 0) {
System.out.println("");
}
}

java nested for loops to get numbers triangle [duplicate]

This question already has answers here:
Java - creating a triangle with numbers using nested for-loops [closed]
(2 answers)
Closed 8 years ago.
my output should look like in image 1, but my output looks like in image 2.
I am not suppose to print out ... there I have to print out same thing with 32 then 64. int
That is what i have so far, I got half of the triangle correct. I don't know how to reverse it though.
k = 1;
int j;
int l = 1;
for(int i=1; i <= 8; i++){
for(j=8; j>i; j--){
System.out.print(" ");
}
for(j=1; j<=k; j=j*2){
System.out.print(j + " ");
}
for (j = 1; j<k; j=j*2) {
System.out.print(j + " ");
}
k = k * 2;
System.out.println();
}
}
}
Your problem is, in the 2nd loop, you still go from j=1 -> k. You can simply do a k -> 1 loop to get a reversed sequence.
Also java has printf method, you may want to take a look..
Some example codes:
int rows = 8;
for (int r = 0; r <= rows; r++) {
System.out.print(new String(new char[rows - r]).replace("\0", " "));
int c = 0;
for (int i = 0; i <= r; i++)
System.out.printf("%s%s", 1<<i, r == 0? "\n" : " ");
if (r > 0)
for (int i = r-1; i >= 0; i--)
System.out.printf("%s%s", 1<<i, i == 0? "\n" : " ");
}
just adjust the rows to the value you like.
I did a test with rows=8, it prints:
1
1 2 1
1 2 4 2 1
1 2 4 8 4 2 1
1 2 4 8 16 8 4 2 1
1 2 4 8 16 32 16 8 4 2 1
1 2 4 8 16 32 64 32 16 8 4 2 1
1 2 4 8 16 32 64 128 64 32 16 8 4 2 1
1 2 4 8 16 32 64 128 256 128 64 32 16 8 4 2 1

Categories