Java : A pipe used in a print statement in java? - 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)

Related

2D array random index Lotto game

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 |

Java: Print format with two arrays in one line and different length

I want to print a beautiful table to my console with the content of two arrays I have given. Both arrays are ArrayLists and may have a different length. Furthermore, inside both ArrayLists are arrays which have a length of 3.
The problem I am facing right now is that I want to have both values of each ArrayLists in one line. E.g:
EAN STOCK CAPACITY | EAN STOCK CAPACITY
10 3 3 | 10 2 4
11 1 6 | 11 4 5
12 5 7 | 12 6 9
13 7 9 | 13 3 5
14 4 7 | 14 0 4
15 0 7 |
16 0 2 |
On the left side you can see one ArrayList with the arrays contained and on the right side the other ArrayList with the arrays contained.
However, I don't know how to iterate through both arrays while printing the values of both in one line. Especially when the size of both ArrayLists are not the same..
This is my code so far... I don't know how to realize it
private void printDrinks(ArrayList<int[]> storageRoom, ArrayList<int[]> saleRoom){
System.out.format("%10s %10s %10s %40s %10s %10s %10s", "EAN", "STOCK", "CAPACITY", "|", "EAN", "STOCK", "CAPACITY"); System.out.println();
String row = "";
for (int i = 0; i < storageRoom.size(); i++){
row += String.format("%10s %10s %10s %10s", storageRoom.get(i)[0], storageRoom.get(i)[1], storageRoom.get(i)[2]);
}
for (int i = 0; i < saleRoom.size(); i++){
row += String.format("%10s %10s %10s %10s", saleRoom.get(i)[0], saleRoom.get(i)[1], saleRoom.get(i)[2]);
}
System.out.println(row);
}
Can you guys give me a hint or help me?
Kind regards and Thank You!
First find the total number of rows to print, then loop that many times. Print spaces (left) or nothing (right) if the current row exceeds size of list.
private static void printDrinks(List<int[]> storageRoom, List<int[]> saleRoom){
int rows = Math.max(storageRoom.size(), saleRoom.size());
System.out.println("EAN STOCK CAPACITY | EAN STOCK CAPACITY");
for (int i = 0; i < rows; i++) {
if (i < storageRoom.size())
System.out.printf("%3d %7d %10d |", storageRoom.get(i)[0], storageRoom.get(i)[1], storageRoom.get(i)[2]);
else
System.out.printf("%25s", "|");
if (i < saleRoom.size())
System.out.printf(" %3d %7d %10d", saleRoom.get(i)[0], saleRoom.get(i)[1], saleRoom.get(i)[2]);
System.out.println();
}
}
Tests
printDrinks(Arrays.asList(new int[][] {{10,3,3},{11,1,6},{12,5,7},{13,7,9},{14,4,7},{15,0,7},{16,0,2}}),
Arrays.asList(new int[][] {{10,2,4},{11,4,5},{12,6,9},{13,3,5},{14,0,4}}));
printDrinks(Arrays.asList(new int[][] {{10,2,4},{11,4,5},{12,6,9},{13,3,5},{14,0,4}}),
Arrays.asList(new int[][] {{10,3,3},{11,1,6},{12,5,7},{13,7,9},{14,4,7},{15,0,7},{16,0,2}}));
Outputs
EAN STOCK CAPACITY | EAN STOCK CAPACITY
10 3 3 | 10 2 4
11 1 6 | 11 4 5
12 5 7 | 12 6 9
13 7 9 | 13 3 5
14 4 7 | 14 0 4
15 0 7 |
16 0 2 |
EAN STOCK CAPACITY | EAN STOCK CAPACITY
10 2 4 | 10 3 3
11 4 5 | 11 1 6
12 6 9 | 12 5 7
13 3 5 | 13 7 9
14 0 4 | 14 4 7
| 15 0 7
| 16 0 2

Java - Bit manipulation (count number of 1s in number)

