Rotating array differently - java

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.

Related

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

Volume reaching over top arrays

Given an array of positive integers representing terrain heights (in 2-d, ala Super Mario)) and an integer representing a flat sea level, return a container of integers representing the volume of each unique body of water.
Please do not solve the whole problem for me!
I have a few questions:
Lets take an example first.
int [] arr = {4, 3, 5, 6, 4, 2};
int sea_level = 4;
The way it is set up is like this:
6
5 6
4 5 6 4 2
4 3 5 6 4 2
4 3 5 6 4 2
4 3 5 6 4 2
Q So we can't cross over 4 right?
So we have the ranges, [4, 3] and [4, 2] (after the [5, 6] range).
But how do I calculate the volume?
Arraylist<Integer> list = new Arraylist<>();
int volume = 0;
for(int i = 0; i < arr.length; i++){
if(arr[i] <= sea_level){
volume += arr[i];
} else{
list.add(volume); //volume for one block, then reset down.
volume = 0; //loop starts with the next one.
}
}
Is this the way to go about it? I don't understand the problem.
Given your example:
6
5 6 5
4 5 6 5
4 3 5 6 5
4 3 5 6 2 5
4 3 5 6 2 1 5
The water line is at 4, so:
6
5 6 5
~~~~~~~~~~~~5
4 5 6 5
4 3 5 6 5
4 3 5 6 2 5
4 3 5 6 2 1 5
Which makes the water volume the holes beneath the water line, or:
6
5 6 5
~~~~~~~~~~~~5
4 W 5 6 W W 5
4 3 5 6 W W 5
4 3 5 6 2 W 5
4 3 5 6 2 1 5
or, 1 cube of water, and then 5 cubes of water.
Now, how do you calculate that... you need the volume.
The volume is measured between the waterline (4) and the terrain height...
So to measure the volume: sea_level - a[i]

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)

Scanning an input and skipping certain characters

I'm scanning a text file that has a sudoku board with a few separators. this is what a sample input would look like.
1 - - | 4 5 6 | - - -
5 7 - | 1 3 b | 6 2 4
4 9 6 | 8 7 2 | 1 5 3
======+=======+======
9 - - | - - - | 4 6 -
6 4 1 | 2 9 7 | 8 3 -
3 8 7 | 5 6 4 | 2 9 -
======+=======+======
7 - - | - - - | 5 4 8
8 r 4 | 9 1 5 | 3 7 2
2 3 5 | 7 4 $ | 9 1 6
where it has "|" as borders and =====+====+==== as dividers. I made this code to ignore the | and ====+===+=== but it's skipping that part of the code and declaring them as invalid characters and adding 0's in there place
public static int [][] createBoard(Scanner input){
int[][] nSudokuBoard = new int[9][9];
for (rows = 0; rows < 9; rows++){
for (columns = 0; columns < 9; columns++){
if(input.hasNext()){
if(input.hasNextInt()){
int number = input.nextInt();
nSudokuBoard[rows][columns] = number;
}//end if int
else if(input.hasNext("-")){
input.next();
nSudokuBoard[rows][columns] = 0;
System.out.print("Hyphen Found \n");
}//end if hyphen
else if(input.hasNext("|")){
System.out.print("border found \n");
input.next();
}// end if border
else if(input.hasNext("======+=======+======")){
System.out.print("equal row found \n");
input.next();
}// end if equal row
else {
System.out.print("Invalid character detected at... \n Row: " + rows +" Column: " + columns +"\n");
System.out.print("Invalid character(s) replaced with a '0'. \n" );
input.next();
}//end else
}//end reading file
}//end column for loop
}//end row for looop
return nSudokuBoard;
}//end of createBoard
I talked it over with a tutor but i don't remember his suggestion on how to fix this.
The String parameter to hasNext is treated as a regular expression. You need to escape special characters:
else if(input.hasNext("\\|")){
else if(input.hasNext("======\\+=======\\+======")){
http://ideone.com/43j7R
Your loops increment the row and column counters even when you are consuming a border or a divider. So even after you fix other issues (as explained in the previous answer), you will finish filling the matrix before you've read all your input. You need to modify your code to conditionally advance the row and column counters only after you've consumed an integer or a dash. This would mean removing the for loops, changing the first if(input.hasNext()) to a while, and adding rows++ and columns++ in the places where you've consumed an integer or dash and are setting a value for nSudokuBoard[rows][columns]. You would also need logic to determine when to increment rows and when to set columns back to 0.
Also, stylistically speaking, you should rename rows to row and columns to column.

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