Tower of Hanoi using 2D arrays issue - java

I'm working on a Tower of Hanoi project for school which needs to ask the user how many disks there are and then it needs to create and then solve the tower with a visual included. How I decided to do it is by using 2D arrays and for the most part its working, my only problem is that I don't know how to move the disks while keeping it modular. Here is my code.
public static void main(String[] args)
{
Scanner scan = new Scanner(System.in);
System.out.println("Enter number of disks");
int num = scan.nextInt();
int temp = num-(num-1);
int measure = num;
//initializing the towers
int[][] towers = new int[num][num];
for(int i = 0 ; i < num; i++)
{
for(int j=0; j <3; j++)
{
}
}
createRings(towers, num, temp);
moveDisk(towers,num);
}
// creating the rings
private static void createRings (int[][]towers, int num, int temp)
{
for(int i = 0; i<num; i++)
{
for(int j=0; j<3;j++)
{
towers[i][0] = temp;
}
temp = temp+1;
}
displayTower(towers, num);
}
// prints the array for display purposes
private static void displayTower (int[][] towers, int num)
{
for(int i = 0; i<num; i++)
{
for(int j = 0; j<3; j++)
{
System.out.print(towers[i][j]+"\t");
}
System.out.println();
}
}
//moves the numbers in the array that represents disks
private static void moveDisk(int[][]towers, int num)
{
System.out.println();
displayTower(towers, num);
}
Does anyone have any suggestions on what I could do?

I've changed your code a bit to make it more readable for me.
I changed the towers array. Now each tower is its own array inside the towers array (makes more sense IMHO).
Arrays in Java know their size. So you don't have to pass the length of the array as a parameter to every method.
I added a method getHighestIdx() which returns the index before the first 0 value in the array
I don't know, how the function moveDisk() was intended to work. I changed the declaration so that it makes sense to me. It now moves a disk from tower i to tower j
This should help you to implement the algorithm from the linked question.
Here is the changed code:
public static void main(String[] args) {
int numberOfRings = 6;
int[][] towers = new int[3][numberOfRings];
createRings(towers);
displayTowers(towers);
moveDisk(towers, 0, 2);
displayTowers(towers);
}
private static void createRings(int[][] towers) {
for (int j = 0; j < towers[0].length; j++) {
towers[0][j] = j + 1;
}
}
private static void displayTowers(int[][] towers) {
for (int i = 0; i < towers[0].length; i++) {
for (int j = 0; j < towers.length; j++) {
System.out.print(towers[j][i] + " ");
}
System.out.println("");
}
}
private static void moveDisk(int[][] towers, int fromIdx, int toIdx) {
int valToMove = towers[fromIdx][getHighestIdx(towers[fromIdx])];
towers[fromIdx][getHighestIdx(towers[fromIdx])] = 0;
towers[toIdx][getHighestIdx(towers[toIdx]) + 1] = valToMove;
}
private static int getHighestIdx(int[] tower) {
int i = 0;
while (i < tower.length && tower[i] != 0) {
i++;
}
return i - 1;
}

Related

How do i fix my interpretation of this run-length encoding algorithm?

