Java prints 00010 as 8 - java

having this issue with a decryption program I am writing in Java. Here is the code in question
public static int int_to_int(int input)
{
int[] value_array = {0, 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};
int[]bin_array= {00000, 00001, 00010, 00011,
00100, 00101, 00110, 00111,
01000, 01001, 01010, 01011, 01100,
01101, 01110, 01111, 10000, 10001,
10010, 10011, 10100, 10101, 10110,
10111, 11000,11001, 11010, 11011};
for(int i=0; i <27; i++)
{
System.out.println("hello");
if(input==value_array[i])
{
System.out.println("returning: " + bin_array[i] + "at: " + i);
return bin_array[i];
}
}
return -1;
}
And here is the issue highlighted in a line
double temp = 00010;
System.out.println("returning: " + temp);
This will output
returning: 8
but I want to see
returning: 00010
thoughts?

The 00010 is octal number, i.e., 8. Remove all the leading zeroes.

Integers prefixed with 0 are treated as octal, not binary. Prefix with 0b or 0B to indicate binary, like 0B00010. To print as binary, use
System.out.println("returning: " + Integer.toBinaryString(temp));
or,
System.out.println("returning: " + Integer.toString(temp, 2));
That is, assuming temp is an integer, like in your bin_array.

public static int int_to_int(int input)
{
int[] value_array = {0, 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};
int[]bin_array= {00000, 00001, 00010, 00011,
00100, 00101, 00110, 00111,
01000, 01001, 01010, 01011, 01100,
01101, 01110, 01111, 10000, 10001,
10010, 10011, 10100, 10101, 10110,
10111, 11000,11001, 11010, 11011};
for(int i=0; i <27; i++)
{
System.out.println("hello");
if(input==value_array[i])
{
System.out.println("returning: " + Integer.toOctalString(bin_array[i]) + "at: " + i);
return bin_array[i];
}
}
return -1;
}
I use Integer.toOctalString

Related

Random generator creates the same numbers

