Printing each step of a Tower of Hanoi using Arrays - java

I'm trying to print each step of a Tower of Hanoi using an array of objects. The objects I'm using are Pokemon objects with only a name. It does have other attributes that are irrelevant to this code. I'm using only the names to sort the Tower. The Array of Pokemon objects is sorted by alphabetical order using this code below:
for ( int i = 0; i<pokemon.length;i++){
for ( int j = i+1; j<pokemon.length; j++){
if ( (pokemon[j].getName().compareTo(pokemon[i].getName())<0)){
String temp = pokemon[i].getName();
pokemon[i].setName(pokemon[j].getName());
pokemon[j].setName(temp);
}
}
}
After the array is properly sorted, I then created this print method to display the Tower of Hanoi process happening.
static public void printArray(int n, Pokemon[] a, Pokemon[] b, Pokemon[] c) {
String slot1 = "";
String slot2 = "";
String slot3 = "";
System.out.println("A\t\tB\t\tC");
for (int i = 0; i < n; i++) {
if (!a[i].getName().equals("")) {
slot1 = a[i].getName();
if (!b[i].getName().equals("")) {
slot2 = b[i].getName();
if (!c[i].getName().equals("")) {
slot3 = c[i].getName();
} else
slot3 = "";
} else
slot2 = "";
} else
slot1 = "";
System.out.println(slot1 + "\t\t" + slot2 + "\t\t" + slot3);
}
}
I understand that using \t to format is a poor choice, but for debugging purposes this is functional for now, I hope to convert it to printf for a better format. The purpose of this printArray method is to print the A B C array's from a top down view.
For every element in the array that does not have a name, i.e. it was never set to anything, it does not print it. This way it only prints the 'action' that is happening. I've verified this by using setName with both random Strings and empty Strings("") to see if it printed correctly, it does.
Next I decided to take a stab at the actual recursion method itself and ended up with this mess
static public void Hanoi(int n, Pokemon[] a, Pokemon[] b, Pokemon[] c){
int a1 =n;
int b1 =n-1;
int c1 =n-1;
for ( int i = 0; i < n;i++){
if ( !a[i].getName().equals("")){
a1--;
}
if ( !b[i].getName().equals("")){
b1--;
}
if ( !c[i].getName().equals("")){
c1--;
}
}
if ( n > 0 ){
printArray(n, a, b,c);
Hanoi(n-1, a, c, b);
c[c1].setName(a[a1].getName());CC
a[a1].setName("");
Hanoi(n-1,b, a, c);
System.out.println("\n\n\n");
}
}
N is the number the user enters ( 'Numbers of disks' )
I should also comment this but I tend to want to make sure my program works before commenting and having everything get messy. The point of the if statements is to decrement the index counters for each individual array (A,B,C) if there is a name already in the array. The higher the index means the bottom of the stack, literally.
I'm fairly lost now and have no idea what to be checking but I'm doing what I can with little bugtests but if anyone has had experience with this and give me some advice or point something out, I would appreciate it!
Note: I'm a student studying OOP right now so my tools are limited to what we have already learned, therefore I'm trying to do this with what I already know, Arrays to handle the Tower of Hanoi Recursive Method.
EDIT: Sorry, it was late at night and I was extremely tired and not thinking clearly to post a logical question. The issue I'm having is tracing back my logic. I get confused when I get to the recursive function calls.
If I enter a 3, the most simple of Tower of Hanoi problems, then I get this sample output
3
A B C
Bulbasaur
Pikachu
Squirtle
A B C
Bulbasaur
Pikachu
A B C
Bulbasaur
The method call is
Hanoi(3,pokemon,b,c)
Tracing back the logic I end up with a1 = 0, b1, = 2, and c1 = 2, which corresponds with the first print for all the indexes
A B C
Bulbasaur
Pikachu
Squirtle
This is where I get confused , when I call the Hanoi(n-1,a,c,b) does the code end up printing 2 times before the outermost loop is finished? If so, I can't decide where to put the print statement because I need the output to only print once every time something changes.
For the regular Tower of Hanoi I think I understand the print line
System.out.println("Moving a stack from", A, C)
However when dealing with Arrays I need to set a value somewhere into the C array and remove a value from the A array, effectively causing a "move", which I have in the lines
c[c1].setName(a[a1].getName());
a[a1].setName("");
If this logic happens after the recursive function call, does that mean that it resolves the innermost loop first? So when n = 1? At this point I'm completely lost because I know that calling the recursive function with
Hanoi(n-1,a,c,b)
means that everytime it does the destination and auxilary array are being switched around, I can't wrap my head around this. Where do I use the print statements. How does the recursive function calls affect my shifting of the disks, is there a better way to deal with Tower of Hanoi with Arrays then using individual indexes to keep track of each Array, because it seems to not work after the Arrays are switched from their original position.

