Java: Shuffling Cards in a Deck using Arrays - java

I am trying to implement a Perfect Shuffle method where it will split a deck into 2 and then interweave the cards so you have one from each deck being placed into the new deck. When I try to run my current program, the output I would get is:
Results of 3 consecutive perfect shuffles:
1: 0 4 1 5 2 6 3
2: 0 2 4 6 1 3 5
3: 0 1 2 3 4 5 6
I do not understand why I get 0 as my first value for each time I shuffle the deck. Can anyone tell me what I am doing wrong? This is my code:
class Ideone {
/**
* The number of consecutive shuffle steps to be performed in each call
* to each sorting procedure.
*/
private static final int SHUFFLE_COUNT = 3;
/**
* The number of values to shuffle.
*/
private static final int VALUE_COUNT = 7;
/**
* Tests shuffling methods.
* #param args is not used.
*/
public static void main(String[] args) {
System.out.println("Results of " + SHUFFLE_COUNT +
" consecutive perfect shuffles:");
int[] values1 = new int[VALUE_COUNT];
for (int i = 0; i < values1.length; i++) {
values1[i] = i;
}
for (int j = 1; j <= SHUFFLE_COUNT; j++) {
perfectShuffle(values1);
System.out.print(" " + j + ":");
for (int k = 0; k < values1.length; k++) {
System.out.print(" " + values1[k]);
}
System.out.println();
}
System.out.println();
}
public static void perfectShuffle(int[] values) {
int[] temp = new int[values.length];
int halfway = (values.length +1)/2;
int position = 0;
for (int j = 0 ; j < halfway; j++)
{
temp[position] = values[j];
position +=2;
}
position = 1;
for (int k = halfway; k < values.length; k++)
{
temp[position] = values[k];
position +=2;
}
for (int k = 0; k < values.length; k++)
values[k] = temp[k];
}
}

array index begin at 0 and not 1.
for (int i = 0; i < values1.length; i++) {
values1[i] = i;
}
you are copying 0 in values1 in this for loop in your main method which you then pass to perfectShuffle

You fill the "deck" starting at 0 and then shuffle, but your shuffle always puts the "0" card first so it never really gets shuffled in. You can see the same thing with the #1 using:
for (int i = 1; i < values1.length+1; i++) {
values1[i-1] = i;
}
Also, with an even number of cards, your last card will never change either.

Related

How to randomly fill in 10% 2 dimensional array with int = 1?

I have little problem , im starting learn java .
I need to create 2dimensional array , and i need fill this array in 10% only int 1 of course my code need fill this array randomly .
Need some hints how to fill in 10% .
public static void main(String[] args) {
int maxX = 10;
int maxY = 10;
int[][] Arr = new int[maxX][maxY];
Random r = new Random();
// random ints
for (int x = 0; x < maxX; x++) {
for (int y = 0; y < maxY; y++) {
Arr[x][y] = r.nextInt(2);
}
}
// printing Arr
for (int i = 0; i < Arr.length; i++) {
for (int j = 0; j < Arr[i].length; j++) {
System.out.print(Arr[i][j] + " ");
}
System.out.println();
}
}
Make the array, take a random row and column, while the percentage is not exceeded, check if the position has 0, if yes fill it with 1.
int[][] array = new int[N][N];
int percentage = N*N/10;
int filled = 0;
while(filled <= percentage)
{
Random rand = new Random();
int i = rand.nextInt(N+1);
int j = rand.nextInt(N+1);
if(array[i][j] == 0)
{
filled++;
array[i][j] = 1;
}
}
for(int i = 0; i < N; i++)
{
for(int j = 0; j < N; j++)
{
System.out.print(array[i][j] + " ");
}
System.out.println();
}
You can take the following steps:
Suppose you need to fill an N * N array.
Create a List and add to it (N * N) / 10 1s and (N * N * 9) / 10 0s. list.addAll(Collections.nCopies(count,1 or 0)) can help you here.
Run Collections.shuffle on that List to obtain random order.
Iterate over the elements of the List. The first N elements will become the first row the the 2D array, the next N elements will become the second row of the array, and so on...
An alternative to shuffling is to pick 10% x N random positions and put a 1 (if a 0 was in the position, otherwise pick another position). In pseudo code:
int[][] array = new int[N][N]
apply N * N / 10 times {
index = random(0 .. N * N)
if array(index) = 0 then array(index) = 1
else retry with another index
}
You will need to convert the index from 0 to N*N into a pair of i,j in the 2D array.
I would use "double random = Math.random();"
And then an if to check if the variable random is less or equal to 0.1

