2D array random index Lotto game - java

I'm trying to do a Lotto game where I have to generate a random card and in the first column numbers go from 1-9, second 10-19 all the way to 90. Another rule of the card is that it can only have 5 numbers at random positions in each line and that's what I'm having trouble with.
I've started with this to put numbers in each column:
int[][] numberCard = new int[3][9];
for (int i = 0; i < numberCard.length; i++) {
numberCard[i][0] = randInt(1, 9);
}
for (int j = 0; j < numberCard.length; j++) {
numberCard[j][1] = randInt(10, 19);
}
And then do put 5 numbers in a number position in each line of the array i tried this:
//Five numbers first line
Random random0 = new Random();
int randomLocation = 0;
while (randomLocation < 5) {
int z0 = random0.nextInt(numberCard.length);
int b0 = random0.nextInt(numberCard[0].length);
if (numberCard[z0][b0] > 0) {
numberCard[z0][b0] = 0;
randomLocation++;
}
}
//Five numbers second line
Random random1 = new Random();
int randomLocation1 = 0;
while (randomLocation1 < 5) {
int z1 = random1.nextInt(numberCard.length);
int b1 = random1.nextInt(numberCard[1].length);
if (numberCard[z1][b1] > 0) {
numberCard[z1][b1] = 0;
randomLocation1++;
}
}
And then the same for the third one.
Output:
0 | 18 | 0 | 0 | 46 | 0 | 61 | 72 | 88 |
0 | 18 | 0 | 31 | 0 | 55 | 0 | 0 | 0 |
0 | 0 | 23 | 34 | 45 | 0 | 0 | 0 | 80 |
The problem is that sometimes I get 5 numbers, sometimes 6 and sometimes 4 when sometimes i get the perfect 5 numbers in each line. More frustrating that not working is only working sometimes...
I thought and I think it is because of the random numbers that sometimes repeat themselves so they go to the same index, but then sometimes I have more than the 5 numbers so that makes no sense.
Correct output expected:
0 | 18 | 23 | 30 | 48 | 0 | 0 | 76 | 0 |
0 | 12 | 24 | 0 | 0 | 58 | 61 | 78 | 0 |
1 | 17 | 0 | 0 | 42 | 54 | 0 | 0 | 86 |

Here is the pretty much the same code as before. The cards have become the rows.
public static void lottery() {
System.out.println(" 1 2 3 4 5 6 7 8 9");
System.out.println("---------------------------");
for (int card = 1; card<= 5; card++) {
List<Integer> numbers = new ArrayList<>();
for (int i = 0; i <= 8; i++) {
int s = i > 0 ? 0 : 1;
numbers.add(ThreadLocalRandom.current().nextInt(i*10 + s,(i+1)*10));
}
Collections.shuffle(numbers);
int[] row = new int[9];
for (int s = 0; s < 5; s++) {
int pick = numbers.get(s);
row[pick/10] = pick;
}
for (int i = 0; i < 9; i++) {
System.out.printf("%3d", row[i]);
}
System.out.println();
}
}
Prints
1 2 3 4 5 6 7 8 9
---------------------------
5 0 0 0 47 0 67 71 81
1 0 22 0 0 55 65 0 88
1 11 0 30 0 58 0 76 0
0 10 24 0 43 0 0 75 88
3 16 0 0 0 0 60 71 81

I think your approach is complicated than it should be. I would recomend to do it like below:
For each row of your 2D-Array, generate a random number between [1 - 90) and put it to the spot where it belongs by dividing the random number with 10 (will give you values [0 - 8]) while checking that that position doesn't have a random value aready assigned. Reapet this 5 times.
public static void main(String[] args) {
int[][] numberCard = new int[3][9];
Random rand = new Random();
for (int i = 0; i < numberCard.length; i++) {
for (int j = 0; j < 5; j++) {
int x = rand.nextInt(89) + 1;
while (numberCard[i][x / 10] != 0) {
x = rand.nextInt(89) + 1;
}
numberCard[i][x / 10] = x;
}
}
//print or do whatever with your numberCard array
for (int[] row : numberCard) {
System.out.println(Arrays.toString(row));
}
}
Sample output:
[0, 0, 24, 0, 40, 55, 0, 71, 86]
[0, 16, 0, 0, 42, 56, 0, 70, 84]
[5, 12, 0, 0, 49, 0, 69, 0, 82]