While looping through a for loop which is randomly 1-10 long. I also go through a while loop. I am trying to find 6 random numbers between 1-42. I then do that again (1-10) times. Currently, these 6 random numbers stay the same. I suspect it has something to do with the seed but I could not solve it.
I tried to use both SecureRandom, Random, and via Math.random()
Nothing has worked.
The model:
public static final int MAX_TIPS = 10;
public static final int MIN_TIPS = 1;
public static final int REQUIRED_NUMBERS = 6;
public static final int RANGE_NUMBER_MIN = 1;
public static final int RANGE_NUMBER_MAX = 42;
public static final int RANGE_LUCKY_NUMBER_MIN = 1;
public static final int RANGE_LUCKY_NUMBER_MAX = 6;
private Random random = new Random();
private int getRandomInt(int min, int max) {
return random.nextInt((max - min) + 1) + min;
}
public ArrayList<LottoTip> createOpponentTips() {
ArrayList<Integer> opponentChosenNumbers = new ArrayList<>();
ArrayList<LottoTip> lottoTips = new ArrayList<>();
//1-10
int amountOfTips = getRandomInt(MIN_TIPS, MAX_TIPS);
for (int i = 0; i < amountOfTips; i++) {
int[] arrayOpponentChosenNumbers = new int[REQUIRED_NUMBERS];
while (opponentChosenNumbers.size() < REQUIRED_NUMBERS) {
//1-42 This here is the problem zone
int randomNumber = getRandomInt(RANGE_NUMBER_MIN, RANGE_NUMBER_MAX);
if (!opponentChosenNumbers.contains(randomNumber)) {
opponentChosenNumbers.add(randomNumber);
}
}
//1-6 ---This here works
int opponentLuckyNumber = getRandomInt(RANGE_LUCKY_NUMBER_MIN, RANGE_LUCKY_NUMBER_MAX);
for (int j = 0; j < opponentChosenNumbers.size(); j++) {
arrayOpponentChosenNumbers[j] = opponentChosenNumbers.get(j);
}
lottoTips.add(new LottoTip(arrayOpponentChosenNumbers, opponentLuckyNumber));
}
return lottoTips;
}
LottoTip:
public class LottoTip {
private int[] numbers;
private int luckyNumber;
public LottoTip(int[] numbers, int luckyNumber) {
this.numbers = numbers;
this.luckyNumber = luckyNumber;
}
public String getNumbers() {
return numbers[0] + ", " + numbers[1] + ", " + numbers[2] + ", " + numbers[3] + ", " + numbers[4] + ", " + numbers[5];
}
public void setNumbers(int[] numbers) {
this.numbers = numbers;
}
public int[] getNumbersArray() {
return numbers;
}
public int getLuckyNumber() {
return luckyNumber;
}
public void setLuckyNumber(int luckyNumber) {
this.luckyNumber = luckyNumber;
}
#Override
public String toString() {
return "\nNumbers: " + getNumbers() + " Lucky Number: " + luckyNumber;
}
}
Here is a System.out.println as you can see the Numbers are staying the same. Could you help me find a way to create a getRandomInt method which works all the time?
Thank you very much for your help.
Kerry York [
Numbers: 6, 4, 30, 15, 25, 5 Lucky Number: 2,
Numbers: 6, 4, 30, 15, 25, 5 Lucky Number: 4,
Numbers: 6, 4, 30, 15, 25, 5 Lucky Number: 5,
Numbers: 6, 4, 30, 15, 25, 5 Lucky Number: 1,
Numbers: 6, 4, 30, 15, 25, 5 Lucky Number: 3,
Numbers: 6, 4, 30, 15, 25, 5 Lucky Number: 6]
Don Dickinson [
Numbers: 23, 29, 34, 18, 16, 19 Lucky Number: 6,
Numbers: 23, 29, 34, 18, 16, 19 Lucky Number: 5,
Numbers: 23, 29, 34, 18, 16, 19 Lucky Number: 3,
Numbers: 23, 29, 34, 18, 16, 19 Lucky Number: 2,
Numbers: 23, 29, 34, 18, 16, 19 Lucky Number: 4,
Numbers: 23, 29, 34, 18, 16, 19 Lucky Number: 1,
Numbers: 23, 29, 34, 18, 16, 19 Lucky Number: 1,
Numbers: 23, 29, 34, 18, 16, 19 Lucky Number: 4,
Numbers: 23, 29, 34, 18, 16, 19 Lucky Number: 3]
Clifford Weinstein [
Numbers: 6, 33, 13, 2, 37, 38 Lucky Number: 6,
Numbers: 6, 33, 13, 2, 37, 38 Lucky Number: 3,
Numbers: 6, 33, 13, 2, 37, 38 Lucky Number: 2,
Numbers: 6, 33, 13, 2, 37, 38 Lucky Number: 1,
Numbers: 6, 33, 13, 2, 37, 38 Lucky Number: 4,
Numbers: 6, 33, 13, 2, 37, 38 Lucky Number: 3,
Numbers: 6, 33, 13, 2, 37, 38 Lucky Number: 5,
Numbers: 6, 33, 13, 2, 37, 38 Lucky Number: 6,
Numbers: 6, 33, 13, 2, 37, 38 Lucky Number: 3,
Numbers: 6, 33, 13, 2, 37, 38 Lucky Number: 3]
Angela Spencer [
Numbers: 12, 39, 8, 25, 40, 15 Lucky Number: 6,
Numbers: 12, 39, 8, 25, 40, 15 Lucky Number: 3,
Numbers: 12, 39, 8, 25, 40, 15 Lucky Number: 2,
Numbers: 12, 39, 8, 25, 40, 15 Lucky Number: 4,
Numbers: 12, 39, 8, 25, 40, 15 Lucky Number: 5,
Numbers: 12, 39, 8, 25, 40, 15 Lucky Number: 4,
Numbers: 12, 39, 8, 25, 40, 15 Lucky Number: 2,
Numbers: 12, 39, 8, 25, 40, 15 Lucky Number: 2,
Numbers: 12, 39, 8, 25, 40, 15 Lucky Number: 3]
Leroy McIntosh [
Numbers: 5, 23, 2, 24, 28, 3 Lucky Number: 1]
You reuse the opponentChosenNumbers list between iterations of the outer for loop.
As such, on the second iteration, the while loop guard
while (opponentChosenNumbers.size() < REQUIRED_NUMBERS) {
is immediately false, so you don't pick new random numbers.
Move the declaration of opponentChosenNumbers into the for loop (or ensure it is empty before the while loop, e.g. by invoking opponentChosenNumbers.clear()).

Fixed Point Perlin Noise returns sum of input points as output

I have taken the fixed-point perlin-noise implementation from: http://mrl.nyu.edu/~perlin/noise/INoise.java and modified it slightly so it compiles under c#. In this version 1.0 is represented by 2^16.
When I pass in input coordinates (int x, int y, int z) the output is simply the sum of the x and z coordinates. What is wrong with my class or input points? Here is an example of the returned output:
for (int y = 0; y < 1; y++) {
for (int x = 0; x < 16; x++) {
for (int z = 0; z < 16; z++) {
Debug.Log(PerlinNoiseFixedPoint.Noise3D(x, y, z));
}
}
}
Output: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 1, 2, 3, 4, 5, 6,
7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
15, 16, 17, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 4, 5, 6, 7,
8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 5, 6, 7, 8, 9, 10, 11, 12, 13,
14, 15, 16, 17, 18, 19, 20, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
20, 21, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 8, 9, 10,
11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 9, 10, 11, 12, 13, 14, 15,
16, 17, 18, 19, 20, 21, 22, 23, 24, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
21, 22, 23, 24, 25, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
26, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 13, 14, 15,
16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 14, 15, 16, 17, 18, 19, 20,
21, 22, 23, 24, 25, 26, 27, 28, 29, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
26, 27, 28, 29, 30
public class PerlinNoiseFixedPoint {
public static int Noise3D(int x, int y, int z) {
int X = x >> 16 & 255, Y = y >> 16 & 255, Z = z >> 16 & 255, N = 1 << 16;
x &= N - 1; y &= N - 1; z &= N - 1;
int u = Fade(x), v = Fade(y), w = Fade(z), A = p[X] + Y, AA = p[A] + Z, AB = p[A + 1] + Z,
B = p[X + 1] + Y, BA = p[B] + Z, BB = p[B + 1] + Z;
return Lerp(w, Lerp(v, Lerp(u, Grad(p[AA ], x , y , z ),
Grad(p[BA ], x-N , y , z )),
Lerp(u, Grad(p[AB ], x , y-N , z ),
Grad(p[BB ], x-N , y-N , z ))),
Lerp(v, Lerp(u, Grad(p[AA+1], x , y , z-N ),
Grad(p[BA+1], x-N , y , z-N )),
Lerp(u, Grad(p[AB+1], x , y-N , z-N ),
Grad(p[BB+1], x-N , y-N , z-N ))));
}
static int Lerp(int t, int a, int b) {
return a + (t * (b - a) >> 12);
}
static int Grad(int hash, int x, int y, int z) {
int h = hash & 15, u = h < 8 ? x : y, v = h < 4 ? y : h == 12 || h == 14 ? x : z;
return ((h & 1) == 0 ? u : -u) + ((h & 2) == 0 ? v : -v);
}
static int Fade(int t) {
int t0 = f[t >> 8], t1 = f[Math.Min(255, (t >> 8) + 1)];
return t0 + ( (t & 255) * (t1 - t0) >> 8 );
}
static int[] p = new int[512] {
151,160,137,91,90,15,
131,13,201,95,96,53,194,233,7,225,140,36,103,30,69,142,8,99,37,240,21,10,23,
190, 6,148,247,120,234,75,0,26,197,62,94,252,219,203,117,35,11,32,57,177,33,
88,237,149,56,87,174,20,125,136,171,168, 68,175,74,165,71,134,139,48,27,166,
77,146,158,231,83,111,229,122,60,211,133,230,220,105,92,41,55,46,245,40,244,
102,143,54, 65,25,63,161, 1,216,80,73,209,76,132,187,208, 89,18,169,200,196,
135,130,116,188,159,86,164,100,109,198,173,186, 3,64,52,217,226,250,124,123,
5,202,38,147,118,126,255,82,85,212,207,206,59,227,47,16,58,17,182,189,28,42,
223,183,170,213,119,248,152, 2,44,154,163, 70,221,153,101,155,167, 43,172,9,
129,22,39,253, 19,98,108,110,79,113,224,232,178,185, 112,104,218,246,97,228,
251,34,242,193,238,210,144,12,191,179,162,241, 81,51,145,235,249,14,239,107,
49,192,214, 31,181,199,106,157,184, 84,204,176,115,121,50,45,127, 4,150,254,
138,236,205,93,222,114,67,29,24,72,243,141,128,195,78,66,215,61,156,180,
151,160,137,91,90,15,
131,13,201,95,96,53,194,233,7,225,140,36,103,30,69,142,8,99,37,240,21,10,23,
190, 6,148,247,120,234,75,0,26,197,62,94,252,219,203,117,35,11,32,57,177,33,
88,237,149,56,87,174,20,125,136,171,168, 68,175,74,165,71,134,139,48,27,166,
77,146,158,231,83,111,229,122,60,211,133,230,220,105,92,41,55,46,245,40,244,
102,143,54, 65,25,63,161, 1,216,80,73,209,76,132,187,208, 89,18,169,200,196,
135,130,116,188,159,86,164,100,109,198,173,186, 3,64,52,217,226,250,124,123,
5,202,38,147,118,126,255,82,85,212,207,206,59,227,47,16,58,17,182,189,28,42,
223,183,170,213,119,248,152, 2,44,154,163, 70,221,153,101,155,167, 43,172,9,
129,22,39,253, 19,98,108,110,79,113,224,232,178,185, 112,104,218,246,97,228,
251,34,242,193,238,210,144,12,191,179,162,241, 81,51,145,235,249,14,239,107,
49,192,214, 31,181,199,106,157,184, 84,204,176,115,121,50,45,127, 4,150,254,
138,236,205,93,222,114,67,29,24,72,243,141,128,195,78,66,215,61,156,180,
};
static int[] f = new int[256] {
0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 2, 3, 3, 4, 6, 7,
9, 10, 12, 14, 17, 19, 22, 25, 29, 32, 36, 40, 45, 49, 54, 60,
65, 71, 77, 84, 91, 98, 105, 113, 121, 130, 139, 148, 158, 167, 178, 188,
199, 211, 222, 234, 247, 259, 273, 286, 300, 314, 329, 344, 359, 374, 390, 407,
424, 441, 458, 476, 494, 512, 531, 550, 570, 589, 609, 630, 651, 672, 693, 715,
737, 759, 782, 805, 828, 851, 875, 899, 923, 948, 973, 998, 1023, 1049, 1074, 1100,
1127, 1153, 1180, 1207, 1234, 1261, 1289, 1316, 1344, 1372, 1400, 1429, 1457, 1486, 1515, 1543,
1572, 1602, 1631, 1660, 1690, 1719, 1749, 1778, 1808, 1838, 1868, 1898, 1928, 1958, 1988, 2018,
2048, 2077, 2107, 2137, 2167, 2197, 2227, 2257, 2287, 2317, 2346, 2376, 2405, 2435, 2464, 2493,
2523, 2552, 2580, 2609, 2638, 2666, 2695, 2723, 2751, 2779, 2806, 2834, 2861, 2888, 2915, 2942,
2968, 2995, 3021, 3046, 3072, 3097, 3122, 3147, 3172, 3196, 3220, 3244, 3267, 3290, 3313, 3336,
3358, 3380, 3402, 3423, 3444, 3465, 3486, 3506, 3525, 3545, 3564, 3583, 3601, 3619, 3637, 3654,
3672, 3688, 3705, 3721, 3736, 3751, 3766, 3781, 3795, 3809, 3822, 3836, 3848, 3861, 3873, 3884,
3896, 3907, 3917, 3928, 3937, 3947, 3956, 3965, 3974, 3982, 3990, 3997, 4004, 4011, 4018, 4024,
4030, 4035, 4041, 4046, 4050, 4055, 4059, 4063, 4066, 4070, 4073, 4076, 4078, 4081, 4083, 4085,
4086, 4088, 4089, 4091, 4092, 4092, 4093, 4094, 4094, 4095, 4095, 4095, 4095, 4095, 4095, 4095,
};
}
1.0 IS REPRESENTED BY 2^16
It was not very obvious but the result was intended.
Wrapping by function:
public static float Noise3D(float x, float y, float z)
{
//65536 = 2 ^ 16
return Noise3D((int)(x * 65536), (int)(y * 65536), (int)(z * 65536)) / 65536f;
}
Resulted in following noise:
P.S. Code, Just in case

QuickSort Program Not Outputting Right

I am attempting to make a QuickSort program and while I feel like it should be outputting as desired, it is not. I feel the problems lies in how I have constructed my loops but that may not be the case. As you can see, the first test with the runner prints out as I want and everything eventually gets sorted right. Any help would be greatly appreciated.
My main program:
import static java.lang.System.*;
import java.util.Arrays;
//use Arrays.toString() to help print out the array
public class QuickSort
{
private static int passCount;
public static void quickSort(Comparable[] list)
{
passCount=0;
quickSort(list, 0, list.length-1);
}
private static void quickSort(Comparable[] list, int low, int high)
{
if(low >= high)
return;
int a = partition(list, low, high);
quickSort(list, low, a-1);
quickSort(list, a+1, high);
}
private static int partition(Comparable[] list, int low, int high)
{
int x = low + 1;
int y = high;
while(x <= y)
{
if(list[x].compareTo(list[low]) <= 0)
{x++;}
else if(list[y].compareTo(list[low]) > 0)
{y--;}
else if(y < x)
{break;}
else
exchange(list, x, y);
}
exchange(list, low, y);
out.println("pass " + passCount++ + " " + Arrays.toString(list) + "\n");
return y;
}
private static void exchange(Object[] list, int x, int y) {
Object temporary = list[x];
list[x] = list[y];
list[y] = temporary;
}
}
My runner:
public class QuickSortRunner
{
public static void main(String args[])
{
QuickSort.quickSort(new Comparable[]{9,5,3,2});
System.out.println("\n");
QuickSort.quickSort(new Comparable[]{19,52,3,2,7,21});
System.out.println("\n");
QuickSort.quickSort(new Comparable[]{68,66,11,2,42,31});
System.out.println("\n");
}
}
My output:
pass 0 [2, 5, 3, 9]
pass 1 [2, 5, 3, 9]
pass 2 [2, 3, 5, 9]
pass 0 [2, 7, 3, 19, 52, 21]
pass 1 [2, 7, 3, 19, 52, 21]
pass 2 [2, 3, 7, 19, 52, 21]
pass 3 [2, 3, 7, 19, 21, 52]
pass 0 [31, 66, 11, 2, 42, 68]
pass 1 [11, 2, 31, 66, 42, 68]
pass 2 [2, 11, 31, 66, 42, 68]
pass 3 [2, 11, 31, 42, 66, 68]
Desired output:
pass 0 [2, 5, 3, 9]
pass 1 [2, 5, 3, 9]
pass 2 [2, 3, 5, 9]
pass 0 [7, 2, 3, 52, 19, 21]
pass 1 [3, 2, 7, 52, 19, 21]
pass 2 [2, 3, 7, 52, 19, 21]
pass 3 [2, 3, 7, 21, 19, 52]
pass 4 [2, 3, 7, 19, 21, 52]
pass 0 [31, 66, 11, 2, 42, 68]
pass 1 [2, 11, 66, 31, 42, 68]
pass 2 [2, 11, 66, 31, 42, 68]
pass 3 [2, 11, 42, 31, 66, 68]
pass 4 [2, 11, 31, 42, 66, 68]
The x++ and y-- to skip exchanges need to be in while loops so that exchange happens only when it is called for.

A abnormally working java loop,

This is a brute force attempt to solve the problem, but it is not giving the right answer. The program runs, but its not producing desired output. I believe the logic and program is correct.
This is problem of a famous site (don't want to a spoiler)
It asks for the number that produces the longest Collatz chain under one million.
class Euler
{
public static void main (String args[])
{
long len,longLength=0;
for(long i =3;i<=1000000;i++)
{
len = Euler14.numFucs(i);
System.out.println("Ans"+len+"\t"+i);
if(len>longLength)
longLength=len;
}
System.out.println(longLength);
}
public static long numFucs(long num)
{
long count=1,$test=0;
while(num>1)
{
if(num%2==0)
{
num=num/2;
}
else
{
num=3*num+1;
}
count++;
}
//System.out.println("\tEnd");
return count;
}
}
Well, I feel like it'd be cheating to give you the code for the right answer, as a fellow Project Euler fan. You're outputting the length of the longest chain, not the number that obtains it. If you really want, I can show you the one line that needs to change, but, honestly, this is a simple fix, and I challenge you to do it yourself.
If the program is suppose to compute the number of steps in the Collatz Conjecture the implementation looks fine to me.
The sequence of numbers in described by OEIS Sequence A008908.
Here's is your program together with some debug output.
class Test {
public static void main(String args[]) {
long len, longLength = 0;
System.out.println(Test.numFucs(13));
String[] correct = ("1, 1, 2, 8, 3, 6, 9, 17, 4, 20, 7, 15, 10, 10, 18,"
+ " 18, 5, 13, 21, 21, 8, 8, 16, 16, 11, 24, 11, 112, "
+ "19, 19, 19, 107, 6, 27, 14, 14, 22, 22, 22, 35, 9, "
+ "110, 9, 30, 17, 17, 17, 105, 12, 25, 25, 25, 12, "
+ "12, 113, 113, 20, 33, 20, 33, 20, 20, 108, 108, 7,"
+ " 28, 28, 28, 15, 15, 15, 103").split(", ");
for (int i = 0; i <= 70; i++) {
len = Test.numFucs(i);
System.out.printf("i = %2d, Correct %3s, Computed: %3d%n", i,
correct[i], len);
if (len > longLength)
longLength = len;
}
System.out.println(longLength);
}
public static long numFucs(long num) {
long count = 1;
while (num > 1) {
if (num % 2 == 0) {
num = num / 2;
} else {
num = 3 * num + 1;
}
count++;
}
// System.out.println(count);
return count;
}
}
Output:
i = 0, Correct 1, Computed: 1
i = 1, Correct 1, Computed: 1
i = 2, Correct 2, Computed: 2
i = 3, Correct 8, Computed: 8
i = 4, Correct 3, Computed: 3
i = 5, Correct 6, Computed: 6
i = 6, Correct 9, Computed: 9
i = 7, Correct 17, Computed: 17
i = 8, Correct 4, Computed: 4
i = 9, Correct 20, Computed: 20
i = 10, Correct 7, Computed: 7
i = 11, Correct 15, Computed: 15
i = 12, Correct 10, Computed: 10
i = 13, Correct 10, Computed: 10
i = 14, Correct 18, Computed: 18
i = 15, Correct 18, Computed: 18
i = 16, Correct 5, Computed: 5
...
As you can see it follows the OEIS sequence.
The error must be some where else.

How would I write a method that rearranges cards in a deck

I need to split a deck of cards into two packets: the top half and the bottom half. This new array of cards is suppose to go: first card from from the top packet, first card from bottom packet, second card from top packet, second card from bottom packet, etc. If there are an odd number of cards then the top packet should have one more than the bottom packet. The top of the deck is the front of the array.
How would I go about doing this?
Here is the method I created to generate the deck of cards (I think it works):
private Card[] cards;
int value, suit;
private final int DECK_SIZE = 52;
public Deck()
{
int index = 0;
cards = new Card[DECK_SIZE];
//0 = spades, 1 = hearts, 2 = clovers, 3 =diamonds
int suits[] = {0, 1, 2, 3};
//1 = Ace, 11=jack, 12=queen, 13=king
int values[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13};
for (int suit : suits)
for (int value : values)
{
cards[index] = new Card(value, suit);
index++;
}
}
Before you go about doing what you say, note that a perfect shuffle is not a good idea if you are looking to randomize the order of a deck:
A perfect faro shuffle, where the cards are perfectly alternated, is considered one of the most difficult sleights of card manipulation, because it requires the shuffler to cut the deck into two equal stacks and apply just the right pressure when pushing the half decks into each other. If one manages to perform eight perfect faro out-shuffles in a row, then the deck of 52 cards will be restored to its original order. If one can do perfect in-shuffles, then 26 shuffles will reverse the order of the deck and 26 more will restore it to its original order.
If you want a random shuffle, on the other hand, the way to go is a Fisher-Yates shuffle. From the wikipedia page:
To shuffle an array a of n elements (indexes 0..n-1):
for i from n − 1 downto 1 do
j ← random integer with 0 ≤ j ≤ i
exchange a[j] and a[i]
Note, however, that depending on your randomness criteria, the standard Java random number generator may not be sufficient: (also from the Wikipedia page:)
For example, the built-in pseudorandom number generator provided by many programming languages and/or libraries may often have only 32 bits of internal state, which means it can only produce 232 different sequences of numbers. If such a generator is used to shuffle a deck of 52 playing cards, it can only ever produce a very small fraction of the 52! ≈ 2225.6 possible permutations. It's impossible for a generator with less than 226 bits of internal state to produce all the possible permutations of a 52-card deck. It has been suggested[citation needed] that confidence that the shuffle is unbiased can only be attained with a generator with more than about 250 bits of state.
Mersenne Twister is a well-known random number generator that would be adequate.
edit: for a literal answer to your original question, here's how I would probably do it (including a test method):
import java.util.Arrays;
public class Shuffle {
/* assumes input and output arrays are same length (N) */
static public <T> void perfectShuffle(T[] input, T[] output, int N)
{
int itop = 0;
int ibottom = N - (N/2);
/* bottom has (N/2) elements; for odd N this is rounded down,
* and the top part has 1 more element */
int k = 0;
while (ibottom < N)
{
output[k++] = input[itop++];
output[k++] = input[ibottom++];
}
// handle last element for N = odd
if (k < N)
output[k] = input[itop];
}
public static void main(String[] args) {
int N = 19;
String[] in = new String[N];
String[] out = new String[N];
for (int i = 0; i < N; ++i)
in[i] = Integer.toString(i);
perfectShuffle(in, out, N);
System.out.println(Arrays.asList(out));
}
}
output of main():
[0, 10, 1, 11, 2, 12, 3, 13, 4, 14, 5, 15, 6, 16, 7, 17, 8, 18, 9]
finally, the reason why you shouldn't use this for shuffling cards:
public static void main(String[] args) {
int N = 52;
String[] in = new String[N];
String[] out = new String[N];
for (int i = 0; i < N; ++i)
in[i] = Integer.toString(i);
for (int k = 0; k < 8; ++k)
{
perfectShuffle(in, out, N);
System.out.println(Arrays.asList(out));
String[] tmp = in;
in = out;
out = tmp;
}
}
output:
[0, 26, 1, 27, 2, 28, 3, 29, 4, 30, 5, 31, 6, 32, 7, 33, 8, 34, 9, 35, 10, 36, 11, 37, 12, 38, 13, 39, 14, 40, 15, 41, 16, 42, 17, 43, 18, 44, 19, 45, 20, 46, 21, 47, 22, 48, 23, 49, 24, 50, 25, 51]
[0, 13, 26, 39, 1, 14, 27, 40, 2, 15, 28, 41, 3, 16, 29, 42, 4, 17, 30, 43, 5, 18, 31, 44, 6, 19, 32, 45, 7, 20, 33, 46, 8, 21, 34, 47, 9, 22, 35, 48, 10, 23, 36, 49, 11, 24, 37, 50, 12, 25, 38, 51]
[0, 32, 13, 45, 26, 7, 39, 20, 1, 33, 14, 46, 27, 8, 40, 21, 2, 34, 15, 47, 28, 9, 41, 22, 3, 35, 16, 48, 29, 10, 42, 23, 4, 36, 17, 49, 30, 11, 43, 24, 5, 37, 18, 50, 31, 12, 44, 25, 6, 38, 19, 51]
[0, 16, 32, 48, 13, 29, 45, 10, 26, 42, 7, 23, 39, 4, 20, 36, 1, 17, 33, 49, 14, 30, 46, 11, 27, 43, 8, 24, 40, 5, 21, 37, 2, 18, 34, 50, 15, 31, 47, 12, 28, 44, 9, 25, 41, 6, 22, 38, 3, 19, 35, 51]
[0, 8, 16, 24, 32, 40, 48, 5, 13, 21, 29, 37, 45, 2, 10, 18, 26, 34, 42, 50, 7, 15, 23, 31, 39, 47, 4, 12, 20, 28, 36, 44, 1, 9, 17, 25, 33, 41, 49, 6, 14, 22, 30, 38, 46, 3, 11, 19, 27, 35, 43, 51]
[0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48, 1, 5, 9, 13, 17, 21, 25, 29, 33, 37, 41, 45, 49, 2, 6, 10, 14, 18, 22, 26, 30, 34, 38, 42, 46, 50, 3, 7, 11, 15, 19, 23, 27, 31, 35, 39, 43, 47, 51]
[0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41, 43, 45, 47, 49, 51]
[0, 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]
If you're able to substitute a non-perfect shuffle, try Collections.shuffle(). Your code would look something like this:
List card_list = Arrays.asList(cards);
Collections.shuffle(card_list);
or as #Mark Peters points out, the more concise:
Collections.shuffle(Arrays.asList(cards));
I was looking for something similar (shuffling a JSONArray) in this question: An efficient way to shuffle a JSON array in java?
I ended up making my own shuffle method implementing this algorithm. For your example, it would be something like:
public Card[] shuffle(Card[] cards) {
// Implementing Fisher–Yates shuffle
Random rnd = new Random();
for (int i = cards.length() - 1; i >= 0; i--)
{
int j = rnd.nextInt(i + 1);
// Simple swap
Card card = cards[j];
cards[j] = cards[i];
cards[i] = card;
}
return cards;
}

Categories