I'm having a minor problem with a program I'm working on. Everything works out perfectly, except for one tiny part.
public class Prog230b
{
public static void main (String args[])
{
for(int i = 1; i <= 25; i++) //
{
int num = i;
System.out.print("\n" + num + ":");
while(num != 1)
{
if(num % 2 == 0)
num /= 2;
else
num = 3 * num + 1;
System.out.print(EasyFormat.format(num,4,0));
}
}
}
}
EasyFormat is just a reference to an exterior formatting file. Below is my output.
1:
2: 1
3: 10 5 16 8 4 2 1
4: 2 1
5: 16 8 4 2 1
6: 3 10 5 16 8 4 2 1
7: 22 11 34 17 52 26 13 40 20 10 5 16 8 4 2 1
8: 4 2 1
9: 28 14 7 22 11 34 17 52 26 13 40 20 10 5 16 8 4 2 1
10: 5 16 8 4 2 1
11: 34 17 52 26 13 40 20 10 5 16 8 4 2 1
12: 6 3 10 5 16 8 4 2 1
13: 40 20 10 5 16 8 4 2 1
14: 7 22 11 34 17 52 26 13 40 20 10 5 16 8 4 2 1
15: 46 23 70 35 106 53 160 80 40 20 10 5 16 8 4 2 1
16: 8 4 2 1
17: 52 26 13 40 20 10 5 16 8 4 2 1
18: 9 28 14 7 22 11 34 17 52 26 13 40 20 10 5 16 8 4 2 1
19: 58 29 88 44 22 11 34 17 52 26 13 40 20 10 5 16 8 4 2 1
20: 10 5 16 8 4 2 1
21: 64 32 16 8 4 2 1
22: 11 34 17 52 26 13 40 20 10 5 16 8 4 2 1
23: 70 35 106 53 160 80 40 20 10 5 16 8 4 2 1
24: 12 6 3 10 5 16 8 4 2 1
25: 76 38 19 58 29 88 44 22 11 34 17 52 26 13 40 20 10 5 16 8 4 2 1
The problem is that it prints nothing for 1. I know this is because I have while(num != 1), but I am unsure what to put instead that does not result in an infinite loop.
Use a do-while loop instead. That way your code will execute at least one time when num starts as 1.
do
{
if(num % 2 == 0)
num /= 2;
else
num = 3 * num + 1;
System.out.print(EasyFormat.format(num,4,0));
} while (num != 1);
Related
I want to ask a question or a probable favor on how am I going to make my program coding "do-while loop" in creating a Triangular Multiplication. Is there a probable way on to create such thing without using any other statement?
public class Main {
static void ssbr(int n) {
int i = 1;
do{
System.out.printf("%4d", n * i);
i = i + 1;
} while(i <= 7);
System.out.println("");
}
public static void main(String[] args) {
int i = 1;
do{
ssbr(i);
i = i + 1;
} while (i <= 7);
}
}
Output it gave:
1 2 3 4 5 6 7
2 4 6 8 10 11 12
3 6 9 12 15 18 21
4 8 12 16 20 24 30
5 10 15 20 25 30 35
6 12 18 24 30 36 42
7 14 21 28 35 42 49
Output I wanted:
1
2 4
3 6 9
4 8 12 16
5 10 15 20 25
6 12 18 24 30 36
7 14 21 28 35 42 49
You can do it with the following algorithm:
You have to do it 7 times and therefore you can use a loop that should run 7 times.
Each row starts with the row number, and run for row number * row number times with a step-value equal to the row number.
Given below is the implementation of this algorithm using for loop and I leave it to you to implement it using the do-while loop (as it seems to be your homework 😀)
public class Main {
public static void main(String[] args) {
int n = 7;
for (int row = 1; row <= n; row++) {
for (int col = row; col <= row * row; col += row) {
System.out.printf("%-4d", col);
}
System.out.println();
}
}
}
Output:
1
2 4
3 6 9
4 8 12 16
5 10 15 20 25
6 12 18 24 30 36
7 14 21 28 35 42 49
In the below code block:
public static void main(String[] args) {
int i;
int x = 0;
int count;
int sum = 0;
Scanner scan = new Scanner(System.in);
System.out.println("Enter The Table Operator (+, -, *, /, %, or R)");
String operator = scan.nextLine();
System.out.println("Enter The Smallest Operand For the Table:");
int small = scan.nextInt();
System.out.println("Enter The Largest Operand For the Table");
int large = scan.nextInt();
for(i = 0; i < 12; i++) {
for(x = 0; x <= large; x ++)
System.out.printf("%4d", x + small);
System.out.printf("\n");
x++;
large++;
}
}
The code outputs:
1 2 3 4 5 6 7 8 9 10 11 12 13
1 2 3 4 5 6 7 8 9 10 11 12 13
1 2 3 4 5 6 7 8 9 10 11 12 13
1 2 3 4 5 6 7 8 9 10 11 12 13
1 2 3 4 5 6 7 8 9 10 11 12 13
1 2 3 4 5 6 7 8 9 10 11 12 13
1 2 3 4 5 6 7 8 9 10 11 12 13
1 2 3 4 5 6 7 8 9 10 11 12 13
1 2 3 4 5 6 7 8 9 10 11 12 13
1 2 3 4 5 6 7 8 9 10 11 12 13
1 2 3 4 5 6 7 8 9 10 11 12 13
1 2 3 4 5 6 7 8 9 10 11 12 13
but I want it to look like this:
1 2 3 4 5 6 7 8 9 10 11 12 13
2 3 4 5 6 7 8 9 10 11 12 13 14
3 4 5 6 7 8 9 10 11 12 13 14 15
4 5 6 7 8 9 10 11 12 13 14 15 16
5 6 7 8 9 10 11 12 13 14 15 16 17
6 7 8 9 10 11 12 13 14 15 16 17 18
7 8 9 10 11 12 13 14 15 16 17 18 19
8 9 10 11 12 13 14 15 16 17 18 19 20
9 10 11 12 13 14 15 16 17 18 19 20 21
10 11 12 13 14 15 16 17 18 19 20 21 22
11 12 13 14 15 16 17 18 19 20 21 22 23
12 13 14 15 16 17 18 19 20 21 22 23 24
It's basically an addition table. I'm trying to get the x value and the value of "large" to implement by one on each loop. I'm pretty sure I'm using the for loop incorrectly but I haven't been able to find out how.
for (int row = 1; row <= 12; row++) {
for (int col = row; col < row + 13; col++)
System.out.print(col != row ? " " + col : col);
System.out.println();
}
This pretty simple trianlge. Just inline all temporary variables like row and 'col' into the loops. Be simple.
int large = 10;
int small = 0;
int x,i;
for( i = 0; i < large; i++) {
for( x = 1; x <= large; x ++)
System.out.printf("%d ", x + small);
System.out.printf("\n");
x++;
small++;
}
Change "%4d" to "%d ". %4d makes every number 4 spaces long no matter what but you wanted the number and one space.
The last line in your outer for-loop should be small++ instead of large++ to offset the start value each time.
Your loop looks right. You are incrementing the wrong variables.
for(i = 0; i < large; i++) {
for(x = 0; x <= large; x ++){
System.out.printf("%4d", x + small);
}
System.out.printf("\n");
small++;
}
output:
1 2 3 4 5 6 7 8 9 10 11 12 13
2 3 4 5 6 7 8 9 10 11 12 13 14
3 4 5 6 7 8 9 10 11 12 13 14 15
4 5 6 7 8 9 10 11 12 13 14 15 16
5 6 7 8 9 10 11 12 13 14 15 16 17
6 7 8 9 10 11 12 13 14 15 16 17 18
7 8 9 10 11 12 13 14 15 16 17 18 19
8 9 10 11 12 13 14 15 16 17 18 19 20
9 10 11 12 13 14 15 16 17 18 19 20 21
10 11 12 13 14 15 16 17 18 19 20 21 22
11 12 13 14 15 16 17 18 19 20 21 22 23
12 13 14 15 16 17 18 19 20 21 22 23 24
int small = 1;
int large = 12;
for(int i = 0; i < 12; i++) {
for(int x = i; x <= i + large; x ++)
{
System.out.printf("%4d", x + small);
}
System.out.printf("\n");
}
checkout this simple change by changing the x ranges from i -> i + large which will avoid increment large ( because it is not need as in every iteration i also increase)
what you are trying to is in every iteration of i and x you are increment it at the end of the print operation that wont effect exactly as you want because for every iteration the value you print should iterate and print so change the x value to i, which will get incremented in every iteration and use it till i + large (where large is the number you obtain as maximum limit)
Note this can be achieved since small, and large are constant through out the loop
The code below is the answer I wrote for a question that asks to rotate an n x n 2D matrix by 90 degrees (clockwise), without creating a new 2D array. So for example,
Given input matrix =
[
[1,2,3],
[4,5,6],
[7,8,9]
],
rotate the input matrix:
[
[7,4,1],
[8,5,2],
[9,6,3]
]
I tried to do it row by row, but the problem I have to deal with is what to do if the pair of index if already altered. So if I try to assign index pair [1, 2] to [0, 1], but then [0,1] is already changed before. The solution I came up with is to use a HashMap, put the index pair in an array as key, and the original number as value.
Here is my code
public void rotate(int[][] matrix) {
int n = matrix.length;
HashMap<int[], Integer> map = new HashMap<>();
for(int i = 0; i < n; i++){
for (int j = 0; j < n; j++){
if(map.containsKey(new int[]{n-j,i})){
matrix[i][j] = map.get(new int[]{n-j, i});
}
else{
int temp = matrix[i][j];
matrix[i][j] = matrix[n-j][i];
map.put(new int[]{n-j,i}, temp);
}
}
}
}
However, the result shows that
if(map.containsKey(new int[]{n-j,i})){
matrix[i][j] = map.get(new int[]{n-j, i});
}
this line of code isn't searching for the array I put in before. I know that I am creating a new array every time, but how does it make containsKey not know if the array contains same numbers(the same array)? Can anyone help me understand why using an array here to mark the pair of index isn't working in a HashMap?
You don't need a Map to rotate a matrix. You only need one temp variable.
To rotate a 3x3:
1 2 3
4 5 6
7 8 9
temp = 1, copy corner values around, then save value to next corner:
1 2 3 7 2 3 7 2 3 7 2 3 7 2 1
4 5 6 → 4 5 6 → 4 5 6 → 4 5 6 → 4 5 6
7 8 9 7 8 9 9 8 9 9 8 3 9 8 3
repeat for border values, temp = 2:
7 2 1 7 4 1 7 4 1 7 4 1 7 4 1
4 5 6 → 4 5 6 → 8 5 6 → 8 5 6 → 8 5 2
9 8 3 9 8 3 9 8 3 9 6 3 9 6 3
And you're done, in-place rotation with only 1 value in temp storage, i.e. O(1) memory footprint.
Now I'll let you actually code that, for any size matrix.
UPDATE
For the fun of it, I decided to try writing it, so here it is, with test code. I'm not going to explain the logic though, that's for you to figure out yourself.
public static void main(String... args) {
for (int size : new int[] {2,3,4,5,10}) {
int[][] matrix = createMatrix(size);
printMatrix(matrix);
System.out.println();
rotateMatrix(matrix);
printMatrix(matrix);
printSeparatorLine(matrix);
}
}
private static int[][] createMatrix(int size) {
int[][] matrix = new int[size][size];
for (int y = 0, i = 0; y < size; y++)
for (int x = 0; x < size; x++)
matrix[y][x] = ++i;
return matrix;
}
private static void rotateMatrix(int[][] matrix) {
for (int y1 = 0; y1 < matrix.length / 2; y1++) {
for (int y2 = matrix.length - y1 - 1, x1 = y1; x1 < y2; x1++) {
int x2 = matrix.length - x1 - 1, temp = matrix[y1][x1];
matrix[y1][x1] = matrix[x2][y1];
matrix[x2][y1] = matrix[y2][x2];
matrix[y2][x2] = matrix[x1][y2];
matrix[x1][y2] = temp;
}
}
}
private static void printMatrix(int[][] matrix) {
int w = maxValueWidth(matrix);
for (int[] row : matrix) {
for (int i = 0; i < row.length; i++)
System.out.printf("%" + (w + (i == 0 ? 0 : 1)) + "d", row[i]);
System.out.println();
}
}
private static void printSeparatorLine(int[][] matrix) {
char[] buf = new char[(maxValueWidth(matrix) + 1) * matrix.length - 1];
Arrays.fill(buf, '-');
System.out.println(new String(buf));
}
private static int maxValueWidth(int[][] matrix) {
return Arrays.stream(matrix).flatMapToInt(Arrays::stream).map(i -> String.valueOf(i).length()).max().getAsInt();
}
Output
1 2
3 4
3 1
4 2
---
1 2 3
4 5 6
7 8 9
7 4 1
8 5 2
9 6 3
-----
1 2 3 4
5 6 7 8
9 10 11 12
13 14 15 16
13 9 5 1
14 10 6 2
15 11 7 3
16 12 8 4
-----------
1 2 3 4 5
6 7 8 9 10
11 12 13 14 15
16 17 18 19 20
21 22 23 24 25
21 16 11 6 1
22 17 12 7 2
23 18 13 8 3
24 19 14 9 4
25 20 15 10 5
--------------
1 2 3 4 5 6 7 8 9 10
11 12 13 14 15 16 17 18 19 20
21 22 23 24 25 26 27 28 29 30
31 32 33 34 35 36 37 38 39 40
41 42 43 44 45 46 47 48 49 50
51 52 53 54 55 56 57 58 59 60
61 62 63 64 65 66 67 68 69 70
71 72 73 74 75 76 77 78 79 80
81 82 83 84 85 86 87 88 89 90
91 92 93 94 95 96 97 98 99 100
91 81 71 61 51 41 31 21 11 1
92 82 72 62 52 42 32 22 12 2
93 83 73 63 53 43 33 23 13 3
94 84 74 64 54 44 34 24 14 4
95 85 75 65 55 45 35 25 15 5
96 86 76 66 56 46 36 26 16 6
97 87 77 67 57 47 37 27 17 7
98 88 78 68 58 48 38 28 18 8
99 89 79 69 59 49 39 29 19 9
100 90 80 70 60 50 40 30 20 10
---------------------------------------
You said "this line of code isn't searching for the array I put in before". But you also acknowledge that you were creating a new object each time. That won't work:
Since arrays extend Object, but don't override hashCode() or equals(), you get the default implementations defined by Object. These require that the array is actually the exact same one as is being compared to - so it can't just be 'equivalent'. That is, another array of the same type, with the same elements in the same order, won't work.
Source: https://coderanch.com/t/399422/java/array-HashMap-Key
Instead, you should use a Pair object to store your coordinates. You can write your own implementation or use a pre-existing one, such as javafx.util.Pair
This question already has answers here:
Java output formatting for Strings
(6 answers)
Closed 5 years ago.
I am trying to print out the multiplication tables up to 10. I have the logic down, but I am not sure how to make it all aligned with nice columns.
Here is what I printing at the moment:
1 2 3 4 5 6 7 8 9 10
2 4 6 8 10 12 14 16 18 20
3 6 9 12 15 18 21 24 27 30
4 8 12 16 20 24 28 32 36 40
5 10 15 20 25 30 35 40 45 50
6 12 18 24 30 36 42 48 54 60
7 14 21 28 35 42 49 56 63 70
8 16 24 32 40 48 56 64 72 80
9 18 27 36 45 54 63 72 81 90
10 20 30 40 50 60 70 80 90 100
I would like this:
1 2 3 4 5 6 7 8 9 10
2 4 6 8 10 12 14 16 18 20
3 6 9 12 15 18 21 24 27 30
4 8 12 16 20 24 28 32 36 40
5 10 15 20 25 30 35 40 45 50
6 12 18 24 30 36 42 48 54 60
7 14 21 28 35 42 49 56 63 70
8 16 24 32 40 48 56 64 72 80
9 18 27 36 45 54 63 72 81 90
10 20 30 40 50 60 70 80 90 100
Here is my current code:
public static void main(String[] args) {
multiplicationTables(10);
}
public static void multiplicationTables(int max) {
for(int x = 1; x <= max; x++) {
for (int y = 1; y <= max; y++) {
System.out.print(x*y + " ");
}
System.out.println();
}
}
Thanks for helping me.
You can use format to pad left each number with spaces:
public static void main(String[] args) {
multiplicationTables(10);
}
public static void multiplicationTables(int max) {
for(int x = 1; x <= max; x++) {
for(int y = 1; y <= max; y++) {
System.out.print(String.format("%4d", x * y));
}
System.out.println();
}
}
Output:
1 2 3 4 5 6 7 8 9 10
2 4 6 8 10 12 14 16 18 20
3 6 9 12 15 18 21 24 27 30
4 8 12 16 20 24 28 32 36 40
5 10 15 20 25 30 35 40 45 50
6 12 18 24 30 36 42 48 54 60
7 14 21 28 35 42 49 56 63 70
8 16 24 32 40 48 56 64 72 80
9 18 27 36 45 54 63 72 81 90
10 20 30 40 50 60 70 80 90 100
My assignment is to create a card deck shuffling program, but I am having an issue with the algorithm I have made to shuffle it. The idea is to take a card at random from the deck (values[]) and place it into the new shuffled deck (shuffled[]). However my program is spitting out shuffles that have too many zeroes in it. The original array contains int values 0-51. The first zero also always stays in the first slot for some reason. Here's my code:
public static void selectionShuffle(int[] values) {
int[] shuffled = new int[52];
for (int k = 51; k > 0;) {
int r = (int)(Math.random() * (double)51);
if (values[r] != -1) {
shuffled[k] = values[r];
values[r] = -1;
k--;
}
}
for (int i = 0; i < values.length; i++) {
values[i] = shuffled[i];
}
}
Results of 8 consecutive random selection shuffles
1: 0 22 40 43 6 14 31 4 47 1 36 41 0 3 24 12 5 39 27 23 11 28 50 38 7 18 16 32 17 20 21 2 8 13 15 46 19 26 9 48 25 34 45 42 10 33 29 49 30 44 37 35
2: 0 17 34 2 26 12 4 13 38 27 20 29 40 28 47 0 48 9 6 43 46 33 23 1 19 3 49 41 7 39 30 8 25 32 10 24 0 16 45 36 14 37 42 11 44 15 50 21 31 18 22 5
3: 0 23 2 44 20 38 45 46 47 27 50 7 26 28 0 21 24 37 11 19 40 10 1 29 36 14 30 12 25 22 16 6 39 0 0 8 18 33 9 48 42 43 34 13 32 17 41 15 49 4 3 31
4: 0 32 49 0 13 41 25 46 18 2 28 23 7 40 0 47 0 29 45 22 21 27 8 30 1 19 4 26 37 14 44 20 15 39 50 12 10 11 36 34 42 0 24 6 3 17 33 16 48 38 9 43
5: 0 29 26 13 1 15 0 20 47 9 17 21 30 34 28 0 22 18 0 3 6 2 0 38 12 48 23 27 11 16 42 32 39 40 33 0 37 44 50 41 46 49 8 24 10 7 14 25 19 45 36 4
6: 0 7 32 26 36 33 28 27 15 39 47 30 45 23 0 0 42 50 17 40 22 48 0 20 37 14 21 49 10 19 9 18 2 16 0 3 8 24 41 1 0 38 13 0 29 44 12 46 11 25 34 6
7: 0 9 0 21 29 18 48 33 45 20 15 24 44 46 47 0 36 2 39 28 0 12 0 50 19 42 32 27 8 38 37 23 0 11 25 13 10 3 0 34 26 40 17 0 41 7 30 14 1 22 16 49
8: 0 46 41 20 8 38 9 36 40 3 14 26 33 44 10 47 24 27 29 16 28 32 0 18 39 48 0 34 12 0 30 17 0 23 15 22 13 0 25 7 45 0 37 11 21 42 50 19 2 0 0 1
I think the issue is in the below line of code. If you don't initialize all values of the array greater than or equal to 0, it will not change the value. Since the default int value is 0, that is what is coming across.
for (int k = 51; k > 0;) {
should be
for (int k = 51; k >= 0;) {
Fill a deck with 52 cards
Parse the deck 51 times, grabbing the card at rand() * (numOfCardsRemainingInDeck)
Shift all cards from 'plucked' position to endOfArray one position 'to the left'.
After 51 iterations, the last card remaining is stuck into the last position of your result deck.
The problem is that your algorithm takes 51 cards out of 52, leaving shuffled[0] at 0. You can see that that is what's happening by looking at the results of the shuffles: position zero is always set to zero, while the remaining positions are set to random values.
One of the cards remains unshuffled from the first iteration; zero takes its place.
The next iteration can shuffle that zero, too, so now you have three zeros. The next iteration may add yet another zero, and so on.
To fix this issue, make sure that the loop goes all the way to zero, i.e.
for (int k = 51; k >= 0;) {
// ^
You also need to multiply random by 52, because otherwise you would never hit the last element of the array:
int r = (int)(Math.random() * (double)52);
You could also make a new random number generator, and call nextInt(52) on it.
Note that hitting that last element may take a while. An alternative solution would be to run the loop 51 times, and then put the last remaining value that has not been reset to -1 into position zero.
I would suggest using a List for this action, instead of an array.
If you use a list<cards>, then you could use Collections.shuffle
Randomly permute the specified list using the specified source of randomness. All permutations occur with equal likelihood assuming that the source of randomness is fair.
This implementation traverses the list backwards, from the last element up to the second, repeatedly swapping a randomly selected element into the "current position". Elements are randomly selected from the portion of the list that runs from the first element to the current position, inclusive.
This method runs in linear time. If the specified list does not implement the RandomAccess interface and is large, this implementation dumps the specified list into an array before shuffling it, and dumps the shuffled array back into the list. This avoids the quadratic behavior that would result from shuffling a "sequential access" list in place.
public static void shuffle(List<?> list, Random rnd) {
int size = list.size();
if (size < SHUFFLE_THRESHOLD || list instanceof RandomAccess) {
for (int i=size; i>1; i--)
swap(list, i-1, rnd.nextInt(i));
} else {
Object arr[] = list.toArray();
// Shuffle array
for (int i=size; i>1; i--)
swap(arr, i-1, rnd.nextInt(i));
// Dump array back into list
ListIterator it = list.listIterator();
for (int i=0; i<arr.length; i++) {
it.next();
it.set(arr[i]);
}
}
}
More info/Source
public class Card {
String name; // for simplicity, just the card's name
public Card(String name) {
this.name = name;
}
public String getName() {return name;}
}
// ...
List<Card> deck = new ArrayList<Card>();
initDeck(); // adds like 52 new cards to the deck
Collections.shuffle(deck); // shuffle the deck
Card drawn = deck.get(0); // draw the first card
deck.remove(drawn); // remove it from the deck
Found here