Can someone explain to my why this method works, I've worked through what it does, but why does this work. Is there a pattern that binary numbers have? Like for example at i = 3, why does it do res[1] + 1 to get 2. How does res[3 >> 1] + (3&1) help to count the number of ones in the binary number of 3?
What the code should do: It works so don't worry about that. It is supposed to return a list that contains the number of ones in the binary representation of each number until num+1. And num is always >= 0. So for num = 5, you would get [0, 1, 1, 2, 1, 2], where the last index represents the number of 1s in the binary representation of 5, and the first index is number of ones in binary rep of 0.
Code:
public int[] countBits(int num) {
int[] res = new int[num+1];
for (int i = 0; i<num+1; i++){
res[i] = res[i >> 1] + (i & 1);
}
return res;
}
This is the part I can't wrap my head around:
res[i] = res[i >> 1] + (i & 1);
EDIT - This is not homework, so please fully explain your answer. This is to help with interviews.
int[] res = new int[num+1];
for (int i = 0; i<num+1; i++){
res[i] = res[i >> 1] + (i & 1);
}
return res;
rewritten as
int[] res = new int[num+1];
for (int i = 0; i<num+1; i++){
x = res[i >> 1];
y = (i & 1);
res[i] = x + y;
}
return res;
Create an array to fit the answers, +1?
for each, starting at the low end.
res[0] = res[0] + 0&1 = 0 + 0 = 0;
res[1] = res[0] + 1&1 = 0 + 1 = 1;
res[2] = res[1] + 0&1 = 1 + 0 = 0;
res[3] = res[1] + 1&1 = 1 + 1 = 2;
Looking at this pattern, I can see that because of the right shift, and the masking with &, it's splitting the problem into 2, one that's been solved previously due to the iteration order, and a bit check of the last digit.
assuming a 8 bit int, for brevity,
1 = 00000001
2 = 00000010
3 = 00000011
Split the binary into parts.
i i>>1 y&1
1 = 0000000 1
2 = 0000001 0
3 = 0000001 1
So it fetches the results for the number of ones in the first half of the array, then counts the last digit.
Because of the iteration order, and array initialisation values, this is guaranteed to work.
For values < 0 , due to 2's compliment it gets hairy, which is why it only works for values >=0
in 'res[i] = res[i >> 1] + (i & 1);'
one number's result is divide into 2 parts
the last bit is 1 or not,which can be calculate by (i & 1).
the first (n-1) bits,this number is equals to res[i >> 1]'s bitcount.this is a simple recursive call
shift by 1 gives the floor number divided by 2.
AND 1 returns 1 if the last bit of the number is 1
Hope the below table helps to see what is happening :) Just my 2 cents.
<pre>
--------------------------------
<b>
# 8 4 2 1 >>1 &1 Ans
</b>
-------------------------------
0 0 0 0 0 0 0 0
1 0 0 0 1 0 1 1
2 0 0 1 0 1 0 1
3 0 0 1 1 1 1 2
4 0 1 0 0 2 0 1
5 0 1 0 1 2 1 2
6 0 1 1 0 3 0 2
7 0 1 1 1 3 1 3
8 1 0 0 0 4 0 1
9 1 0 0 1 4 1 2
10 1 0 1 0 5 0 2
11 1 0 1 1 5 1 3
12 1 1 0 0 6 0 2
13 1 1 0 1 6 1 3
14 1 1 1 0 7 0 3
15 1 1 1 1 7 1 4
</pre>

Rotating array differently

