Reversing Diagonal In Matrix - java

Title says it all, I developed this diagonal method that searches the Matrix 'matrix' and goes from the Center to the far right corner. I also have it another set from the center to the left. I now have the question, how would I make it reversed, not starting from the bottom but actually starting "C", go all the way to "G" and keep moving towards the Left.
All it has to do is be reversed but I have tried and tried for about 2 hours and still to no avail. This is actually the final piece to my project I have going on and would awesome if someone could help flip.
Here's the code, I took out a large portion to conserve space.
public class Word {
public static int curCol = 10;
public static int curRow = 10;
public static String[][] matrix = {{"A","B","C"},
{"D","E","F"},
{"G","H","I"}};
private static void searchDiagonalCenterToRight(String word) {//Center to bottom Righ t. Diagnol Works, debug to go along column is needed
int rowOn = 0;
int colOn = 0;
int resetableCol = curCol;
resetableCol--;//Just resets everything then starts again.
int decreaser = curCol;//What to decrease by everytime it runs 10,9,8,7 all the way to 1
int resetableDec = decreaser;
resetableDec--;
char c;
String toFind = word.toUpperCase();
String developingInverse = "";
int integer = 0;
for(int row = 0; row < curRow; row++)//Matrices Row
{
for(int i = 0; i <= resetableDec; i++)
{
String developingWord = "";
integer = i;
for(int j = integer; j <= resetableDec; j++,integer++)
{
c = matrix[j][integer+row].charAt(0);//Sets to whatever letter it is on
char uC = Character.toUpperCase(c);
developingWord = developingWord + "" +uC;
System.out.println("On Row: " + row + " Started From: " + integer + " Now On: " + j);
System.out.println("Processing Letter: " + matrix[j][integer] + " Adding Letter To: " + developingWord);
}
}
resetableDec--;
}
System.out.println("\nNo Matching Word Was Found, Center To Left.");
}
}

Here is the code
public class ReverseDiagonalMatrix {
public static void main(String[] args) {
int [][] a = {{ 1, 2, 3, 4},
{ 5, 6, 7, 8},
{ 9,10,11,12},
{13,14,15,16}};
int a1[][]= {{1,2,3},
{4,5,6},
{7,8,9}};
int a2[][]= {{1,2},
{3,4}};
int [][] a3 = {{ 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}};
System.out.println("==========5x5==============");
findReverseDiagonalOrder(a3);
System.out.println("==========4x4==============");
findReverseDiagonalOrder(a);
System.out.println("===========3x3=============");
findReverseDiagonalOrder(a1);
System.out.println("===========2x2=============");
findReverseDiagonalOrder(a2);
}
public static void findReverseDiagonalOrder(int[][] a) {
int m = a.length;
int row=0;
int col = m-1;
for(int i=0;i<m*m;i++) {
System.out.println(a[row][col]);
if(col==m-1) {
if(row==0)
col--;
else {
col= (row==col)? 0:col-(row+1);
row= (row==m-1)? 1:0;
}
}
else if(row==m-1) {
if(col-1==0 && col>0)
col--;
else {
row = m-col;
col=0;
}
}
else {
row++;
col++;
}
}
}
}

To access the other diagonal just use the following loop
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
if(i==(n-j-1)){
//Do something
}
}
}
By using this logic you will get CEG
Add the same logic to construct other strings too.
EDIT:-
By changing loop like this
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
if(i<=(n-j-1)){
System.out.println("("+i+","+j+")");
}
}
}
You can access elements (0,0) (0,1) (0,2) (1,0) (1,1) (2,0). I hope that is what you want.

Related

User input comparison with values of array

