Creating a looping square with java - java

Full Disclosure: Homework.
Explanation: I cant understand my teacher.
Problem:
Write a method called printSquare that takes in two integer
parameters, a min and a max, and prints the numbers in the range from
min to max inclusive in a square pattern. The square pattern is
easier to understand by example than by explanation, so take a look at
the sample method calls and their resulting console output in the
table below. Each line of the square consists of a circular sequence
of increasing integers between min and max. Each line prints a
different permutation of this sequence. The first line begins with
min, the second line begins with min + 1, and so on. When the
sequence in any line reaches max, it wraps around back to min. You
may assume the caller of the method will pass a min and a max
parameter such that min is less than or equal to max
I cannot for the life of me figure out how to make the numbers stop at the 'max' value and start over in the middle of the line.
This is what I have so far, apologies but I have trouble with for loops.
for(int i = 0; i < row; i++)
{
for(int d = 0; d < row; d++)
{
System.out.print(d+1);
}
System.out.println(i);
}
I know I used row twice, but its the only way i can get the compiler to form a square shape with the loop. Does anyone even remotely understand what i'm trying to do? :/

This is actually a nice mathematical problem. Assume:
int side = to - from + 1; /// the size/width of the square.
the value at any point in the square (row, col) is:
from + ((row + col) % side)
you should be able to put that in your loops and "smoke it".
Edit based on comment asking for explanation.
The trick is to loop through all the positions in the 'matrix'. Given that the matrix is square, the loops are relatively simple, just two loops (nested) that traverse the system:
final int side = to - from + 1;
for (int row = 0; row < side; row++) {
for(int col = 0; col < side; col++) {
... magic goes here....
}
}
Now, in this loop, we have the variables row and col which represent the cell in the matrix we are interested in. The value in that cell needs to be proportional to the distance it is from the origin..... let me explain.... If the origin is the top left (which it is), then the distances from the origin are:
0 1 2 3 4
1 2 3 4 5
2 3 4 5 6
3 4 5 6 7
4 5 6 7 8
The distance is the sum of the row and the column...... (rows and columns start counting from 0).
The values we put in each matrix are limited to a fixed range. For the above example, with a square of size 5, it could have been specified as printSquare(1,5).
The value in each cell is the from value (1 in this example) plus the distance from the origin... naively, this would look like:
1 2 3 4 5
2 3 4 5 6
3 4 5 6 7
4 5 6 7 8
5 6 7 8 9
here the values in the cell have exceeded the limit of 5, and we need to wrap them around... so, the trick is to 'wrap' the distances from the origin..... and the 'modulo' operator is great for that. First, consider the original 'origin distance' matrix:
0 1 2 3 4
1 2 3 4 5
2 3 4 5 6
3 4 5 6 7
4 5 6 7 8
if we instead populate this matrix with 'the remainder of the distance when dividing by 5' (the modulo 5, or %5) we get the matrix:
0 1 2 3 4
1 2 3 4 0
2 3 4 0 1
3 4 0 1 2
4 0 1 2 3
Now, if we add this 'modulo' result to the from value (1), we get our final matrix:
1 2 3 4 5
2 3 4 5 1
3 4 5 1 2
4 5 1 2 3
5 1 2 3 4
in a sense, all you need to know is that the value at each cell is:
the from value plus the remainder when you divide the 'distance' by the width.
Here's the code I tested with:
public static final String buildSquare(final int from, final int to) {
final StringBuilder sb = new StringBuilder(side * side);
final int side = to - from + 1;
for (int row = 0; row < side; row++) {
for(int col = 0; col < side; col++) {
sb.append( from + ((row + col) % side) );
}
sb.append("\n");
}
return sb.toString();
}
public static void main(String[] args) {
System.out.println(buildSquare(1, 5));
System.out.println(buildSquare(3, 9));
System.out.println(buildSquare(5, 5));
System.out.println(buildSquare(0, 9));
System.out.println(buildSquare(0, 3));
}