You can do it like this:
The card consists of 3 rows.
Each row consists of 9 random cells: 5 filled and 4 hollow.
Column ranges: 1-9 first, 80-90 last, x0-x9 others.
No duplicate numbers in every column.
List<int[]> card = new ArrayList<>();
IntStream.range(0, 3)
// prepare a list of cell indices of the row
.mapToObj(row -> IntStream.range(0, 9)
.boxed().collect(Collectors.toList()))
// random order of cell indices
.peek(Collections::shuffle)
// list of 5 random cell indices in the row
.map(list -> list.subList(0, 5))
// fill the cells with random numbers
.map(list -> IntStream.range(0, 9)
// if this cell is in the list, then fill
// it with a random number, otherwise 0
.map(i -> {
int number = 0;
if (list.contains(i)) {
// unique numbers in each column
boolean isPresent;
do {
// [1-9] first, [80-90] last, [x0-x9] others
number = (int) ((i > 0 ? i * 10 : 1)
+ Math.random()
* (i < 8 ? (i > 0 ? 10 : 9) : 11));
isPresent = false;
for (int[] row : card)
if (row[i] == number)
isPresent = true;
} while (isPresent);
}
return number;
}).toArray())
// add this row to the card
.forEach(card::add);
// output
card.stream()
// row of numbers to string
.map(row -> Arrays.stream(row)
.mapToObj(j -> j == 0 ? " " : String.format("%2d", j))
// concatenate cells into one row
.collect(Collectors.joining(" | ", "| ", " |")))
.forEach(System.out::println);
Output:
| 7 | 20 | | | 47 | 53 | | | 86 |
| | | 27 | 38 | | | 63 | 80 | 85 |
| 4 | | 26 | | | | 69 | 77 | 81 |

Related

vice versa coding for value and its variables