Related

JAVA seperate class method not incrementing a variable in my main class method

so this is the main code for my text-based game.
import java.util.Scanner;
public class D_M_RPG {
public static void main(String[] args) {
//Creating the class to call on my toolbox
D_M_RPGtoolbox toolbox = new D_M_RPGtoolbox();
//Creating the scanner class for user input
Scanner input = new Scanner(System.in);
//Initiating variables and final variables aswell as arrays
//token variable to validate open spots in an array
int slotCounter = 0;
int inventoryExpander = 11;
//First initiated will be the character creation variables
String hairColor = "";
String eyeColor = "";
String skinColor = "";
String gender = "";
//Initiating the arrays for character inventory slots
String[] weaponSlots = new String[10];
//initiating the arrays for the character creation
String[] hairColorARR = {"black","Green","Yellow","Brown","Blue","Blonde","Grey","White"};
String[] eyeColorARR = {"Green","Brown","Blue","Grey",};
String[] skinColorARR = {"White","brown","Black",};
String[] genderARR = {"Male","Female"};
//Creating the introduction title and introduction
System.out.println("Welcome to, COLD OMEN.");
System.out.println("\nNOVEMBER 12th, 2150: ONTARIO, CANADA");
System.out.println("\nYou hear loud shouts and gun fire all around you but can't pinpoint the location of anything, you feel a bit dazed until someone grabs you and you open your eyes and snap out of it.");
System.out.println("\nUnknown: 'Get up, its time to move out. Take this.'");
System.out.println("\nUnknown hands you a 'M4-A4 RIFLE'");
System.out.println("\nyou manage to catch a small glimpse of him before you get up.");
//Character creation screen
System.out.println();
//ONLY WORKS ONCE WONT INCREMEMENT THE SLOTCOUNTER
toolbox.insert(weaponSlots, slotCounter, inventoryExpander, "M4-A4 RIFLE");
System.out.println("\n" + weaponSlots[0]);
toolbox.insert(weaponSlots, slotCounter, inventoryExpander, "ak47");
System.out.println(weaponSlots[0]);
}
}
so I have this method I made to basically add an "item" to the weaponSlots array (the inventory) but whenever I run it it will add to the first element in the array [0] but it wont incremement the slotcounter which should go up by one every time the method is used so that I dont replace any items in the array It should just add items until its full which is checked using the inventoryExpander variable. at the moment I have it printing the element at 0 and 0 for the array but i have checked 1 aswell and 1 is just null no item added it only just replaces the element at 0. heres the code for the method to increment etc:
public class D_M_RPGtoolbox {
//method for random number generating to be used for crit hits, turns, loot generation etc
public int randomGen(){
int x = (int) (Math.random()*((20-0)+1)+0);
return x;
}
//method for inserting into an array ONLY WORKS ONCE WONT INCREMEMENT THE SLOTCOUNTER FIX
public void insert(String[] a, int b, int d , String c) {
if(b < d) {
a[b] = c;
b++;
}//end of if statement
}//end of method
}
What you are actually performing the ++ operation on in b is a copy of the value in slotCounter.
The variable slotCounter is passed into insert "by-value".
This unlike what you probably imagine, that it is passed "by-reference".
One solution would be to do the slotCounter++ from the call row instead; and another would be to let the toolbox own the slotCounter variable completely.
This question uses the image of passing a copy of document content (by value) where changes to the document would not be seen by the sender; or as a link to a shared document (by reference), where changes could be made to the same page that the sender sees.
Its always going to be zero since you are passing zero and incrementing the local variable b.
Try calling the method as below with post increment ++ to slotCounter and see if it works for you,
toolbox.insert(weaponSlots, slotCounter++, inventoryExpander, "M4-A4 RIFLE");

ArrayLinkedList Insertion Sort