Since this is homework, I'll just give a hint.
I cannot for the life of me figure out how to make the numbers stop at the 'max' value and start over in the middle of the line.
Here's one way to do it.
Create the first number twice in an array. Taking the printSquare(1, 5) example, create an int array of 1, 2, 3, 4, 5, 1, 2, 3, 4, 5.
Use a loop to loop through the array, starting with element zero and ending with element 4, and another loop to display 5 digits (max - min + 1).

try this
int i,j,k;
for(i=min;i<=max;i++) {
for(j=i;j<=max;j++) {
System.out.print(j);
}
for(k=min;k<i;k++){
System.out.print(k);
}
System.out.println();
}

you can try
loop from min value to max value and put all the numbers in an array
now loop again from min value to max value
each time print the array and do a circular shift (for circular shift you can find lot of example in SO)

I think #rolfl's solution is the cleanest. I'd recommend going with that.
You can find another simple solution by observing that each output in your "square" simply shifts the first element to the end the list of numbers. To imitate this, you can put all the numbers from min to max in a data structure like LinkedList or ArrayDeque where you can easily add/remove items from both ends, then you'd print the contents in order, and shift the first entry to the end. E.g., coll.addLast(coll.removeFirst()). If you repeat that process max - min + 1 times, you should get the desired output.

no array no problem you can easily solve.
it work with any range of number.
static void printSquare(int min, int max){
int len = max - min + 1;
int copy_min = min, permanent_min = min;
for(int i = 0; i < len; i++){
for(int j = 0; j< len; j++){
if(min > max)
if(min % len < permanent_min)
System.out.print((min % len )+ len);
else
System.out.print(min % len);
else
System.out.print(min);
min++;
}
min = ++copy_min;
System.out.println();
}
}

public static void printSquare(int min, int max)  {
    
    for (int i = min; i <= (max -min)+min; i++)  {
        
        for( int j =i; j <= max ; j++) {                
            System.out.print(j);   
            } 
        for (int j1= min; j1<= i * 1 - 1; j1++) {
            System.out.print(j1);
            }
        System.out.println();
    }
    
}

Related

How would I loop over the permutations of N numbers with a given range, preferably without recursion?

I have N numbers, and a range, over which I have to permute the numbers.
For example, if I had 3 numbers and a range of 1-2, I would loop over 1 1 1, 1 1 2, 1 2 1, etc.
Preferably, but not necessarily, how could I do this without recursion?
For general ideas, nested loops don't allow for an arbitrary number of numbers, and recursion is undesireable due to high depth (3 numbers over 1-10 would be over 1,000 calls to the section of code using those numbers)
One way to do this, is to loop with one iteration per permuation, and use the loop variable to calculate the values that a permuation is made off. Consider that the size of the range can be used as a modulo argument to "chop off" a value (digit) that will be one of the values (digits) in the result. Then if you divide the loop variable (well, a copy of it) by the range size, you repeat the above operation to extract another value, ...etc.
Obviously this will only work if the number of results does not exceed the capacity of the int type, or whatever type you use for the loop variable.
So here is how that looks:
int [][] getResults(int numPositions, int low, int high) {
int numValues = high - low + 1;
int numResults = (int) Math.pow(numValues, numPositions);
int results[][] = new int [numResults][numPositions];
for (int i = 0; i < numResults; i++) {
int result[] = results[i];
int n = i;
for (int j = numPositions-1; j >= 0; j--) {
result[j] = low + n % numValues;
n /= numValues;
}
}
return results;
}
The example you gave in the question would be generated with this call:
int results[][] = getResults(3, 1, 2);
The results are then:
1 1 1
1 1 2
1 2 1
1 2 2
2 1 1
2 1 2
2 2 1
2 2 2

Getting median out of frequency table (counting sort)