hey,
I need to rotate a 2d array in such way :
4X4-->
Input Output
1 2 3 4 5 1 2 3
5 6 7 8 1 2 6 4
1 2 3 4 5 3 7 8
5 6 7 8 6 7 8 4
or for odd 5X5-->
Input Output
1 2 3 4 5 6 1 2 3 4
6 7 8 9 10 1 2 7 8 5
1 2 3 4 5 6 7 3 9 10
6 7 8 9 10 1 8 9 4 5
1 2 3 4 5 2 3 4 5 10
can someone help me?
as you can see there are two different rings and are gettin rotated .
plz help
Im out of ideas and luck.
You can divide the n x n array like this:
+-----------+
|\ /|
| \ 1 / |
| \ / |
| \ / |
| \ / |
| 4 + 2 |
| / \ |
| / \ |
| / \ |
| / 3 \ |
|/ \|
+-----------+
Then all pixels in region 1 move right one pixel, all pixels in region 2 move down one pixel, etc.
The regions can be defined mathematically. Assume the lower-left corner is (0,0), then the line dividing regions 1&4 from 2&3 is x = y, and the line dividing regions 1&2 from 3&4 is x = n - y. Then:
A pixel is in region 1 if x < y and x > n - y. (left of x=y, right of x=n-y)
A pixel is in region 2 if x > y and x > n - y. (right of x=y, right of x=n-y)
Similarly for regions 3 & 4.
You need to get the edge pixels right (some of those comparisons need an equal sign), and your code will depend on the odd-or-even-ness of the array size. But you should be able to go from there.
int [][] size = new int[sx][sx];
int [][] rot = new int[sx][sx];
int x=0;
for(int i=0;i<sx;i++)
{
for(int j=0;j<sx;j++)
{
size[i][j]=x++;
}
}
for(int i=0;i<sx;i++)
{
for(int j=0;j<sx;j++)
{
System.out.print(size[i][j]+"\t");
}
System.out.println();
}
int n=sx-1;
for(int i=0;i<=n;i++)
{
for(int j=0;j<=n;j++)
{
if(i<j && i>=n-j)
rot[i+1][j]=size[i][j];
else if(i>=j && i > n-j)
rot[i][j-1]=size[i][j];
else if(i>j && i <= n-j)
rot[i-1][j]=size[i][j];
else if(i<=j && i < n-j)
rot[i][j+1]=size[i][j];
}
}
How about going like this:
FIND OUTER EDGES (Hint: 0,0 to max_x,0; max_x,0 to max_x,max_y; max_x,max_y to 0,max_y; 0,max_y to 0,0)
Create a new array (call it buffer). (buffer[x][y])
buffer[1][0]=arr[0][0];
buffer[1][0]=arr[0][0];
buffer[1][0]=arr[0][0];
...
buffer[max_x][0]=arr[max_x - 1][0];
Make the next inner an "outer edge", start at 1,1 to max_x-1,max_y-1, and repeat.

Finding Shortest path in DAG (unweighed), between 2 vertices