I'm trying to make a lottery game in java to run in the console afterwards with user input. I have a [3][9] array of random numbers between 1-9 in column 1, 10-19 in column 2, until 90, with half the numbers being 0, meaning they aren't part of the game or simply blanks.
So far, I have the numbers created in the array and they output fine, but I need to allow the user to have input and the numbers being guessed to start as blanks (or x instead of the number) and when the user actually gets the right number, it would switch that with the number generated previously. This would repeat itself until all the numbers were right, and then a message indicating a win would show.
How can I compare the inputs with the values generated? And how do I hide these values until they are guessed by the user?
Final Edit: If a line is completed with correct numbers, how do I keep track of this to also display message if this happens?
This is the random array index:
import java.util.Arrays;
import java.util.Random;
class Loto {
public static void main(String[] args) {
int[][] cartao = new int[3][9];
Random rand = new Random();
for(int i = 0; i< cartao.length; i++){
for(int j = 0; j< 5; j++){
int x = rand.nextInt(89) + 1;
while(cartao[i][x / 10] !=0) {
x = rand.nextInt(89) + 1;
}
cartao[i][x / 10] = x;
}
}
for(int[] row : cartao){
System.out.println(Arrays.toString(row));
}
}
}
You have to store what has been guessed correctly or not. For example you can use an auxiliary boolean matrix though it is not necessary (u can use only your card array, storing correctly guessed guesses has -1 for example), but it is easier to the eye I would say
public class Lotto {
boolean correctlyGuessed[][];
int lottoCard[][];
public Lotto() {
correctlyGuessed = new boolean[3][9];
lottoCard = new int[3][9];
Random rand = new Random();
for(int i = 0; i< lottoCard.length; i++){
for(int j = 0; j< 5; j++){
int x = rand.nextInt(89) + 1;
while(lottoCard[i][x / 10] !=0) {
x = rand.nextInt(89) + 1;
}
lottoCard[i][x / 10] = x;
}
}
}
public boolean guess(int row, int col, int number) {
if(lottoCard[row][col] == number) {
correctlyGuessed[row][col] = true;
return true;
}
return false;
}
public boolean hasLottoEnded() {
for(boolean[] arr:correctlyGuessed) {
for(boolean guess: arr) {
if(!guess) //if a guess is still false the game hasn't ended
return false;
}
}
return true;
}
public int getNumber(int row, int col) {
return lottoCard[row][col];
}
#Override
public String toString() {
StringBuilder sb = new StringBuilder();
for(int row = 0; row < lottoCard.length; row++) {
for(int col = 0; col < lottoCard[row].length; col++) {
if(correctlyGuessed[row][col])
sb.append(lottoCard[row][col] + " ");
else
sb.append("X ");
}
//spacing
sb.append("\n");
}
return sb.toString();
}
public static void main(String[] args) {
Lotto card = new Lotto();
Scanner sc = new Scanner(System.in);
while(!card.hasLottoEnded()) { //loop whilst the game hasn't ended
System.out.println("Row:");
int row = sc.nextInt();
System.out.println("Column:");
int col = sc.nextInt();
System.out.println("Number:");
int number = sc.nextInt();
if(card.guess(row, col, number))
System.out.println("You have guessed correctly!");
else
System.out.println("Wrong guess :(");
System.out.println(card);
}
System.out.println("You win!");
sc.close();
}
}

Merge sort recursion trouble

I've been trying to make a merge sort and I got the merging part down, it's just the recursive splitting that I'm having a little trouble with. The left and right lists are getting merged and sorted individually and not carrying over between each recursive pass. I'm not sure what I'm doing wrong with the recursion or how to fix it without scrapping the entire division method.
public static int[] mergeSort(int[] x)
{
divide(x);
return sorted;
}
public static void divide(int[] x)
{
int midP;
if((x.length/2f) == 1.5f) //the left side of the list will always be larger
midP = 2;
else
midP = x.length/2;
if(midP == 0) //if the list contains one number end
return;
System.out.println("mid: " + midP);
int[] left = new int[midP];
int[] right = new int[x.length - midP];
for(int i = 0; i < midP; i++) //fills the left list
left[i] = x[i];
for(int i = midP; i < x.length; i++) //fills the right list
right[i-midP] = x[i];
divide(left);
divide(right);
sorted = merge(left, right);
}
public static int[] merge(int[] x, int[] y)
{
int[] mergedList = new int[x.length + y.length];
int counter = 0, xCounter = 0, yCounter = 0, high = 0;
while(xCounter < x.length && yCounter < y.length)
{
printArray(x);
printArray(y);
System.out.println("checking: " + x[xCounter] + " " + y[yCounter]);
if(x[xCounter] < y[yCounter])
{
mergedList[counter] = x[xCounter];
high = y[yCounter];
if(xCounter != x.length)
xCounter++;
}
else
{
mergedList[counter] = y[yCounter];
high = x[xCounter];
if(yCounter != y.length)
yCounter++;
}
counter++;
}
mergedList[counter] = high;
return mergedList;
}
public static void printArray(int[] x)
{
System.out.print("list: ");
for(int i = 0; i < x.length; i++)
System.out.print(x[i] + " ");
System.out.println();
}
When using recursive methods, it's tricky to use static or instance variables like sorted in this case. What's happening is that sorted gets set and reset over the recursive calls, and it can be difficult to predict what its value will be at any given time. Recursive functions are easier to understand if you only use local variables. So change your divide function so that it returns the sorted array, and use the return value from the recursive calls:
public static int[] divide(int[] x) {
... your existing divide logic ...
int[] leftSorted = divide(left);
int[] rightSorted = divide(right);
return merge(leftSorted, rightSorted);
}
Don't forget to also change the main entry point:
public static int[] mergeSort(int[] x) {
return divide(x);
}
You seem to still have a bug in the merge method:
int[] x = {5, 4, 1, 2, 3};
int[] sorted = mergeSort(x);
results in 1 2 3 4 0