I can't understand the logic behind getMedian method. How exactly median is evaluated, what is the connection between count of elements and sum of elements? Appreciate if someone could explain it's logic.
public static void main(String[] args) {
Random r = new Random();
int[] ar = r.ints(0, 100).limit(9).toArray();
int k = ar.length;
int[] count = getCounts(ar);
double median = getMedian(count, k);
System.out.println(median);
}
private static int[] getCounts(int[] ar) {
int[] count = new int[100];
for (int i = 0; i < ar.length; i++) {
count[ar[i]]++;
}
return count;
}
private static double getMedian(int[] count, int d) {
int sum = 0;
for (int i = 0; i < count.length; i++) {
sum += count[i];
if (2 * sum < d)
continue;
else if (2 * sum == d)
return (2 * i + 1) / 2.0;
else
return i * 1.0;
}
return -1.0;
}
There is a relation because it is a frequency table. You are thinking it differently but let me give you an example.
1 1 1 3 3 4 4 4 5 5 5 5 if this is the array then the frequency table would be :-
1 3 4 5
- - - -
3 2 3 4
So this is median.
So now I am adding every element count and asking us the question, where does the median lie? or where is that indexm which if I consider I will cover the middle element?
Now here I am checking if sum > d/2 then it's done. We found the median.else if it is less then I still have to traverse other elements to get to the middle of the array. And if it is sum==d/2 then we have found it but we have to send the correct position. And we simply send the one in the lower middle (happens in case like 1,1,1,1).
Walk through
1 1 1 3 3 4 4 4 5 5 5 5
Now I check if I traverse all set of 1's where I am? I covered 3 elements. But it's not the half of the total numbers(6).
Now add number of 3's. 5. This is also not.
Now I add number of 4's, So 8 elements I covered. So I covered more than half of number of elements. So median lies here.
More detailed explanation:
You are asked to find the median of an array of 10 integers.
[1 2 3 4 5 6 7 8 9]
Then median is in element at position floor(9/2)=4, which is 5 Right?
[1 1 2 2 3 3 4 4 5]
Where is the median element at position floor(9/2)=4, which is 3. Right?
So now think this,
1 2 3 4 5
2 2 2 2 1
Now you will try to find the floor(9/2) th element here starting from beginning. And that's why you need to find the sum of the frequencies and all.
Hope you get it?
Correct algorithm
What you need to do is :-
N = number of elements.
F[] = frequency array
so if N is odd
find the element at floor(N/2)-th place and median is that element.
else
find the element at floor((N-1)/2) and floor(N/2) th position and return their average.
Finding the element is simple:
Find( F[], p) // find the element at position p
{
p=p+1
for i in [0..|F|]
cumulative+=F[i]
if cumulative == p
return this element.
else cumulative >p
return this element
}

Adding Two Elements in an Array (Java)

I need to write a method that adds the two last elements of two arrays together and add the sum on another array. But if the two elements are more than 10, then I would need to carry that number to the next array.
This program should be similar to what an odometer does.
Here is my sample code.
int [] sum(int []number1, int []number2)
{
int [] total;
int carry = 0;
for ( int k = numbers1 - 1; k >= 0; k++)
{
sum = number1[k] + number2[k] + carry;
carry = sum/10;
total[k] = sum
}
return total;
}
An example output would be:
0 1 2 3 4
0 8 9 9 9
4 5 7 0 3
5 4 7 0 2
So the top array is just a visual aid that tells where the position for the number is.
The program is suppose to add the next two arrays together. i.e. 9 + 3 = 12
Since 12 is above 9, it carries over the 10 to the next set of arrays, that is why the third array only has a 2 in its place, and that is why the next array is 9 + 0 = 0; because the 10 was carried over.
I am not sure why my code won't work. I don't get the right numbers. Could anyone give any hints or solution to the problem?
-Thanks
I assume numbers1 is the number of elements in the array.
In this case it should be k-- instead of k++ because you are starting from the last element and moving backword.

3 Dice Sum Counting Program Java