I have 2 variables A and B
if A =1 then B should B=2
and if A=2 then B should B=1
Like this, there are 3 pairs 1-2,3-4,5-6
What's the best way of making a code instead of just if-else
It is possible to use simple addition and subtraction to get the other element of the two (x, x + 1):
int a = 1; // the other is 2, sum is 3
int b = 3 - a; // if a = 2, b = 1
int c = 3; // the other is 4, sum is 7
int d = 7 - c; // if c = 4, d = 3
int m = 5; // the other is 6, sum is 11
int n = 11 - m;
Another approach could be using the following logic:
if (a % 2 == 1) b = a + 1;
else b = a - 1;
So, an array could be used to provide +/- 1:
static int[] signs = {-1, 1};
public static int nextWithArrPositive(int a) {
return a + signs [a % 2];
}
This expression fails to work for negative a as in this case a % 2 == -1 and more advanced logic would be required to calculate the value properly to take into account the negative remainder:
public static int nextWithArr(int a) {
int sign = (a & 0x80000000) >> 31; //-1 if a < 0, 0 otherwise
// a >= 0 : 0 - even, 1 - odd;
// a < 0 : 1 - even, 0 - odd
return a + signs[a % 2 - sign];
}
However, a simpler expression can be designed:
public static int nextWithMod(int a) {
return a + a % 2 - (a - 1) % 2;
}
Let's compare the results of the three implementations including xor solution b = ((a - 1) ^ 1) + 1 offered in the comments by user3386109:
public static int nextXor(int a) {
return ((a - 1) ^ 1) + 1;
}
Tests:
System.out.println("+-----+-----+-----+-----+");
System.out.println("| a | arr | mod | xor |");
System.out.println("+-----+-----+-----+-----+");
for (int i = -6; i < 7; i++) {
System.out.printf("| %2d | %2d | %2d | %2d |%n", i, nextWithArr(i), nextWithMod(i), nextXor(i));
}
System.out.println("+-----+-----+-----+-----+");
Output:
+-----+-----+-----+-----+
| a | arr | mod | xor |
+-----+-----+-----+-----+
| -6 | -5 | -5 | -7 |
| -5 | -6 | -6 | -4 |
| -4 | -3 | -3 | -5 |
| -3 | -4 | -4 | -2 |
| -2 | -1 | -1 | -3 |
| -1 | -2 | -2 | 0 |
| 0 | -1 | 1 | -1 |
| 1 | 2 | 2 | 2 |
| 2 | 1 | 1 | 1 |
| 3 | 4 | 4 | 4 |
| 4 | 3 | 3 | 3 |
| 5 | 6 | 6 | 6 |
| 6 | 5 | 5 | 5 |
+-----+-----+-----+-----+
One simple solution is a table lookup. In an array for each possible value of a I store the corresponding value of b:
private static final int[] B_PER_A = { -1, 2, 1, 4, 3, 6, 5 };
Since array indices always start at 0 in Java, we need to put a dummy value at index 0. This value is never used (or should never be, at least).
Let’s try it out:
for (int a = 1; a <= 6; a++) {
int b = B_PER_A[a];
System.out.format("a: %d; b: %d.%n", a, b);
}
Output:
a: 1; b: 2.
a: 2; b: 1.
a: 3; b: 4.
a: 4; b: 3.
a: 5; b: 6.
a: 6; b: 5.
Generalized to more than 3 pairs
If you need to handle a variable number of pairs, resort to math.
public static int calcB(int a) {
// 0-based index of pair (0 = 1-2, 1 = 3-4, etc.)
int pairNumber = (a - 1) / 2;
// a + b for given pair
int pairSum = 4 * pairNumber + 3;
int b = pairSum - a;
return b;
}
In each pair the sum is equivalent to 3 modulo 4. I am exploiting this fact in finding the sum for a given pair. When I subtract a from that sum, I get b. Let’s see that demonstrated too:
for (int a = 1; a <= 8; a++) {
int b = calcB(a);
System.out.format("a: %d; b: %d.%n", a, b);
}
a: 1; b: 2.
a: 2; b: 1.
a: 3; b: 4.
a: 4; b: 3.
a: 5; b: 6.
a: 6; b: 5.
a: 7; b: 8.
a: 8; b: 7.
The latter solution is more complicated and harder to read. So if you always have got three pairs, no more, no less, I recommend the simpler table lookup presented first.

Pascal's triangle faulty output