2 arrays to randomly display 1-10 and random 1-10 without function

The goal of this program is to have A2[] display the numbers 1-10 in a random order.It needs to be done without anything past base level knowledge. A2[] gets the numbers from A1[], the A1[] array has the numbers 1-10 stored in sequence. In its current state the program runs, but does not filter out results that have already been store in A2[]. For example.... 4,2,3,7,5,9,7,1,4 should not be able to be a result. Only a random order of 1-10 should display, with each int occurring only once. Any help is greatly appreciated. The code presently is as follows : `
public class W07problem07 {
public static int getRandomIntRange(int min, int max) {
int x = (int) (Math.random() * ((max - min))) + min;
return x;
}
public static void main(String[] args) {
int ranNum;
int count = 1;
int[] A1 = new int[10];
int[] A2 = new int[10];
//loop for storing 1-10 int number withing A1[].
for (int k = 0; k < A1.length; k++) {
A1[k] = count;
count++;
}
for (int k = 0; k < A2.length; k++) {
A2[k] = k;
}
for (int j = 0; j < A2.length; j++) {
int a;
ranNum = getRandomIntRange(0, A2.length);
a = A2[j];
if(a==ranNum){
j--;
} else{
A2[j]= A1[ranNum];
}
}
for (int k = 0; k < A2.length; k++) {
System.out.println(A2[k]);
}
}
}
`
There are really many ways to do what you are asking.
One of the simplest is appling the hash theory, using the next uncalled number as next (pseudo)random number.
I'm assuming that what you wrote in your code doesn't make much sense, so to follow what's next, i'm assuming A1 is populated with numbers 1-10 and you are populating A2 directly with shuffled numbers.
Example:
this is the current state of your A2. The next random number picked is 1, but that is not good as long it was already picked.
A1 |1 2 3 4 5 6 7 8 9 10|
A2 |1 4 7 9 . . . . . . |
So when a "collision" is found continue to apply this fix:
the new random number become x = x+1 until an unpicked number is taken.
So
A1 |1 2 3 4 5 6 7 8 9 10|
A2 |1 4 7 9 2 . . . . . |
As you can imagine there are a lot of collision policy that you can use, the previous one is called open addressing.
One more solution
public class W07problem07 {
public static int getRandomIntRange(int min, int max) {
int x = (int) (Math.random() * ((max - min))) + min;
return x;
}
public static void main(String[] args) {
int count = 1;
int[] A1 = new int[10];
int[] A2 = new int[10];
//loop for storing 1-10 int number withing A1[].
for (int k = 0; k < A1.length; k++) {
A1[k] = count;
count++;
}
int j = 0;
while (j < A1.length) {
int ranNum = getRandomIntRange(1, A1.length + 1);
if (!numAlreadyExists(A2, ranNum)) {
A2[j++] = ranNum;
}
}
for (int k = 0; k < A2.length; k++) {
System.out.println(A2[k]);
}
}
public static boolean numAlreadyExists(int[] array, int element) {
for (int i = 0; i < array.length; i++) {
if (element == array[i]) {
return true;
}
}
return false;
}
}

Transpose java error