For school, i have to build myself a method in java that compresses an array using RLE(run-length encoding). I can't find a solution online because my teacher wants me to solve the problem myself. I, unfortunately, cannot do this for i am a busy man with some busy plans.
RLE turns this: {1,1,1,1,2,2,3,3,6,6,6,7,8,8,8}
into this: {4,1,2,2,2,3,3,6,1,7,3,8}
it basically makes a new array that follows this formula {# of this value, this value, # of this value, this value, cont...} there are 4 1's so {4,1} you get my drift.
Here is what i tried to do(forgive me for my crappy code, i am merely a high school student):
public class tester{
public static void main(String[] args){
int[] potato = {1,1,1,2,2,4,4,4,6,6,6,6};
printArray(compress(potato));
}
public static void printArray(int[] arr){
for(int i = 0; i < arr.length; i++){
System.out.println(arr[i]);
}
}
public static int[] compress(int[] a) {
//figure out how many different numbers there are.
int diffNums = 1;
for(int i = 0; i < a.length; i++){
if(i != a.length-1 && a[i] != a[i+1]){
diffNums++;
}
}
//make compressed array at the correct length.
int[] compressed = new int[diffNums * 2];
//figure out what each number is.
int[] nums = new int[diffNums];
nums[0] = a[0];
int spot = 0;
for(int i = 0; i < a.length; i++){
if(i != a.length-1 && a[i] != a[i+1]){
nums[spot] = a[i+1];
}
}
//figure out quantity of each number.
int[] quantities = new int[diffNums];
int spot2 = 0;
int spotcur = 0;
for(int i = 0; i < diffNums; i++){
int quant = 0;
while(a[spotcur] == a[spot2]){
quant++;
spotcur++;
}
spot2 = spotcur;
quantities[i] = quant;
}
//add them together and return compressed array
int spotter = 0;
for(int i = 0; i < diffNums; i++){
compressed[spotter] = quantities[i];
spotter++;
compressed[spotter] = nums[i];
spotter++;
}
return compressed;
}
}
Does anyone know how i can fix this crappy code? i am stuck on it
I think this problem could be solved with a lot less code. You could use an outer/inner loop construct something like the following:
public static int[] compress(int[] a) {
List<Integer> encoded = new ArrayList<>();
for (int i=0; i<a.length; i++) {
int num = a[i];
int count = 1;
for (int j=i+1; j<a.length; j++) {
int nextNum = a[j];
if (nextNum != num)
break;
count++;
i++;
}
encoded.add(count);
encoded.add(num);
}
return encoded.stream().mapToInt(i->i).toArray();
}
Also, the Arrays class contains a useful toString method already defined.
System.out.println(Arrays.toString(compress(potato)));

Freeman Chain Code in Java

Okay, hopefully this makes more sense. I have an array hard coded with only 1s and 0s. I am trying to write a function that reads each element to see if it is a 0 or 1. If it is a 1, it will execute another function and then change that 1 to a 0 so that it is not read again. I have it printing simply as a placeholder for the other function I will be implementing later. I'm having trouble getting the findfirst1 function to check every element in the array. I have tried putting the incrementors for i and k in different places within the flow of the code but nothing I have tried gets me the correct output.
public static void main(String[] args)
{
int[][] testarray = {{1,0,0,0,0,0,0,1},{0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0},{1,0,0,0,0,0,0,1}};
findfirst1(testarray);
}
public static void findfirst1(int[][] array1)
{
int value = 0;
for(int i = 0; i < 6;i++)
{
for(int k = 0; k < 7;k++)
{
value = array1[i][k];
if(value == 1)
{
System.out.println(value);
array1[i][k] = 0;
}
else
{
System.out.println(value);
}
}
}
}
Okay, so after starting completely over and writing it all from scratch I figured it out. The array.length was right all along. I had trouble wrapping my head around it because I was so focused on the idea of the "image".
Edit: I just found an error where it wouldn't print the last line for array1, so I just added an extra row of 0s and it worked.
public class ChainCodeClass {
public static void main(String[] args)
{
int[][] array1 = {{0,1,0,0,0,0,0,0},{0,1,0,0,0,1,0,0},{0,1,1,1,0,0,1,0},
{0,0,0,1,1,0,0,1},{0,0,0,0,1,0,0,1},{0,0,0,0,0,1,0,0},
{0,0,0,0,0,0,1,0}**,{0,0,0,0,0,0,0,0}**};
int[][] array2 = {{0,0,0,0,0,0,0,0},{0,1,1,1,1,0,1,0},{0,0,0,0,1,0,1,0},
{0,0,1,1,1,0,1,0},{0,0,1,0,0,0,1,0},{0,0,1,0,0,0,1,0},{0,0,0,0,0,0,1,1},
{0,0,0,0,0,0,0,0}};
System.out.print("First Image");
print(array1);
findfirst1(array1);
print(array1);
System.out.print("Second Image");
print(array2);
outline8(array2);
}
public static void findfirst1(int[][] array)
{
int value = 0;
for(int i = 0; i < array.length; i++)
{
for(int k = 0; k < array.length; k++)
{
value = array[i][k];
if(value == 1)
{
System.out.print(value + " ");
array[i][k] = 0;
}
else
{
System.out.println(value);
}
}
}
}
public static void print(int[][] array)
{
for(int i = 0; i < array.length; i++) // print function for the array using incrementors
{
System.out.print("\n");
for(int k = 0; k < array.length; k++)
{
System.out.print(array[i][k] + " ");
}
}
System.out.println();
}
}

Java set/setElementAt not setting the right value

I need to find all the permutations for a given n(user input) without backtracking.
What i tried is:
import java.util.Scanner;
import java.util.Vector;
class Main {
private static int n;
private static Vector<Vector<Integer>> permutations = new Vector<>();
private static void get_n() {
Scanner user = new Scanner(System.in);
System.out.print("n = ");
n = user.nextInt();
}
private static void display(Vector<Vector<Integer>> permutations) {
for (int i = 0; i < factorial(n) - 1; ++i) {
for (int j = 0; j < n; ++j) {
System.out.print(permutations.elementAt(i).elementAt(j) + " ");
}
System.out.println();
}
}
private static int factorial(int n) {
int result = 1;
for (int i = 1; i <= n; ++i) {
result *= i;
}
return result;
}
private static int max(Vector<Integer> permutation) {
int max = permutation.elementAt(0);
for (int i = 1; i < permutation.size(); ++i)
if (permutation.elementAt(i) > max)
max = permutation.elementAt(i);
return max;
}
// CHECKS FOR ELEMENT COUNT AND 0 - (n-1) APPARITION
public static int validate_permutation(Vector<Integer> permutation) {
// GOOD NUMBER OF ELEMENTS
if (max(permutation) != permutation.size() - 1)
return 0;
// PROPER ELEMENTS APPEAR
for (int i = 0; i < permutation.size(); ++i)
if (!permutation.contains(i))
return 0;
return 1;
}
private static Vector<Integer> next_permutation(Vector<Integer> permutation) {
int i;
do {
i = 1;
// INCREMENT LAST ELEMENT
permutation.set(permutation.size() - i, permutation.elementAt(permutation.size() - i) + 1);
// IN A P(n-1) PERMUTATION FOUND n. "OVERFLOW"
while (permutation.elementAt(permutation.size() - i) == permutation.size()) {
// RESET CURRENT POSITION
permutation.set(permutation.size() - i, 0);
// INCREMENT THE NEXT ONE
++i;
permutation.set(permutation.size() - i, permutation.elementAt(permutation.size() - i) + 1);
}
} while (validate_permutation(permutation) == 0);
// OUTPUT
System.out.print("output of next_permutation:\t\t");
for (int j = 0; j < permutation.size(); ++j)
System.out.print(permutation.elementAt(j) + " ");
System.out.println();
return permutation;
}
private static Vector<Vector<Integer>> permutations_of(int n) {
Vector<Vector<Integer>> permutations = new Vector<>();
// INITIALIZE PERMUTATION SET WITH 0
for (int i = 0; i < factorial(n); ++i) {
permutations.addElement(new Vector<>());
for(int j = 0; j < n; ++j)
permutations.elementAt(i).addElement(0);
}
for (int i = 0; i < n; ++i)
permutations.elementAt(0).set(i, i);
for (int i = 1; i < factorial(n); ++i) {
// ADD THE NEXT PERMUTATION TO THE SET
permutations.setElementAt(next_permutation(permutations.elementAt(i - 1)), i);
System.out.print("values set by permutations_of:\t");
for (int j = 0; j < permutations.elementAt(i).size(); ++j)
System.out.print(permutations.elementAt(i).elementAt(j) + " ");
System.out.println("\n");
}
System.out.print("\nFinal output of permutations_of:\n\n");
display(permutations);
return permutations;
}
public static void main(String[] args) {
get_n();
permutations.addAll(permutations_of(n));
}
}
Now, the problem is obvious when running the code. next_permutation outputs the correct permutations when called, the values are set correctly to the corresponding the vector of permutations, but the end result is a mass copy of the last permutation, which leads me to believe that every time a new permutation is outputted by next_permutation and set into the permutations vector, somehow that permutation is also copied over all of the other permutations. And I can't figure out why for the life of me.
I tried both set, setElementAt, and an implementation where I don't initialize the permutations vector fist, but add the permutations as they are outputted by next_permutation with add() and I hit the exact same problem. Is there some weird way in which Java handles memory? Or what would be the cause of this?
Thank you in advance!
permutations.setElementAt(next_permutation(permutations.elementAt(i - 1)), i);
This is literally setting the vector at permutations(i) to be the same object as permutations[i-1]. Not the same value - the exact same object. I think this the source of your problems. You instead need to copy the values in the vector.

How to print a matrix in clockwise order

There is matrix for [x][y] order. i want to print its value in clockwise order
I have tried several methods but unable to write the logic of the code. I'm trying it in java but logic is important so you can help me in any language.
When I read your post I've started to play so I'll post you my code maybe it will be halpful for you. I've did it for square if you want for rectangle one need separate stepX and stepY. SIZE would be input parameter in your case, I have it final static for test.
public class clockwise {
private static final int SIZE = 3;
public static void main(String[] args) {
// int[][] test_matrix = {{1,2,3,4},{5,6,7,8},{9,10,11,12},{13,14,15,16}};
int[][] test_matrix = {{1,2,3},{5,6,7},{9,10,11}};
int[][] direction = {{1, 0},{0, 1},{-1, 0},{0, -1}}; //{x,y}
for(int i = 0; i < SIZE; i++) {
for(int j = 0; j < SIZE; j++)
System.out.print(test_matrix[i][j] + " ");
System.out.println("");
}
int x = 0;
int y = 0;
int directionMove = 0;
int stepSize = SIZE;
boolean changeStep = true;
int stepCounter = 0;
for(int i = 0; i < SIZE*SIZE; i++) {
System.out.print(test_matrix[x][y] + " ");
stepCounter++;
if (stepCounter % stepSize == 0) {
directionMove++;
directionMove = directionMove%4;
if(changeStep) { //after first edge one need to decrees step after passing two edges
stepSize--;
changeStep = false;
} else {
changeStep = true;
}
stepCounter = 0;
}
x += direction[directionMove][0];
y += direction[directionMove][1];
}
}
}

two quick fix issues - Merge Sort

I have created my version of the merge sort algorithm in java code. My issues are these: when I run the code as is, I get a NullPointerExecpetion in the main on line 27 (see commented line). And I know there is way to make the method calls and instantiate newArray without them being static but Im not quite sure how.. can someone help fix these? I am still relatively new to java so be nice :)
Main:
import java.util.Random;
public class MergeSort_main
{
public static void main(String[] args)
{
int[] originalArray = new int[1000];
Random rand = new Random();
for (int i = 0; i < originalArray.length; i++)
{
int randNum = rand.nextInt(1000)+1;
originalArray[i] = randNum;
}
for(int i = 0; i < originalArray.length; i++)
{
System.out.println(i+"." + originalArray[i]);
}
System.out.println("---------------------End Random Array-------\n");
MergeSortAlgorithm.mergeSortAlg(originalArray);
int[] sortedArray = MergeSortAlgorithm.getSortedArray();
for(int i = 0; i < sortedArray.length; i++) //NULL POINTER EXCEPTION HERE
{
System.out.println(i+ "." + sortedArray[i]);
}
}
}
Algorithm Class:
public class MergeSortAlgorithm
{
private static int[] newArray;
public static void mergeSortAlg(int[] randomNums)
{
int size = randomNums.length;
if (size < 2)
{
return; //if the array can not be split up further, stop attempting to split.
}
int half = size / 2;
int firstHalfNums = half;
int secondHalfNums = size - half;
int[] firstArray = new int[firstHalfNums];
int[] secondArray = new int[secondHalfNums];
for (int i = 0; i < half; i++)
{
firstArray[i] = randomNums[i];
}
for (int i = half; i < size; i++)
{
secondArray[i - half] = randomNums[i];
}
mergeSortAlg(firstArray);
mergeSortAlg(secondArray);
merge(firstArray, secondArray, randomNums);
}
public static void merge(int[] firstArray, int[] secondArray, int[] newArray)
{
int firstHalfNums = firstArray.length;
int secondHalfNums = secondArray.length;
int i = 0; //iterator for firstArray
int j = 0; //iterator for second array
int k = 0; //interator for randomNums array
while (i < firstHalfNums && j < secondHalfNums)
{
if (firstArray[i] <= secondArray[j])
{
newArray[k] = firstArray[i];
i++;
k++;
}
else
{
newArray[k] = secondArray[j];
k++;
j++;
}
}
while (i < firstHalfNums)
{
newArray[k] = firstArray[i];
k++;
i++;
}
while (j < firstHalfNums)
{
newArray[k] = secondArray[j];
k++;
j++;
}
}
public static int[] getSortedArray()
{
return newArray;
}
}
Basically, the only problem with your code is that you don't initialize newArray with any values, resulting in a null.
You are also redefining newArray at the top of your merge function .
The problem is that newArray[] is never instantiated i.e. newArray reference is pointing to null. And, no change is made in the newArray so value or reference returned to main is null. And, then you are performing sortedArray.length where sorted array having a null value.
You have to make newArray[] point to randomNums[].

Categories