Pascal's triangle code failing after certain row

import java.util.*;
public class PascalFinal
{
public static void main()
{
Scanner f = new Scanner(System.in);
System.out.print("How many rows of Pascal's triangle do you want to print: ");
int row = f.nextInt();
Pascal(row);
showPascal(Pascal(row));
}
public static void showPascal(int[][] Pascal)
{
for(int a = 0; a < Pascal.length; a++)
{
for(int b = 0; b < Pascal[a].length; b++)
{
System.out.print(Pascal[a][b] + " ");
}
System.out.println();
}
}
public static int[][] Pascal(int x)
{
int[][] Pascal = new int[x][];
int rowLength = 1;
for(int a = 0; a < x; a++)
{
Pascal[a] = new int[rowLength];
rowLength++;
}
for(int a = 0; a < Pascal.length; a++)
{
for(int b = 0; b < Pascal[a].length; b++)
{
int Piscal = a-b;
Pascal[a][b] = Factorial(a)/Factorial(b)/Factorial(Piscal);
}
}
return Pascal;
}
public static int Factorial(int n)
{
if (n < 0)
{
int x = -1;
return x;
}
if (n == 0)
{
int x = 1;
return x;
}
else
{
return (n * Factorial(n - 1));
}
}
When I run that code, it works perfectly fine for the first 13 lines, however it then starts putting in weird values for the rest of the rows. My first though was that it could be due to the values getting too big from the factorial method and the int datatype not being able to hold it but I am not sure. No clue why this is getting messed up. Please help.
Edit: I tried using the long datatype instead of int, but the same issue occurs once I get past 20 rows.
If the Pascal's triangle that you have to draw is the one designed here
you do not need to evaluate any factorial.
Each row can be evaluated using the previous row with simple sums...
You can do it using an array. As a suggestion, start with the arrary: [0, 1, 0]
and remember that the next row can be evaluated doing a sum of the adjacent numbers of the previous row.
You need to loop over [0, 1, 0] and create [0,1,1,0] and then [0,1,2,1,0]
As you can see, the first is 0 and remains always 0, the next is the sum of the first two, and so on...

Arrays for Maze Algorithm not Storing Proper Values

I have everything down in my maze solver, except for the fact that the wasHere array is storing the solution (which is supposed to be stored by the correctPath array). It is also missing marking the end square of the maze. All the wasHere array is supposed to store are the spots that the program has gone to in the maze. The correctPath array has all false values, which is totally unexpected. I am using the recursive method mentioned in Wikipedia: https://en.wikipedia.org/wiki/Maze_solving_algorithm
This is my Maze Solver:
private static int[][] maze = {{2, 2, 2, 2, 1, 2, 2},
{2, 2, 2, 2, 1, 2, 2},
{2, 2, 2, 2, 1, 2, 2},
{2, 1, 1, 1, 1, 1, 1}}; // The maze
private static boolean[][] wasHere = new boolean[4][7];
private static boolean[][] correctPath = new boolean[4][7]; // Solution
private static int startX = 4;
private static int startY = 0;
private static int endX = 1;
private static int endY = 3;
public static void main(String[] args) {
System.out.println("Maze: ");
printMaze(maze);
solveMaze();
boolean b = recursiveSolve(startX, startY); // Whether or not there is a solution to the maze
}
public static void solveMaze()
{
for (int row = 0; row < maze.length; row++)
{
// Sets boolean arrays to false
for (int col = 0; col < maze[row].length; col++)
{
wasHere[row][col] = false;
correctPath[row][col] = false;
}
}
}
public static void printMaze(int[][] array)
{
for (int row = 0; row < array.length; row++)
{
for (int col = 0; col < array[row].length; col++)
{
System.out.print(array[row][col]);
if (col == array[row].length - 1)
{
System.out.print("\n");
}
}
}
System.out.print("\n");
}
public static void printPath(boolean[][] array)
{
for (int row = 0; row < array.length; row++)
{
for (int col = 0; col < array[row].length; col++)
{
if (array[row][col] == true)
{
System.out.print("1");
}
else
{
System.out.print("2");
}
if (col == array[row].length - 1)
{
System.out.print("\n");
}
}
}
}
public static boolean recursiveSolve(int x, int y)
{
if (x == endX && y == endY) // Reach end
{
System.out.println("The maze is solvable.");
printPath(wasHere);
return true;
}
if (maze[y][x] == 2 || wasHere[y][x] == true) // Hit a dead end or end up in same place (no solution)
{
return false;
}
wasHere[y][x] = true;
if (x != 0) // On left edge or not
{
if (recursiveSolve(x - 1, y))
{
correctPath[y][x] = true;
return true;
}
}
if (x != maze[0].length - 1) // On right edge or not
{
if (recursiveSolve(x + 1, y))
{
correctPath[y][x] = true;
return true;
}
}
if (y != 0) // On top edge or not
{
if (recursiveSolve(x, y - 1))
{
correctPath[y][x] = true;
return true;
}
}
if (y != maze.length - 1) // On bottom edge or not
{
if (recursiveSolve(x, y + 1))
{
correctPath[y][x] = true;
return true;
}
}
System.out.println("The maze is not solvable.");
return false;
}
Your maze solver is working correctly. The problem is that you were probably printing the values of the correctPath array before your recursive method had finished writing to it.
I assume that where you had the following lines inside the recursiveSolve(int x, int y) method:
System.out.println("The maze is solvable.");
printPath(wasHere);
... at some point, you tried to run it using the correctPath variable instead, right? Something like this?
System.out.println("The maze is solvable.");
printPath(correctPath);
But that is too soon. The correctPath array values are set after the recursive calls start returning from the end of the maze.
Instead, try moving the printPath call after the top level call to the recursiveSolve method inside your main(). Like this:
public static void main(String[] args) {
System.out.println("Maze: ");
printMaze(maze);
solveMaze();
boolean b = recursiveSolve(startX, startY); // Whether or not there is a solution to the maze
// Put this here! It will work as expected.
System.out.println();
printPath(correctPath);
}
If this doesn't quite make sense to you, then it probably means that you haven't quite grasped how recursion works. Use a debugger to step through your program, as you should have done in the first place, and things should become clearer.

Waffle Stacking Algorithm needs improvement

I am working on a problem called Waffle Stacking. I am aware that a question already exists but the post needed to know where to start but I already have most of it done. The problem can be seen here: http://www.hpcodewars.org/past/cw16/problems/Prob20--WaffleStacking.pdf
My algorithm calculates the 120 permutations (5!) of the String "12345". I then place then row by row and make sure that they match the side clues. Then I check if it so far matches the top side. (Meaning that I go through the tiles that I currently have and I find the tallest stack and I look for the unused stacks and check if they are higher than the current highest stack and then I can see if I use the unused stacks they will match the clue). Using the example, my algorithm is very flawed. It produces only 4 rows and only one is correct. I believe it is due to checking the column. Any help is apprectated with checking the top and bottom sides.
package HP2013;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Scanner;
public class WaffleStacking
{
public static String t[];
public static String l[];
public static String r[];
public static String b[];
public static void getInput()
{
try{
Scanner keyb = new Scanner(new File("src/HP2013/WaffleStacking.dat"));
t = keyb.nextLine().split(" ");
l = new String[5];
r = new String[5];
for (int i = 0; i < 5; i++)
{
String a[] = keyb.nextLine().split(" ");
l[i] = a[0];
r[i] = a[1];
}
b = keyb.nextLine().split(" ");
}
catch (IOException e)
{
e.printStackTrace();
}
}
public static ArrayList<String> perms = new ArrayList<String>();
public static void getPerms(String s)
{
getPerms("", s);
}
public static void getPerms(String pfx, String s)
{
int n = s.length();
if (n == 0)
perms.add(pfx);
else
{
for (int i = 0; i < s.length(); i++)
getPerms(pfx + s.charAt(i) + "", s.substring(0, i) + s.substring(i + 1));
}
}
public static void solve()
{
int mat[][] = new int[5][5];
for (int r = 0; r < 5; r++)
{
String row = "";
for (int p = 0; p < perms.size(); p++)
{
if (goodRow(perms.get(p), r))
{
row = perms.get(p);
for (int c = 0; c < row.length(); c++)
mat[r][c] = Integer.valueOf(row.charAt(c) + "");
if (uniqueCol(mat, r + 1) && goodCol(mat, r + 1))
break;
else
{
mat[r] = new int[] {0, 0, 0, 0, 0}.clone();
}
}
}
}
for (int m[] : mat)
System.out.println(Arrays.toString(m));
}
public static boolean uniqueCol(int mat[][], int rStop)
{
for (int c = 0; c < mat.length; c++)
{
ArrayList<Integer> col = new ArrayList<Integer>();
for (int r = 0; r < rStop; r++)
col.add(mat[r][c]);
Collections.sort(col);
for (int i = 0; i < col.size() - 1; i++)
if (col.get(i) == col.get(i + 1))
return false;
}
return true;
}
public static boolean goodRow(String row, int index)
{
int left = 0;
int max = -1;
for (int i = 0; i < row.length(); i++)
{
int stack = Integer.valueOf(row.charAt(i) + "");
if (stack > max)
{
left++;
max = stack;
}
}
int right = 0;
max = -1;
for (int i = row.length() - 1; i >= 0; i--)
{
int stack = Integer.valueOf(row.charAt(i) + "");
if (stack > max)
{
right++;
max = stack;
}
}
if (left == Integer.valueOf(l[index]) && right == Integer.valueOf(r[index]))
return true;
return false;
}
public static boolean goodCol(int mat[][], int rStop)
{
return checkTop(mat, rStop);
}
public static boolean checkTop(int mat[][], int rStop)
{
for (int c = 0; c < 5; c++)
{
int left = Integer.valueOf(t[c] + "");
int max = -1;
String used = "";
for (int r = 0; r < rStop; r++)
{
int stack = mat[r][c];
used += stack;
if (stack > max)
{
max = stack;
left--;
}
}
ArrayList<Integer> leftovers = new ArrayList<Integer>();
for (int n = 1; n <= 5; n++)
{
if (!used.contains(n + ""))
leftovers.add(n);
}
for (int j = 0; j < leftovers.size(); j++)
{
if (leftovers.get(j) > max)
{
max = leftovers.get(j);
left--;
}
}
if (left > 0)
return false;
}
return true;
}
public static void main(String args[])
{
getInput();
getPerms("12345");
solve();
}
}
Input:
2 2 3 2 1
4 1
1 4
3 2
2 2
3 2
3 2 1 3 4
Output:
[1, 3, 2, 4, 5]
[5, 1, 4, 3, 2]
[2, 4, 1, 5, 3]
[3, 2, 5, 1, 4]
[0, 0, 0, 0, 0]
So the first problem I see is no way to jump out when you've found a good answer. You're loops are probably continuing on after they've found the correct answer and unrolling to a point where you're losing the last row because of your else clause for a bad match.
Bottom side checking was not the problem, I overthought it; It should be very similar to top side checking. The solve method was very faulty and I switched to a recursive solution which ended up solving the problem. That way I can try several possibilities of valid rows while maintaining unique columns and then check if the columns were valid as well. If they weren't I can continue trying different possibilities.

Categories

Resources