I was trying to do a 2D array program to demonstrate a TRANSPOSE but I am getting error .. here is my code.
import java.util.Scanner;
/* To demonstrate TRANSPOSE USING 2-D array */
public class Array_2ddd {
public static void main(String args[]) {
Scanner s1 = new Scanner(System.in);
int i, j;
int myArray1[][] = new int[9][9];
int myArray2[][] = new int[9][9];
for (i = 0; i < 9; i++) {
for (j = 0; j < 9; j++) {
System.out.println("Enter array from 1 to 9");
myArray1[i][j] = s1.nextInt();
System.out.print("your array is" + myArray2[i][j]);
}
}
// Transposing now...
for (i = 0; i < 9; i++) {
for (j = 0; j < 9; j++) {
myArray2[i][j] = myArray1[j][i];
}
}
// After transposing
for (i = 0; i < 9; i++) {
for (j = 0; j < 9; j++) {
System.out.print("Your array is as follow" + myArray2[i][j]);
}
}
}
}
EDIT: My error during runtime (Solved)
EDIT 2: Solved
EDIT 3: The loop is in infinity ..it keeps on asking for values fromt the user even when i wrote i<9 and j<9..it still keeps on asking for values till infinity..
There are several errors in your code, also it is recommend that the dimensions of the array is to be declared as a final int, so your code works for all matrix sizes and that debugging is easier. In your original code, the errors are:
At the input step, you are printing one element of myArray[2] before you perform the transpose. That means, you are getting your array is0.
In the section commented "After transposing", you are outputting your array wrong. Namely, for each entry, you call System.out.print("Your array is as follow" + myArray2[i][j]);, and that you forgot to add a new line after each row (when inner loop is finished).
"..it keeps on asking for values fromt the user even when i wrote i<9 and j<9..it still keeps on asking for values till infinity.." There are 81 entries for the 9-by-9 case and you did not output which i,j index to be applied. You probably mistaken an infinite loop with a long but terminating loop.
Your transpose step is good.
Here is a refined version of your code which allows you to input array (in reading order, or more technically, row-major order), create a transposed array. You can copy and compare your current code with this code directly to test it.
public static void main(String args[]) {
final int m = 9; // Rows
final int n = 9; // Columns
Scanner s1 = new Scanner(System.in);
int i, j;
int myArray1[][] = new int[m][n]; // Original array, m rows n cols
int myArray2[][] = new int[n][m]; // Transposed array, n rows m cols
// Input
for (i = 0; i < m; i++) {
for (j = 0; j < n; j++) {
// Should be only prompt.
// Improved to show which entry will be affected.
System.out.printf("[%d][%d]" + "Enter array from 1 to 9\n", i, j);
myArray1[i][j] = s1.nextInt();
}
}
// Transposing now (watch for the ordering of m, n in loops)...
for (i = 0; i < n; i++)
{
for (j = 0; j < m; j++)
{
myArray2[i][j] = myArray1[j][i];
}
}
// After transposing, output
System.out.print("Your array is:\n");
for (i = 0; i < m; i++) {
for (j = 0; j < n; j++) {
System.out.print(myArray1[i][j] + " ");
}
System.out.println(); // New line after row is finished
}
System.out.print("Your transposed array is:\n");
for (i = 0; i < n; i++) {
for (j = 0; j < m; j++) {
System.out.print(myArray2[i][j] + " ");
}
System.out.println();
}
s1.close();
}
For an array with three rows (m = 3) and four columns (n = 4), I inputted the numbers from 0 to 9, and then 0, 1, 2. As expected, the output should be:
Your array is:
0 1 2 3
4 5 6 7
8 9 0 1
Your transposed array is:
0 4 8
1 5 9
2 6 0
3 7 1
You define your matrix as 9x9
int myArray1[][] = new int[9][9];
But actually you want to insert 10x10 items:
for (i = 0; i <= 9; i++)
{
for (j = 0; j <= 9; j++)
So either:
Redefine your arrays to store 10x10 items
int myArray1[][] = new int[10][10];
Only read and store 9x9 items in your defined array
for (i = 0; i < 9; i++) {
for (j = 0; j < 9; j++)
You haven't close your first outer for loop i.e in line 17 and change your array size to 10,as you wanted take 10 input (for 0 to 9 = 10 values).

Create a reverse order array from given array

I have an assignment to create a class in which I create an array of size 10, called source, and assign random integers in the range 0-10 to all indexes in it, and then call a method that creates a new array in reverse order. I tried the code below:
public class Exercise7_4 {
// reverse array method
public static int[] reverseArray(int[] arr) {
int[] reverse = new int[arr.length];
for (int i = 0; i < reverse.length - 1; i++) {
reverse[i] = arr[arr.length - 1 - i];
}
return reverse;
}
// print array in ascending order
public static void printArray(int[] arr) {
for (int i = 0; i < arr.length - 1; i++) {
System.out.printf("%d\t", arr[i]);
}
System.out.println();
}
public static void main(String[] args) {
int[] source = new int[10];
for (int i = 0; i < source.length - 1; i++) {
source[i] = (int) (Math.random() * 10 + 1);
}
int[] reverse = reverseArray(source);
printArray(source);
printArray(reverse);
}
}
The problem is that the output i get looks like this:
7 1 3 7 10 9 6 2 6
0 6 2 6 9 10 7 3 1
meaning, the reverseArray method doesn't work properly on reverse[0] for some reason.
I would like to know why this is happening and how I can fix it.
Thanks in Advance!
change all your for-loops from
for (int i = 0; i < source.length - 1; i++)
to
for (int i = 0; i < source.length; i++)
Your reverse method is completely correct (if you change the loop). The mistake you made is that you created an array of size 10, filled it with 9 random values (the value of index 10 will therefore be 0).
You could check wich index are consulted in each iteration of your for loop.
This is your solution
for (int i = 0; i < reverse.length - 1; i++) {
System.out.println("" + i + " " + (reverse.length - 1 - i));
}
And it prints:
0 9
1 8
2 7
3 6
4 5
5 4
6 3
7 2
8 1
The 'i' don't get the value 9, and the (reverse.length - 1 - i) don't get the value 0.
Changing the testing condition for this:
i < reverse.length
gives you the last position:
9 0
Change reverseArray function as follows:
public static int[] reverseArray(int[] arr) {
int[] reverse = new int[arr.length];
for (int i = 0; i < reverse.length; i++) {
reverse[i] = arr[arr.length - i];
}
return reverse;
}
You need not to -1 from arr.length.
Change another for loop also:
for (int i = 0; i < source.length; i++) {
source[i] = (int) (Math.random() * 10 + 1);
}
Here, also you do not need to do -1 from source.length.
package com.test;
public class SortArray {
private int[] getSortedArry(int[] arr){
int arrLen = arr.length;
int reversedArry[] = new int[arrLen];
System.out.println("array lenght: " +arr.length);
int j = 0;
for(int i=arrLen-1; i>=0; i--){
reversedArry[j] = arr[i];
j++;
}
System.out.print("\n");
return reversedArry;
}
public static void main(String[] args){
int arr[] = {10,2,3,4,5,12,23,43,45,65};
SortArray sortArray = new SortArray();
int reversedArry[] = sortArray.getSortedArry(arr);
for(int i=0;i<reversedArry.length;i++){
System.out.print(reversedArry[i] + " ");
}
}
}

Mirrored Triangle generation in java

I happened to appear for a test and got the following as question. I am unable to figure out how to proceed. The scenario is to write a java program that prints the following with respective N. If suppose N=3, it must have 2*N rows and output must be,
1
2*3
4*5*6
4*5*6
2*3
1
Output must consist only numbers and asterisk. N varies between 0 to 100. Also, given
public static void main(String[] args){
int rows=2;
mirrorTriangle(rows);
}
public void mirrorTriangle(int n){
//Logic
}
I don't understand why is that rows declared as 2 if rows are supposed to be varying with N. Please explain the logic.
Please find the solution to your problem, with explanation comments.
public static void main(String[] args) throws Exception
{
// initialize n
int n = 4;
// initialize x to 1 from where our printing will start.
int x = 1;
/* We will store our generated numbers in an array.
* For example, the array after we generate
* the numbers would look like:
* [1,0,0,
2,3,0,
4,5,6,
4,5,6,
2,3,0,
1,0,0]
*
* When n = 3, there are going to be 3*2 i.e, n*2 rows.
* in our case 6 rows.
* visualize with the above values.
* The first n/2 rows will be the numbers we print,
* the next n/2 will be the mirror image of the first n/2 rows.
* no. of columns in each row will be equal to n, in our example:3
*/
int arr[][] = new int[n*2][n];
/*
* Start populating the matrix
* Each row will contain number of elements eaual to the row number,
* so 1st row -> 1 element, 2nd - > 2,.. and so on.
*/
for(int row=0;row<n;row++)
{
int col = 0;
while(col < row+1)
{
arr[row][col] = arr[n*2-row-1][col] = x++;
col++;
}
}
/*
* Now our task is just to read out the array.
* The tricky part is adding the astricks.
* We notice that row1 will have 1-1 asticks, row2 -> 2-1 astricks ,.. and so on.
* So in between the numbers while reading out,
* for each row we maintain the number of astricks.
*/
for(int i=0;i<arr.length;i++)
{
StringBuilder build = new StringBuilder();
for(int j=0;j<arr[i].length;j++)
{
if(arr[i][j] > 0)
{
build.append((arr[i][j])).append("*");
}
}
System.out.print(build.delete(build.length()-1,build.length()).toString());
System.out.println();
}
}
o:p for n=4:
1
2*3
4*5*6
7*8*9*10
7*8*9*10
4*5*6
2*3
1
def N = 3
def i = 0
def j = 0
int[][] numbers = new int[N][]
// Generate, print, and store numbers
while( i < numbers.length ){
numbers[i] = new int[i+1]
j = 0
while( j < numbers[i].length ){
numbers[i][j] = j+1
++j
print j
}
println ""
i++
}
// Print them again, in reverse order
i = numbers.length - 1
while( i >= 0 ){
j = 0
while( j < numbers[i].length ){
print numbers[i][j]
j++
}
println ""
i--
}
Output:
1
12
123
123
12
1
The code is pretty self-explanatory. You need just N rows but print 2N because, wait for it ... symmetry. If you have 6 rows, first 3 are new while the other 3 are just mirrored images so why waste the memory space when you can just print them again?
Is there an explicit requirement for recursion? It is implied by the structure of the problem not mentioned anywhere.
int rows=2 is an example probably, for the purposes of the problem you can't do anything 'smart' like using pointers ...
I will also assume that you are not permitted to use values '> 100' so that you can overload the meaning of the n value - same goes for 2's complement.
If you allow for looping, as a substitute for recursion you can generate the triangle without having to save state outside of the stack:
public static void main(String[] args){
int rows=3;
mirrorTriangle(rows);
}
public static void mirrorTriangle(int n){
for (int i = 0 ; i < n + 1 ; i++) {
renderLine(i);
}
for (int i = n ; i > 0 ; i--) {
renderLine(i);
}
}
private static void renderLine(int n) {
int j = n * (n - 1) / 2 + 1;
int k = j + n;
while (j < k) {
System.out.print(j);
j++;
if (j < k) System.out.print('*');
}
System.out.println();
}
Try this fresh code:
public class String4 {
public static void main(String[] args) {
int rows = 3;
mirrorTriangle(rows);
}
private static void mirrorTriangle(int rows) {
for(int i=1;i<=rows;i++)
{
for(int j=1;j<=i;j++)
{
System.out.print(i);
if(j>0&&j<i)
System.out.print("*");
}
System.out.println();
}
for(int k=rows;k>0;k--)
{
for(int l=1;l<=k;l++)
{
System.out.print(k);
if(l>0&&l<k)
System.out.print("*");
}
System.out.println();
}
}
}
Output:
1
2*2
3*3*3
3*3*3
2*2
1
I think this is a better and simple solution than the chosen one.
public static void main(String[] args) {
Scanner s = new Scanner(System.in);
System.out.println("Enter limit");
int limit = s.nextInt();
int start[] = new int[limit];
int v = 1;
for (int i=1; i<=limit; i++) {
start[i-1] = v;
for (int j=1; j<=i; j++) {
System.out.print(v++);
if(j==i)
continue;
System.out.print("*");
}
System.out.print("\n");
}
for (int i=limit-1; i>=0; i--) {
v=start[i];
for (int j=i; j>=0; j--) {
System.out.print(v++);
if(j==0)
continue;
System.out.print("*");
}
System.out.print("\n");
}
}

Categories