For my Computer Science Class, my teacher is asking us to do the following:
Program Description: You are learning to play a new game that involves 3 six-sided die. You know that if you knew the probability for each of the possible rolls of the die that you’d be a much better competitor.
Since you have just been studying arrays and using them to count multiple items that this program should be a snap to write. This will be cool since the last time we did this we work just looking for how many times 9 or 10 could be rolled and this program won’t require any if statements.
Required Statements: output, loop control, array
Sample Output:
Number Possible Combinations
1 0
2 0
3 1
4 3
5 6
6 10
7 15
8 21
9 25
10 27
11 27
12 25
13 21
14 15
15 10
16 6
17 3
18 1
I can easily do this with an if statement, but I don't understand how to do it without one. It is especially tricky because under hints, she wrote: "These programs utilize a counting array. Each time a value is generated the position at that index is incremented. It’s like the reverse of the lookup table." I have no idea what this means.
Here's my code with the if statement:
public class prog410a
{
public static void main(String args[])
{
System.out.println("Number\tPossible Combinations");
for (int x = 1; x <= 18; x++)
{
int count = 0;
for (int k = 1; k <= 6; k++)
{
for (int i = 1; i <= 6; i ++)
{
for (int j = 1; j <= 6; j++)
{
if (k + i + j == x)
count++;
}
}
}
System.out.println(x + "\t\t\t" + count);
}
}
}
So I guess my overall question is this: How can I emulate this, but by using some sort of array instead of an if statement?
You don't need the outer x loop. All you need is three nested loops, one for each die. You will also need an array of integers all initialized to zero. Inside the innermost dice loop, you just use the sum of the three dice as the index to you integer array and increment the value at that index.
After you complete the dice loops, then you can iterate over your integer array and output the frequency of your results.
Since this is homework, I won't write the code for you, just give you the general outline.
Create a count array of size 18. Initialise all values to 0.
Have three nested loops counting from 1 to 6 exactly like your three inner loops. These represent the values on your dice.
Inside your innermost loop, add the three loop counters together. This is your dice total and you use it as an index into the count array to increment the value at that index.
After you exit the three nested loops, use another loop to iterate through the count array to print out the values.
This seems to work - and without if:
public void test() {
// Remember to -1 because arrays are accessed from 0 to length-1
int[] counts = new int[18];
// Dice 1.
for (int k = 1; k <= 6; k++) {
// Dice 2.
for (int i = 1; i <= 6; i++) {
// Dice 3.
for (int j = 1; j <= 6; j++) {
// Count their sum (-1 as noted above).
counts[i + j + k - 1] += 1;
}
}
}
// Print out the array.
System.out.println("Number\tPossible Combinations");
for (int i = 0; i < counts.length; i++) {
System.out.println("" + (i + 1) + "\t" + counts[i]);
}
}
Essentially you build the results in an array then output them.
From Wikipedia: In computer science, a lookup table is an array that replaces runtime computation with a simpler array indexing operation. The savings in terms of processing time can be significant, since retrieving a value from memory is often faster than undergoing an 'expensive' computation or input/output operation., this means that usually we use lookup tables to save computation time by precalculating some process into a table in which we already stored the result. In this case you are using the process to store the number of possible outcomes in an array. Basically you are building a lookup table for the dice outcome. Only the three inner loops are needed.
for (int k = 1; k <= 6; k++)
{
for (int i = 1; i <= 6; i ++)
{
for (int j = 1; j <= 6; j++)
{
arr[k + i + j-1] = arr[k + i + j-1] +1;
}
}
}
And this is what is happening:
dices index
i j k (i+j+k)
1 1 1 3
1 1 2 4
1 1 3 5
1 1 4 6
1 1 5 7
1 1 6 8
1 2 1 4
1 2 2 5
1 2 3 6
1 2 4 7
1 2 5 8
1 2 6 9
1 3 1 5
1 3 2 6
.
.
.
You are enumerating each possible outcome and then adding the spot in the array with the index generated. When the nested loops are done, you will have an array containing the desired information.

For loop to print the number in sequence and reverse it