Hi I'm making an iterative Pascal's triangle in Java. So far everything works great, until number of rows exceed 13. The output becomes faulty. I must be doing something wrong here, please help.
IterativePascal:
public class IterativePascal extends ErrorPascal implements Pascal {
private int n;
IterativePascal(int n) throws Exception {
super(n);
this.n = n;
}
public void printPascal() {
printPascal(false);
}
public void printPascal(boolean upsideDown) {
if (n == 0) { return; }
for (int j = 0; j <= n; j++) {
for (int i = 0; i < j; i++) {
System.out.print(binom(j - 1, i) + (j == i + 1 ? "\n" : " "));
}
}
}
public long binom(int n, int k) {
return (k == 0 || n == k) ? 1 : faculty(n) / (faculty(k) * faculty(n - k));
}
private long faculty(int n) {
if (n == 0 || n == 1) { return 1; }
int result = 1;
for (int i = 2; i <= n; i++) {
result = result * i;
}
return result;
}
}
Output:
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
1 5 10 10 5 1
1 6 15 20 15 6 1
1 7 21 35 35 21 7 1
1 8 28 56 70 56 28 8 1
1 9 36 84 126 126 84 36 9 1
1 10 45 120 210 252 210 120 45 10 1
1 11 55 165 330 462 462 330 165 55 11 1
1 12 66 220 495 792 924 792 495 220 66 12 1
1 4 24 88 221 399 532 532 399 221 88 24 4 1 <----- wrong
1 0 1 5 14 29 44 50 44 29 14 5 1 0 1 <----- wrong
Help would be appriciated, since I'm new with algorithms.
You're reaching number overflow. Because 14! is too big to fill in java long.
The solution will be to use + instead of !.
Keep your triangle as an 2D array and iterate through it. Each cell should be sum of two 'above'.
+---+---+---+---+
| 1 | | | |
| 1 | 1 | | |
| 1 | 2 | 1 | |
| 1 | 3 | 3 | 1 |
+---+---+---+---+
The code will be as it follows:
public static void triangle(int n) {
int[][] triangle = new int[n];
for (int i = 0; i < n; i++) {
triangle[i] = new int[i+1];
}
triangle[0][0] = 1;
triangle[1][0] = 1;
triangle[1][1] = 1;
for (int i = 2; i < n; i++) {
triangle[i][0] = 1;
for (int j = 1; j < triangle[i].length - 1; j++) {
triangle[i][j] = triangle[i-1][j] + triangle[i-1][j+1];
}
triangle[i][triangle[i].length-1] = 1;
}
printArray(triangle);
}
Edit:
As the OP requires recursive solution with binoms, I decided to add solution introducing BigIntegers as it might be the case.
public BigInteger binom(int n, int k) {
return (k == 0 || n == k) ? BigInteger.ONE : faculty(n).divide((faculty(k).multiple(faculty(n - k)));
}
private BigInteger faculty(int n) {
BigInteger result = BigInteger.ONE;
while (!n.equals(BigInteger.ZERO)) {
result = result.multiply(n);
n = n.subtract(BigInteger.ONE);
}
return result;
}
public void printPascal(boolean upsideDown) {
if (n == 0) { return; }
for (int j = 0; j <= n; j++) {
for (int i = 0; i < j; i++) {
System.out.print(binom(j - 1, i).toString() + (j == i + 1 ? "\n" : " "));
}
}
}
Probably the problem is in your computation of the factorial: I'd assume that your int type can hold numbers up to 32 bits, but 13! is larger than that.
You could check whether long can store larger numbers and define result as long.

array combine inputs more then 2

I'm working on an implementation of the "Merge Numbers" game, seen here on the Play store: https://play.google.com/store/apps/details?id=com.ft.game.puzzle.cubelevels
The idea is that if I have a 2D array of cells, some of which are empty and others of which have numbers, and I place a given number into an empty cell, then if that number matches at least 3 of its neighbors, the neighbors are made empty and the cell value is incremented. A simple example:
| 1 | 2 | 3 | 4 |
| 3 | | 2 | |
| 1 | 2 | 3 | |
| | 2 | 1 | 4 |
If the next number (generated randomly by the game) is 2, and I place it into cell (1, 1) (where (0, 0) is the upper left cell), the new game board should look like this:
| 1 | | 3 | 4 |
| 3 | 3 | | |
| 1 | | 3 | |
| | 2 | 1 | 4 |
The newly-placed 2 is incremented to 3, and the neighboring cells with value of 2 have been cleared.
I'm having trouble figuring out how to do this. Here is my code so far:
package com.company;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
int[][] w = {{1, 2, 3, 4}, {3, 0, 4, 0}, {1, 2, 3, 0}, {0, 2, 1, 4}};
Scanner input = new Scanner(System.in);
System.out.println("Enter space for putting 1: ");
int a = input.nextInt();
int b = input.nextInt();
if (a == 1 && b == 1) {
w[1][1] = 1;
for (a = 0; a < w.length; a++) {
for (b = 0; b < w[0].length; b++) {
System.out.print(w[a][b] + " ");
}
System.out.print('\n');
}
System.out.println("Enter space for putting 4: ");
a = input.nextInt();
b = input.nextInt();
if (a == 1 && b == 3) {
w[1][3] = 4;
for (a = 0; a < w.length; a++) {
for (b = 0; b < w[0].length; b++) {
System.out.print(w[a][b] + " ");
}
System.out.print('\n');
}
}
}
}
}
How can I check to see if the neighbors of the newly-added number have the same value?
How can I increment the newly-added number?