I have to do an Array List for an insertion sort and my teacher sent this back to me and gave me an F, but says I can make it up before Friday.
I do not understand why this isn't an A.L insertion sort.
Can someone help me fix this so it hits his criteria?
Thanks.
HE SAID:
After checking your first insertion sort you all did it incorrectly. I specifically said to shift the numbers and move the number into its proper place and NOT SWAP THE NUMBER INTO PLACE. In the assignment in MySA I said if you do this you will get a 0 for the assignment.
import java.util.ArrayList;
public class AListINSSORT {
private static void insertionSort(ArrayList<Integer> arr) {
insertionSort();
}
private static void insertionSort() {
ArrayList<Integer> swap = new ArrayList<Integer>();
swap.add(1);
swap.add(2);
swap.add(3);
swap.add(4);
swap.add(5);
int prior = 0;
int latter = 0;
for (int i = 2; i <= latter; i++)
{
for (int k = i; k > prior && (swap.get(k - 1) < swap.get(k - 2)); k--)
{
Integer temp = swap.get(k - 2);
swap.set(k - 2, swap.get(k - 1));
swap.set(k - 1, temp);
}
}
System.out.println(swap);
}
}
First of all, it seems your teacher asked you to use a LinkedList instead of an ArrayList. There is quite a difference between them.
Secondly, and maybe more to the point. In your inner loop you are saving a temp variable and swapping the elements at position k - 2 and k - 1 with each other. From the commentary this is not what your teacher intended. Since he wants you to solve the problem with element insertion, I recommend you look at the following method definition of LinkedList.add(int i, E e): https://docs.oracle.com/javase/7/docs/api/java/util/LinkedList.html#add(int,%20E).
This should point you in the right direction.
As far as I see, your code does nothing at all.
The condition of the outer for loop
for (int i = 2; i <= latter; i++)
is not fulfilled.
As you start with i = 2 and as latter = 0, it never holds i <= latter.
Thus, you never run through the outer for loop and finally just give back the input values.
If you add the input values to swap in a different order (not already ordered), you will see that your code does not re-order them.
There's a lot of stuff wrong here.
Firstly, your method:
private static void insertionSort(ArrayList<Integer> arr) {
insertionSort();
}
takes an ArrayList and completely ignores it. This should presumably be the List which requires sorting.
Then in insertionSort() you create a new ArrayList, insert some numbers already in order, and then attempt something which looks nothing like insertion sort, but slightly more like bubble sort.
So, when you call insertionSort(List) it won't actually do anything to the list at all, all the work in insertionSort() happens to a completely different List!
Since on SO we don't generally do people's homework for them, I suggest looking at the nice little animated diagram on this page
What you should have then is something like:
public void insertionSort(LinkedList<Integer> numbers) {
//do stuff with numbers, using get() and add()
}

Remove an object n times from array list in JAVA

Alright, I'm making a method that should be able to remove objects from an array list through the use of a string input.
Say I want to remove the following numbers: {1,2,4,3,3,1} from an arraylist. How can I ensure that it only removes 1 & 3 twice and 4 & 2 once?
What I have is:
mv.displayMessages("choosedicestokeep");
String in = mv.getInput();
for (char c : in.toCharArray()) {
int x = Character.getNumericValue(c);
for (Iterator<Integer> it = rollingHand.iterator(); it.hasNext(); ){
int i = it.next();
if (x == i) {
finalHand[finalArrIndex] = i;
it.remove();
finalArrIndex++;
}
}
}
But this checks the arraylist "RollingHand" and removes ALL instances of a number and not the number of times I write a number which is what I want.
So if i enter {1,1,1,2,2,4} it should remove three 1s, two 2s and one 4.
https://stackoverflow.com/users/4584292/mike Solved the obvious answer.
Breaking to a statement outside the inner loop solved the problem.
The method doesn't return anything because it sets a private int[] finalHand in the class which is later accessed by other methods.
All cred to Mike!

