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.
Related
I am trying to solve a classical coin-change (dynamic) problem.
To find number of all unique combinations to get a sum from infinite denominations of coins using dynamic approach, i used this method:
/*
n - number of coins
arr[] - coin denominations
x - total sum
dp[] - array to store number of combinations at index i.
*/
for (int j = 0; j < n; j++)
for (int i = 1; i <= x; i++)
if (arr[j] <= i)
dp[i] = (long) ((dp[i] + dp[i - arr[j]]) % (1e9 + 7));
This gives me all unique possible combinations count:
Eg:
Input:
n=3 x=9
Coins: 2 3 5
Output:
3
So far ,all good.
But i observed that just by interchanging the loops in above snippet, i get all the possible permutations.
for (int i = 1; i <= x; i++)
for (int j = 0; j < n; j++)
if (arr[j] <= i)
dp[i] = (long) ((dp[i] + dp[i - arr[j]]) % (1e9 + 7));
This gives me all unique possible permutations count:
Eg:
Input:
3 9
2 3 5
Output:
8
With debugging and going through each iteration, i mapped a pattern that was formed, but didn't understand the reason behind why i am getting permutations.
Can any one explain me this iteratively. Any help will be appreciated.
Thanks
Both questions can be found here:
Permutations: Coin Combinations 1
Combinations: Coin Combinations 2
The first code with outer loop by coins updates number of ways to compose values dp[] with new coin at every round of outer loop. So after k-th round we have dp[] array filled with combinations of k coins only, and the rest of coins is not used yet. If we will store combinations themselves for sorted coin array, we will see only ordered ones like 1 1 5, and 5 never will go before 1. That is why combinations.
The second code at m-th round of outer loop fills m-th cell dp[m] using all possible coins. So we count for m=7 both 1 1 5 and 1 5 1 and 5 1 1 variants. That is why all permutations are counted here.
In addition for comment: we can make 2d array, where dp[x][c] contains number of permutations with sum x, ending with coin a[c]. Note that in this case we have to join counts of permutations with sum x-a[c]. For reference - 1d and 2d Python code.
def coins1(a, n): #permutations
count = [1]+[0]*n
for x in range(1, n + 1):
for c in a:
if (x-c >= 0):
count[x] += count[x-c]
return count[n]
def coins11(a, n): #permutations 2d
m = len(a)
count = [[1] + [0]*(m-1)] + [[0]*m for i in range(n)]
for x in range(1, n + 1):
for c in range(m):
if x>=a[c]:
count[x][c] += sum(count[x-a[c]])
return sum(count[n])
Write a program that prints a part of the sequence:
1 2 2 3 3 3 4 4 4 4 5 5 5 5 5 ...
(the number is repeated as many times, to what it equals to).
I've used two for loops, however, I can't get 1 to print once, 2 to print twice, instead, I get
1 2 3 4 5 6 1 2 3 4 5 6, etc.
You need two for loops for this.
for (int i = 0; i <= 5; i++) { // This will loop 5 times
for (int j = 0; j < i; j++) { //This will loop i times
System.out.print(i);
}
}
As I remember the goal is to print n numbers (for example 1 2 2 3 3 3 4 for n = 7), diveded by space. Sorry for my java)), I wrote it in Kotlin, tried to change for Java, but main idea is clear. BTW n – the number of the elements, you need to read with Scanner.
int count = 0 //Idea is to create a counter, and to increment it each time of printing
for (int i = 0; i <= n; i++) { //Loops n times
for (int j = 0; j < i; j++) { //Loops i times
if (int count < int n) {
System.out.print(" "+i+" ");
int count++ //Prints 1 one time, 2 two times, etc. stops if reached n number
}
}
}
How about this :
for(int i=1;i<=num;i++){
for(int j=1;j<=i;j++){
System.out.print(" "+i+" ");
}
}
where, num = 1,2,....n
(Also we wont be able to tell why you got that output unless you attach the code. Please attach the code snippets for such questions :) !
So the goal was to use a nested for loop to output 6 rows and 10 columns. The thing was though that the inner for loop was supposed to check to see whether the number was even or odd as, if it was even, we would add 2 to it and then print out that number 10 times before moving onto the next output. So this is what were were supposed to get
1 1 1 1 1 1 1 1 1 1
4 4 4 4 4 4 4 4 4 4
3 3 3 3 3 3 3 3 3 3
6 6 6 6 6 6 6 6 6 6
5 5 5 5 5 5 5 5 5 5
8 8 8 8 8 8 8 8 8 8
I thought I was on the right track but my output is a complete mess, here's what I have. Thank you to anyone willing to help.
for (int numberE = 1; numberE <= 6; numberE++)
{
for (int nestedE = 1; nestedE < 10; nestedE++)
{
if (numberE%2 == 0)
{
numberE += 2;
System.out.printf("%2d", numberE);
} else {
System.out.printf("%2d", numberE);
}
}
System.out.printf("%2d\n", numberE);
}
well to start with your inner loop will only iterate nine times. second you don't need a nested loop, you need one loop and a guard determining when to print.
Don't modify numberE inside the loops. Instead just print numberE + 2.
Also, if your inner loop runs from 0 to <10 you will get 10 iterations and you don't need to print the number again - just a newline.
for (int numberE = 1; numberE <= 6; numberE++)
{
for (int nestedE = 0; nestedE < 10; nestedE++) // <-- start at 0 and end <10 for 10 iterations
{
if (numberE%2 == 0)
{
System.out.printf("%2d", numberE + 2); // <-- print the number + 2
} else {
System.out.printf("%2d", numberE);
}
}
System.out.println(); // <-- don't print the value again here
}
I would do it this way. Gives the required result.
public class NestedForLoop {
public static void main(String[] args) {
for (int i = 1; i <= 6; i++)
{
int temp = i;
if(temp%2 == 0) {
temp +=2;
}
for(int j=1;j<=10;j++) {
System.out.print(temp+" ");
}
System.out.println();
}
}
}
A brief description of what is happening here:
So, since we need 6 rows, we use the value of 6 as a row counter. The variable i takes care of keeping a count of the rows. Here since the target is 6, we start from row number 1 and go until row no 6. Inside each value of the loop, we save the value of i to temp because we don't want the value of i to change before incrementing in the main for loop. We then check if this temp value is even by doing a modulo division by 2. If it is even, we increment the temp value by 2.
Then, we run a loop from 1 to 10 since we need 10 columns to print the value temp(either the original i or incremented because it was even). After exiting the loop, finally to move to the next row, we do a System.out.println().
I would suggest using a temporary variable to store the current intended value.
The issue with your solution was that you were modifying the value of numberE by using numberE += 2; inside the second for loop, this changes the value globally.
Moving the final column in to the nested for loops also makes it easier as you wouldn't need to define the temporary variable outside of the loop. Using this also meant changing the <10 to <=10.
for (int numberE = 1; numberE <= 6; numberE++) {
for (int nestedE = 1; nestedE <= 10; nestedE++) {
int current = (numberE % 2 == 0) ? numberE + 2 : numberE;
System.out.printf("%2d", current);
}
System.out.printf("\n");
}
You were pretty close though, with practise you'll get better.
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 + " ");
}
}
}
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();
}
}