Java : A pipe used in a print statement in java?

What is it when a pipe is used in print statement in java? For example
System.out.println(6 | 3);
Output : 7
System.out.println(6 | 4);
Output : 6
Quite simple
System.out.println(6 | 3);
Performing "OR" operation of two values using corresponding binary values.
6 - 0 1 1 0
3 - 0 0 1 1 (OR)
-------------
0 1 1 1 (7)
-------------
System.out.println(6 | 4);
6 - 0 1 1 0
3 - 0 1 0 0 (OR)
-------------
0 1 1 0 (6)
-------------
6 | 3 6 | 4
6 binary: 110 110
another: 101 100
bin or: 111 110
transform: 7 6
It's a binary bitwise or operator, and it produces an int. We can inspect the values in binary and decimal with a small program like
int i = 6;
for (int j = 3; j < 5; j++) {
System.out.printf("%d (%s) | %d (%s) = %d (%s)%n", i,
Integer.toBinaryString(i), j, Integer.toBinaryString(j),
(i | j), Integer.toBinaryString(i | j));
}
And the output is
6 (110) | 3 (11) = 7 (111)
6 (110) | 4 (100) = 6 (110)

Code to concatenate two numbers' bits not working

The task is to concat the binary of 2 given numbers.
Example:
Given 5 (101) and 3 (011), the result is 46 (concat(101, 011) = 101011)
The code thus far:
public class Concat {
public static void main(String[] args) {
int t = 0;
int k = 5;
int x = 3;
int i = 0;
while (i < 3) {
t = x % 2;
x /= 2;
k <<= 1;
k |= t;
++i;
}
System.out.println(k);
}
}
But the problem is that the above code gives 101110, not 101011.
What's the problem?
Your problem is that you're feeding the bits of the second number in backwards. That's because x%2 is the low order bit:
+---+---+---+ <110
| 1 | 0 | 1 | <-----------------+^
+---+---+---+ |1
+---+---+---+ |1
| 0 | 1 | 1 | ----+0
+---+---+---+ 011>
Cringe at my awesome artistic abilities :-) However, if you already know that it's 3 bits wide, just use:
public class concat {
public static void main (String[] args) {
int t = 0;
int k = 5;
int x = 3;
k <<= 3;
k |= x;
// or, in one line: k = (k << 3) | x;
System.out.println(k);
}
}
In terms of how that looks graphically:
+---+---+---+
k:| 1 | 0 | 1 |
+---+---+---+
+---+---+---+
x:| 0 | 1 | 1 |
+---+---+---+
+---+---+---+---+---+---+
k<<=3:| 1 | 0 | 1 | 0 | 0 | 0 |
+---+---+---+---+---+---+
+---+---+---+
x:| 0 | 1 | 1 |
+---+---+---+
+---+---+---+---+---+---+
k|=3:| 1 | 0 | 1 | 0 | 1 | 1 |
+---+---+---+---+---+---+
^ ^ ^
+---+---+---+
x:| 0 | 1 | 1 |
+---+---+---+
There's no apparent reason for doing it one bit at a time.
You just shift one number and then or with the other number:
int a = 5;
int b = 3;
int c = (a << 3) | b;
I don't know what language you are using, it's almost Java, so I am going with that.
This returns the result you are asking for, though you haven't given rules for determining how you know that 3 should be 011 instead of 11.
I have made the assumption that you want to assume that both numbers have the same number of bits, so 3 is 011 because 5 requires 3 bits.
public class Concat {
public static void main(String[] args) {
System.out.println( joinNums(3,5) );
}
public static int numBits( int n ) {
return (int)Math.ceil( Math.log(n) / Math.log(2) );
}
public static int joinNums( int num1 , int num2 ) {
int bits = Math.max( numBits(num1) , numBits(num2) );
return (num1 << bits) + num2;
}
}

Categories

Resources