How to breakdown a method and process it [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I am preparing for an exam next week, and I decided to look for some exam questions online for better preparation.
I came across this question and the answer is c. But I really want to know how or the step by step process to answer to answer a question like this. The part where I got stuck is trying to logically understand how a int m = mystery(n); How can a number equal a method? Whenever I get to a question like this is their anything important I should breakdown first?
private int[] myStuff;
/** Precondition : myStuff contains int values in no particular order.
/*/
public int mystery(int num)
{
for (int k = myStuff.length - 1; k >= 0; k--)
{
if (myStuff[k] < num)
{
return k;
}
}
return -1;
}
Which of the following best describes the contents of myStuff after the
following statement has been executed?
int m = mystery(n);
(a) All values in positions 0 through m are less than n.
(b) All values in positions m+1 through myStuff.length-1 are
less than n.
(c) All values in positions m+1 through myStuff.length-1 are
greater than or equal to n.
(d) The smallest value is at position m.
(e) The largest value that is smaller than n is at position m.
See this page to understand a method syntax
http://www.tutorialspoint.com/java/java_methods.htm
int m = mystery(n); means this method going to return int value and you are assigning that value to a int variable m. So your final result is m. the loop will run from the array's end position to 0. loop will break down when array's current position value is less than your parameter n. on that point it will return the loop's current position. s o now m=current loop position. If all the values of the loop is greater than n it will return -1 because if condition always fails.
Place the sample code into a Java IDE such as Eclipse, Netbeans or IntelliJ and then step through the code in the debugger in one of those environments.
Given that you are starting out I will give you the remainder of the code that you need to make this compile and run
public class MysteriousAlright {
private int[] myStuff;
public int mystery(int num)
{
for (int k = myStuff.length - 1; k >= 0; k--) {
if (myStuff[k] < num) {
return k;
}
}
return -1;
}
public static void main(String[] args) {
MysteriousAlright ma = new MysteriousAlright();
ma.setMyStuff(new int[] {4,5,6,7});
int m = ma.mystery(5);
System.out.println("I called ma.mystery(5) and now m is set to " + m);
m = ma.mystery(3);
System.out.println("I called ma.mystery(3) and now m is set to " + m);
m = ma.mystery(12);
System.out.println("I called ma.mystery(12) and now m is set to " + m);
}
public void setMyStuff(int[] myStuff) {
this.myStuff = myStuff;
}
}
You then need to learn how to use the debugger and/or write simple Unit Tests.
Stepping through the code a line at a time and watching the values of the variables change will help you in this learning context.
Here are two strategies that you can use to breakdown nonsense code like that which you have sadly encountered in this "educational" context.
Black Box examination Strategy
Temporarily ignore the logic in the mystery function, we treat the function as a black box that we cannot see into.
Look at what data gets passed in, what data is returned.
So for the member function called mystery we have
What goes in? : int num
What gets returned : an int, so a whole number.
There are two places where data is returned.
Sometimes it returns k
Sometimes it returns -1
Now we move on.
White Box examination Strategy
As the code is poorly written, a black box examination is insufficient to interpret its purpose.
A white box reading takes examines the member function's internal logic (In this case, pretty much the for loop)
The for loop visits every element in the array called myStuff, starting at the end of the array
k is the number that tracks the position of the visited element of the array. (Note we count down from the end of the array to 0)
If the number stored at the visited element is less than num (which is passed in) then return the position of that element..
If none of elements of the array are less than num then return -1
So mystery reports on the first position of the element in the array (starting from the end of the array) where num is bigger than that element.
do you understand what a method is ?
this is pretty basic, the method mystery receives an int as a parameter and returns an int when you call it.
meaning, the variable m will be assigned the value that returns from the method mystery after you call it with n which is an int of some value.
"The part where I got stuck is trying to logically understand how a int m = mystery(n); How can a number equal a method?"
A method may or may not return a value. One that doesn't return a value has a return type of void. A method can return a primitive value (like in your case int) or an object of any class. The name of the return type can be any of the eight primitive types defined in Java, the name of any class, or an interface.
If a method doesn't return a value, you can't assign the result of that method to a variable.
If a method returns a value, the calling method may or may not bother to store the returned value from a method in a variable.

Counting in recursion calls

I need to write a method that checks how many possible ways there are to finish a grid (a 2D array).
the movement inside the grid is like this:
start with [0][0] take the number inside there (for instance 14) then go to either
[array.[0][0]%10][array.[0][0]/10] or [array.[0][0]/10][array.[0][0]%10]
for our example:
[1][4] or [4][1]
until you get to the end of the array (bottom right corner).
I can get to the end of the array (all possible ways) - my problem is to count how many times I actually finished the array - I can not use a variable outside of the method, and the method has to be recursive.
this is the code :
private static int howMany(int[][] array, int y, int x, int count) {
if(y+(array[y][x]%10) < array.length && x+(array[y][x]/10)< array[y].length && array[y][x]!=0) {
System.out.println("["+y+"]["+x+"] is: "+array[y][x]);
howMany(array, y+(array[y][x]%10), x+(array[y][x]/10),count);
}
if(y+(array[y][x]/10) < array.length && x+(array[y][x]%10)< array[y].length && array[y][x]!=0) {
System.out.println("["+y+"]["+x+"] is: "+array[y][x]);
howMany(array, y+(array[y][x]/10), x+(array[y][x]%10),count);
}
if(y==array.length-1 && x==array[y].length-1) count++;
return count;
}
this is obviously wrong and will return what count was in the first place, I tried many other ways but to no avail...
here's the full class (with an array to test):
link to full class
edit: a big Thanks to everyone for their help!
The count is already returned from each call to howMany. I think you just need to save it:
count = howMany(array, y + (array[y][x] % 10), x + (array[y][x] / 10), count);
Do this inside both if blocks. I made this change in your linked code and got the expected result (3).
You are already on the right track, since your method signature returns an int. You should define a variable to hold the count, increment it for the primary recursive call, and add to it the result of the recursive method itself. Passing the count into the each recursive call is unnecessary and should be removed.
Return 1 if you've reached the end of the array (bottom right corner) and 1+howMany(array, newY, newX) otherwise. You don't need to keep the count and pass it every time. The function will work so:
1 + returned value of 2nd call =
1 + 1 + returned value of 3rd call =
1 + 1 + 1 + returned value of 4th call =... and so on.
Finally as result you'll get number of calls which is what you want.

Categories