Before the Floyd–Warshall/Dijkstra replies flood comes in please let me explain the situation as i'm sure either algorithm can be tuned for this case, and it has to be as this is not a toy example program (mind you, in java so have to keep it manageable memory-wise)
What i have is a web graph generated from node 0 to node n, node 3 cannot link to node 5, because node 5 didnt exist when node 3 was choosing it's out links. Every "node" is represented as in_neighbours[nodeID] and out_neighbours[nodeID] say nodeId=3, so we're talking about node 3. Note also that in_/out_ are both sorted, (in_ is naturally sorted as 5 will have chosen its out links all at once, only then 6 will choose out_links so 3's in_'s can never contain {6, 5, 7}) and ofc both can contain duplicates. (in/out are ArrayList arrays of size n, where out_ is always of size d or m, which along with n is specified at startup by the user)
No weights. What i must do is find the averageDistance()
public double getAvgDistance() {
int sum = 0;
for (int i=1; i<n; i++) {
for (int j=0; j < i; j++) {
sum += dist(i, j); // there are duplicates, make sure i skip
}
}
return (double)sum / (double)( ((n*(n-1)) / 2) );
}
What I have so far is the best case. Note i want only to find the distance between j & i, not all distances at the same time (not enough memory, it will be tested at m=20 d=1 000 000)
private int dist(int i, int j) {
int dist = 0;
for (int link : in_neighbours[j]) {
System.out.print("\nIs "+j+" linked to by "+i);
if (out_neighbours[i].contains(link)) {
System.out.print(" - yes!");
dist = 1;
}
}
return dist;
}
So im asking if the "fresher" (ofc at this point the graph is completed) node i is linking to any of its older buddies directly if so, distance is 1 hop.
Is it just me or the 'shortest' path will always be the first found path if nodes are traversed backwards?
How do i check if its not 1, the "else" after the base case? My math is fairly weak please be gentle :)
Any hints how to make use of the fact that the links are sorted?
It's not homework or something that im trying to cheat around from, it's not about the code itself, this has to be a useful tool, the "learning" comes by itself along the way.
here's how a graph looks nodeID, out links, in links for m=7 n=13, (note the 0 cycles is just how the graph is initialized):
0 | 0 0 0 0 0 0 0 | 0 0 0 0 0 0 0 1 1 1 1 1 1 1 2 2 2 2 2 3 4 5 6 6 7 8 9
1 | 0 0 0 0 0 0 0 | 2 2 3 4 5 5 8 12
2 | 0 0 0 0 0 1 1 | 3 3 3 3 3 4 4 4 6 7 8 10
3 | 0 1 2 2 2 2 2 | 4 4 5 5 6 6 7 11
4 | 0 1 2 2 2 3 3 | 5 5 6 8 9 10
5 | 0 1 1 3 3 4 4 | 6 7 8 9 9 11 12
6 | 0 0 2 3 3 4 5 | 7 7 7 8 9 9 12
7 | 0 2 3 5 6 6 6 | 8 9 10 11 11 12
8 | 0 1 2 4 5 6 7 | 10 10 10 11 12
9 | 0 4 5 5 6 6 7 | 10 11 11
10 | 2 4 7 8 8 8 9 | 12 12
11 | 3 5 7 7 8 9 9 |
12 | 1 5 6 7 8 10 10 |
Sorry for the agonising long read.
EDIT: Wrong code in the methods, this is what i think is correct now.
Revision of dist nr2, just try and find if theres a path at all:
private int dist(int i, int j) {
int dist = 0, c = 0, count = 0;
boolean linkExists = false;
for (int link : in_neighbours[j]) {
//System.out.print("\nIs "+j+" linked to by "+i);
if (out_neighbours[i].contains(link)) {
//System.out.print(" - yes!");
dist = 1; // there is a direct link
} else {
while ( c < j ) {
// if there's a path from 0 up to j, check if 'i' links to a node which eventually links to 'j'
if (out_neighbours[i].contains(c) &&
(out_neighbours[c].contains(link) || in_neighbours[c].contains(link) )) {
count++; // yes. and this is one node we had to step through to get closer
linkExists = true;
} else {
linkExists = false; // unreachable, the path was interrupted somewhere on the way
break;
}
c++;
}
if (linkExists) {
dist = count-1; // as 2 nodes are linked with 1 edge
} else {
dist = 0; // no path was found
}
}
}
return dist;
}
Since all edges have the same weight in your model, you can use a BFS search to find the shortest path from S to T.
This is an iterative process, starting with set #0, containing only the source node ({S}).
At each step i, you create set #i by finding all nodes achievable from set (i-1) in one step.
The iteration terminates in two cases:
1) When you detect that set #k contains T. In this case you return k-1.
2) When the set is empty, meaning that the two nodes are unreachable.
The memory consumption is about twice the number of nodes, since at each step i you are working with two sets (i-1 and i), bounded by the total number of nodes.
--EDIT--
Here is a possible implementation (I made some tests on it):
private Integer getDist(int i, int j) {
Set<Integer> currentSet = new HashSet<Integer>();
currentSet.add(i);
int dist = 0;
while (true) {
Set<Integer> nextSet = new HashSet<Integer>();
for (Integer currNode : currentSet)
nextSet.addAll(out[currNode]);
if (nextSet.isEmpty())
return null; //i.e. infinite
if (nextSet.contains(j))
return dist;
dist++;
currentSet = nextSet;
}
}
The implementation assumes that in and out are defined as List<Integer>[], and nodes are identified by numbers starting from 0. The minimal distance is counted as the number of intermediate nodes in the path, and not as the number of edges.
The duplicates you have in the lists do not break anything here, but they are irrelevant for the algorithm.

Categories

Resources