How to print the following output with only one for-loop in java?
1 2 3 4 5 6 7 8 9 1 0 9 8 7 6 5 4 3 2 1
Code snippet:
class Series{
public static void main(String args[]){
for(int i=1; i<=10; i++){
System.out.println(i);
}
System.out.println(i);
for(int j=9; j>=0; j--){
System.out.println(j);
}
}
My program's in the following manner. Can anyone correct it?
public static void main(String...strings ){
int dir = 1;
for(int i=1; i>0; i+=dir){
if(i == 10)
dir = -1;
System.out.print(i+" ");
}
}
Output:
1 2 3 4 5 6 7 8 9 10 9 8 7 6 5 4 3 2 1
The series in the question is wrong.
It should be: 1 2 3 4 5 6 7 8 9 10 9 8 7 6 5 4 3 2 1
The code, in one loop, is as follows:
int ctr = 1;
for(int i = 1; i > 0; i += ctr)
{
if(i == 10)
{
ctr = -1;
}
System.out.print(i + " ");
}
Every sequence follows a pattern, Let's try finding one in this.
To work with this code, analyze What loop would print with the variable that you increment and What you want in the output?
In your problem, assuming that the number you are entering is entered by user i.e. n, you want 2*n - 1 numbers in your sequence. Hence we now have the limits of our loop
For n=5, Under no Conditions the loop would simply print a sequence like this
1 2 3 4 5 6 7 8 9 provided you are starting your loop from 1.
The sequence you want is 1 2 3 4 5 4 3 2 1.
Now looking at both the sequences you can see that the sequence is same till the mid point that is till the value of n is reached. Now if you observe the pattern further if you subtract 2 from 6 you get 4 that is the number you want in your sequence. Similarly when you subtract 4 from 7 you get 3 which is the next number in the sequence you required.
Hence the pattern this sequence follows is that after the loop reaches the value provided by the user you need to subtract (2 * k) from the next number where k starts from 1 and increases with every iteration
Now you know how to achieve the pattern which would be easy to achieve using conditional statements.
PS: let's assume an added constraint of using no conditional statements then we have to write an arithmetic expression to solve our problem.
Following the pattern again the expression must display i where i is the variable incremented in the loop
so our code looks like
for (i = 1; i<=2*n - 1;i++)
{
System.out.print(i);
}
Now to get the pattern we need to subtract multiples of 2 after the user provided integer n is reached. But whatever we subtract should also not affect out first n integers.
Since we know we have to subtract multiples of 2 we know the expression we have to subtract would look like 2 * (____). As we want a sequence of multiples we can obtain that using %. As soon as the number goes over n the % operator on i would give us back sequence from 0 to n-1 hence generating multiples of 2.
Now our expression comes to 2 * (i % n). But the problem is that it would also subtract from the first 4 integers which we don't want so we have to make changes such that this expression will work only after loop reaches the value provided by the user.
As we know the division / operator provides us with the quotient. Hence it would yield us 0 till we reach the value of user defined number and 1 for the rest of the sequence as we run our loop till 2*n -1. Hence multiplying this expression to our previous expression yields 2*(i%n)*(i/n)
And there we have it our final code to generate the sequence would be
for (int i = 1;i<2*r;i++)
{
System.out.print(i - 2 * (i%r)*(i/r));
}
Observe the above code for the first n-1 integers i/r would make subtracted expression 0 and for i = n, i % r would make the expression 0. For the rest of the sequence i / r would generate value 1 and hence we will get multiples of 2 from 2 *( i % r) to provide us with the sequence
try this
int j = 10;
for (int i = 1; i <= 10; i++) {
if(i<10)
System.out.print(" " +i);
if(i==10){
i--;
System.out.print(" " +j);
if(j==1){
i++;
}
j--;
}
}
OutPut
1 2 3 4 5 6 7 8 9 10 9 8 7 6 5 4 3 2 1
Something like this?
for(int i=0;i<20;i++) {
if((i/10)%2 == 0)
System.out.print(i%10 + " ");
else
System.out.print((10-(i%10)) + " ");
}
Try this code, You just need a if condition in for loop.
int i = 1;
for(int j=1; j<=20; j++)
{
if(j<11)
System.out.print(j+" ");
else
{
System.out.print((j - i == 10 ?" ": (j-i + " ")));
i = i+2;
}
}
public class forLoopTest {
public static void main(String[] args) {
for (int i = 1; i < 10; i++) {
System.out.print(i + " ");
}
for (int j = 10; j >= 1; j--) {
System.out.print(j + " ");
}
}
}

Categories