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.
Related
Given a matrix of N * M. Find the minimum path sum in matrix. The minimum path is sum of all elements from first row to last row where you are allowed to move only down or diagonally to left or right. You can start from any element in first row.
I've written the code,but what is wrong in my code/logic?
here in my algorithm I am starting from the element of the top row, now I'm going to the second row and algorithm is finding the minimum value and add with the first element and thus it makes way to the bottom(a element can only add with the elment which is under it and also can move diagonally right and left)
import java.util.Scanner;
public class Main{
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int row, column, i, j,temp=0;
System.out.print("Please enter the desire grid dimension: ");
row = sc.nextInt();
column = sc.nextInt();
int array[][] = new int[row][column];
System.out.println("Please enter the desired input:");
for (i = 0; i < row; i++) {
for (j = 0; j < column; j++) {
array[i][j] = sc.nextInt();
}
}
for(i=1;i<row;i++){
for(j=0;j<column;j++){
array[i][j] += Math.min((j==0)?0:array[i-1][j-1],Math.min(array[i-1][j],(j==column-1)?0:array[i-1][j+1]));
}
}
for(i=0;i<row;i++){
for(j=0;j<column;j++){
System.out.print(array[i][j] + " ");
}
System.out.println();
}
for(j=0;j<column-1;j++){
temp = Math.min(array[row-1][j],array[row-1][j+1]);
}
System.out.println(temp);
}
}
let your input is
1 5 1 5 1* 5
3 3 2 3 3* 4
2 3 4 4 3 2*
2 2 3 2 2* 4
2 2 4 3 4 2*
4 4 4 4 2* 3
your output should be 12,path is marked with(*) 1+3+2+2+2+2=12
I'm getting 3,because after running my algorithm the matrix became
1 5 1 5 1 5
3 4 3 4 4 4
2 6 7 7 7 2
2 4 9 9 4 4
2 4 8 7 8 2
4 6 8 11 4 3
I am not giving you a complete answer. You will learn more from finding out yourself. At the same time this will be more gratifying for you. So I will just guide you slightly on the way and trust you to do the rest yourself. It’s not that hard.
First, however, for other readers to follow what I write I need to give the explanation that you should have given in the question of how your algorithm was supposed to work. You are modifying the matrix in a way so that each cell instead of its original number gets to contain the minimum sum of a path from the top to that cell inclusive. For example:
We see from your matrix after the algorithm has run that the top line is unchanged. This is correct since you can go directly into each cell, so the sum is equal to the original cell value.
In the second line, the second (index 1) cell has been changed from 3 to 4. This is correct since to go to that cell we need to go through 1 or 5 or 1 in the first line. 1 gives the minimal sum, so 1 is added to 3, hence 4.
In the same line, the leftmost cell is unchanged 3. The is incorrect. To get to this cell you also need to go through either 1 or 5 in the first line, so this 3 too should have been changed to 4. I will give you one piece of information: the cell was not forgotten. Your loop assigns a value to the cell, only not the correct value. 1 should have been added, instead 0 was added. Where does this 0 come from? Your turn! Happy debugging.
I am supposed to print the following output by using loops:
1
2 1
3 2 1
4 3 2 1
5 4 3 2 1
6 5 4 3 2 1
7 6 5 4 3 2 1
The highest number in this pattern (in this example, 7) is determined by user input. Here is the applicable code for the pattern:
index=patternLength+1; n=1; //These values are all previously intitialized
while (index!=1) {
index--;
printSpaces((index*2)-2); //A static method that prints a certain number of spaces
while(n!=1) {
n--;
System.out.print(n + " ");
}
System.out.print("\n");
n=patternLength+1-index;
}
And here is the incorrect output for the user input "7":
1
2 1
3 2 1
4 3 2 1
5 4 3 2 1
There are two blank lines preceding the incorrect output; these lines have the correct number of spaces necessary for the complete/correct pattern, but for some reason, the actual numbers start printing too "late" in the loop. In other words, the spaces that appear before the "1, 2 1" in the correct example are in the incorrect output. It's some of the numbers that are missing and make the incorrect example incorrect.
OK, I got it.
index=patternLength+1; n=1;int nSetter=1;
//Loop C
System.out.println("Pattern C:");
while (index!=1) {
index--;
printSpaces((index*2)-2);
while(n!=0) {
System.out.print(n + " ");
n--;
}
System.out.print("\n");
nSetter++;
n = nSetter;
}
My problem was that my "n" needed to go both up and down, so the extra variable "nSetter" seems to have solved that, although this may be a round-about solution. Whatever. Thanks to #Andreas for pointing me in the correct direction and #JohnKugelman for the helpful edit.
Please try this code your second while loop is not correct.
int index = patternLength + 1;
int n = 2; //These values are all previously intitialized
int i = 1;
while (index != 1) {
index--;
printSpaces((index * 2) - 2); //A static method that prints a certain number of spaces
while (n != 1) {
n--;
System.out.print(n + " ");
}
System.out.print("\n");
i++;
n = i+1;
}
Overview
I'm sure this is a simple problem for most of you on here, but I have been struggling with a small spacing problem and was hoping I can learn from someone more experienced. I need to produce a triangle similar to the one below. You can see that the numbers are aligned correctly no matter the length.
Enter the number of lines: 8
1
1 2 1
1 2 4 2 1
1 2 4 8 4 2 1
1 2 4 8 16 8 4 2 1
1 2 4 8 16 32 16 8 4 2 1
1 2 4 8 16 32 64 32 16 8 4 2 1
1 2 4 8 16 32 64 128 64 32 16 8 4 2 1
My Code
Here is what I have so far. It isn't the prettiest, but it seems to give me the correct values at least.
import java.util.Scanner;
public class Pyramid2
{
public static void main(String[] args)
{
int i, j, k, l, a;
//Create a Scanner object
Scanner in = new Scanner (System.in);
//Prompt the user to enter number of rows in pyramid
System.out.print("Enter number of rows: ");
int rows = in.nextInt();
a = rows;
//Variables to determine length
int length = ("" + rows).length();
String str = " %" + length + "s";
//Logic
for (i = 1; i <= rows; i++)
{
for (j = a; j > 0; j--)
{
System.out.printf(str, " ");
}
for (j = 1; j <= (2*rows); j++)
{
if (j == (rows+1))
{
continue;
}
if (j < (rows+1))
{
k = j;
}
else
{
k = ((2*rows)-j+1);
}
if (k >= (rows+1-i))
{
l = (int)Math.pow(2, (i+k-rows-1));
String str1 = "" + l;
System.out.printf(str, str1);
}
}
a--;
System.out.println();
}
}
}
My Results
This is the console output when 6 rows are chosen. Everything looks good until row 5 when a 2 digit number (16) appears. What are some efficient ways to align the results properly?
Enter number of rows: 6
1
1 2 1
1 2 4 2 1
1 2 4 8 4 2 1
1 2 4 8 16 8 4 2 1
1 2 4 8 16 32 16 8 4 2 1
You calculate length as the number of digits in rows, but it needs to be number of digits in largest number in triangle.
E.g. for rows = 6, largest number is 32, so length should be 2.
For rows = 8, largest number is 128, so length should be 3.
Largest number is 2rows, which in Java means 1 << rows, so change length calculation to:
int length = ("" + (1 << rows)).length();
You are also adding one too many blanks on the left.
Change code to this:
a = rows - 1;
First of all i can recommend to determine the largest number in pyramid. Then count digits in this number. For 8 rows this number is 128, it has 3 digits. According this information we can decide that we need 3+1=4 (including spaces) characters to print every value in pyramid.
After it you have to complete every output number by spaces (from the left) to achive string size of 4 characters.
And the global prefix for every pyramid line will contain (rows - i) * 4 spaces.
I have the layout for the pyramid set I just can't find out how I would combine or mathematically get the next few numbers. What I need is:
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
My code right now is:
int x = 7;
for (int i =1; i<=x; i++) {
for (int j =1; j<=x-i; j++) {
System.out.print(" ");
}
for (int k=1; k<=i;k++) {
System.out.printf("%2d",k);
}
for(int k=i-1; k>=1;k--) {
System.out.printf("%2d",k);
}
System.out.println(" ");
}
But my output comes out as:
1
1 2 1
1 2 3 2 1
1 2 3 4 3 2 1
1 2 3 4 5 4 3 2 1
1 2 3 4 5 6 5 4 3 2 1
1 2 3 4 5 6 7 6 5 4 3 2 1
Sorry if this came out weird; this is my first question ever on this site. How can I modify my code to get the other pyramid?
Firstly, I presume you are trying to compute a Pascal triangle and that when you wrote that the desired output was:
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
you actually mean:
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
because otherwise it doesn't make much sense.
Assuming you have made a slight error and the second triangle is the one you want then that is a Pascal's triangle. The rules for computing a Pascal triangle is to add the number above and to the left with the number above and to the right to find the new value.
Image credit Hersfold
You can quite easily write a recursive function that will do this. With a recursive function a good approach is to write your guards and base case, then recurse. This would look like:
private static int calculatePascalNumber(int row, int column)
{
if (row < 1 || column < 1 || column > row) {
return 0;
} else if (column == 1 || row == column) {
return 1;
} else {
return calculatePascalNumber(row - 1, column - 1) +
calculatePascalNumber(row - 1, column);
}
}
These are the rules for this function
if the row or column is less than 1 or the column is wider than the
row these are points outside of the triangle and should return 0
if the column is in one of the end columns (either column equals 1 or the row and column are equal) return 1
otherwise add the two numbers above to the left and the right
You could then call this function within your code that would look like
int x = 7;
for (int row = 1; row <= x; row++) {
for (int j =1; j<=x-row; j++) {
if (j % 2 == 0) {
System.out.print(" ");
} else {
System.out.print(" ");
}
}
for (int column=1; column<=row;column++) {
System.out.printf(" %2d", calculatePascalNumber(row, column));
}
System.out.println(" ");
}
I have revised it a little for formatting, if you wanted to put in further work the ouput formatting would be a good thing to look at.
Finally, it is worth noting performance. If you wanted to run this to compute values on large triangles the number of recursive calls would start making this function go very slowly. A possible way to resolve this would be to cache the results of calls to calculatePascalNumber so that when it is called with parameters it has already computed it returns the value from a hashmap/ array rather than running through all the computations multiple times.
Another option to speed this up for larger triangles is to use this function for calculating a row by itself which could lead to the following code for calculatePascalNumber
private static int calculatePascalNumber(int row, int column)
{
if (row < 0 || column < 0 || column > row) {
return 0;
} else if (column == 1) {
return 1;
} else {
return (calculatePascalNumber(row, column - 1)
* (row + 1 - column)) / (column - 1);
}
}
but what you gain with efficiency you lose with clarity.
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.