Replicating the sleight of hand Trick Oil and Water - java

Note: I haven't found an answer to this particular question.
Backstory:
I recently learned the Oil and Water routine that magician's use in sleight of hand (this doesn't mean I can actually do it, but I have the mechanics done). For those that are unfamiliar with this routine, it takes three red cards and three black cards. These cards are initially put together red, black, red, black, red, black. By the end of the trick, all the reds are back together and all the blacks are back together.
I have successfully coded this in Java, but I am at a loss as to explain why it is doing it correctly. I think there is a problem with my logic I am sure, but I need some verification.
Here is the code I currently have:
int[] mixed = {1,2,1,2,1,2};
System.out.println("Before Sort: ");
for (int element : mixed){
System.out.println("Element: " + element);
}
for (int element : mixed){//this for loop moves all but the first and last element.
// for (int element=0;element < mixed.length-1;element++){// this for loop reverses order
int temp = mixed[element];
mixed[element]=mixed[element+1];
mixed[element+1]=temp;
}
if ((mixed[0]==1) && (mixed[5]==2)){//this swaps the first and last elements after using an enhanced for loop
int temp = mixed[0];
mixed[0] = mixed[5];
mixed[5] = temp;
}
System.out.println("After sort: ");
for (int element : mixed){
System.out.println("Element: " + element);
}
Make sure to read the comments I have in the code, as this is where my wtf moment is. My goal is to be able to have my high school students do this when it comes time to hit arrays. I would like to be able to introduce this as I introduce arrays. Any help would be greatly appreciated.

You are iterating over the array using elements of the array as an index for the switches that you make.
You are only ever doing two of the same switches.
When the current element is 1, it switches values at index 1 and index 2 of the array.
When the current element is 2, it switches values at index 2 and index 3 of the array.
This doesn't work; you have to do a manual switch at the end. And this manual switch will not work in other cases.
The right way to do this is to:
array 1 2 1 2 1 2
index 0 1 2 3 4 5
Switch:
0 with 1
1 with 3
2 with 5
The are only 3 switches so the loop should start at 0 and end at array length / 2.

Related

When to use set and add methods in list

cutDeck() does the last step of shuffling -- cutting the deck. This should move the first cutLocation number of cards ("first" meaning at the lowest index) from cards and add them to the back of the List. Make certain that you add cards in the same (relative) order that they were originally stored.
public List<PlayingCard> cutDeck(int cutLocation) {
for (int i = 0; i < cutLocation; i++) {
cards.add(cards.get(i));
}
for (int i = 0; i < cutLocation; i++) {
cards.remove(cards.get(i));
}
return cards;
}
This is the error message i am getting
cutDeck(133) did not correctly cut when cards had 208 cards. At index 0 expected 5H but was 3C expected:<[5H]> but was:<[3C]>
I can't see how I am doing something wrong, is it my logic should I be using the cards.set() instead of cards.add()?
Your removal is wrong. Imagine cards has five cards in it and we're splitting it after the first two cards.
1 2 3 4 5
After your first loop terminates, you get:
1 2 3 4 5 1 2
Now, your second loop starts and removes the first card at i = 0, which is 1
2 3 4 5 1 2
Now, your second loop removes the first card at i = 1, which is 3, and NOT 2!
This is where your mistake is. You could simplify the whole logic to a single for loop:
for(int i = 0; i < cutLocation; i++) {
cards.add(cards.remove(0));
}
When you removed the first card in your second for loop all your cards will have been shifted to the front by one position. But your loop variable i is still increasing and you use it in your cards.get(i) call. This means that when you are in the second iteration of your loop you will call cards.get(1), but this would be the original third card to remove. After that you try to remove the next card with cards.get(2), but it would delete the original fifth card and so on.
You might want to use cards.removeAt(0) to (always) remove the card at the beginning until you reached the limit cutLocation.

Replacement selection sorting

So I've been trying to implement this algorithm but I'm not so sure on where to start. Basically from what I understood you can implement it in two ways, by sorting it that the top level is the minimum (minHeap) or that the top level is the max of everything (maxHeap). I googled a lot about any of the two ways and I could not get a grip on how to actually implement it. I do not get the idea in general I would say, can anyone please explain how this works? Like how the minHeap one should work, or the maxHeap one.
Thank you in advance!
I'm assuming that you have a basic understanding of binary heap implementation in an array.
Let's say you have an array of integers that you want to sort into ascending order. One way is to rearrange items in the array so that they form a max-heap.
Then, you swap the top item (the largest item in the array) with the last item in the heap, decrease the heap count by 1, and sift the item from the top down into its new place in the heap. At the end, the first item in the array will be the next largest item. You repeat that for every item and your array is sorted.
Let's take a small example. Given the array [4,7,6,1,3,5,2], you rearrange them into a heap using Floyd's algorithm.
for (int i = array.length/2; i >= 0; i--)
{
siftDown(i);
}
This is an O(n) operation.
When you're done, the array is arranged in a binary heap. In this case, the heap would be [7,4,6,1,3,5,2], or:
7
4 6
1 3 5 2
So, we swap the root item with the last item, giving us: [2,4,6,1,3,5,7]. We decrease the count and sift 2 down to its proper place, giving: [6,4,5,1,3,2,7], or the heap representation:
6
4 5
1 3 2
(I omitted the 7 because we decreased the count. But it's still at the end of the array.)
Again, swap the top item with the last item in the heap: [2,4,5,1,3,6,7], decrease the count, and sift down: [5,4,2,1,3,6,7]:
5
4 2
1 3
If you continue that for the remaining five items in the heap, you'll end up with a sorted array.
The code for this is pretty simple:
int count = array.length-1;
while (count > 0)
{
swap(array[0], array[count]);
--count;
siftDown(0);
}
If you want to do a descending sort, you can either do the above with a max-heap and then reverse the array (an O(1) operation), or you can build a min-heap to start.
The siftDown method just moves the item down to its proper place, following the rules for binary heap construction:
void siftDown(int index)
{
// Left child is at index*2+1. Right child is at index*2+2;
while (true)
{
// first find the largest child
int largestChild = index*2+1;
// if left child is larger than count, then done
if (largestChild >= count)
{
break;
}
// compare with right child
if (largestChild+1 < count && array[largestChild] < array[largestChild+1])
{
++largestChild;
}
// If item is smaller than the largest child, then swap and continue.
if (array[index] < array[largestChild])
{
swap(array[index], array[largestChild]);
index = largestChild;
}
else
{
break;
}
}

Java how to return a function that returns a 2d array right angle pattern

Consider a set of number grids like:
1 1 2 1 2 3
2 2 2 2 3
3 3 3
In other words, a square grid where the number in each position follows a right-angle pattern. How do I write a function that creates, fills in, and returns such a 2d array?
( Also, I'm wondering if Math.max(a, b) would be useful for filling in the grid. I'm wondering if it could return which value is greater between two inputs a and b.)
I already have a function set up, but I don't know where to start:
int[][] cornerPattern(int squareSize) {
}
Hints would be fine
Most of the java programs can easily be solved or atleast initiated by finding a pattern.
So whats the pattern here?
The pattern is that the relation between array index and the element at that place. Every index which has 0 in it has 1 so arr[0][0] is 1.See the pattern there? Every index which has [1] in it has 2. So arr[0][1], arr[1][0] and arr[1][1] are 2 and same is the condition with 3. The size of the array is also defined in the same way. 3, will be [3][3] matrix.
Hope that helps. :)
You are looking for something like this
int m =//input;
int[][] arr = new int[m][m];
for(int i=0;i<m;i++){
for(int j=0;j<m;j++){
if(i>=j)
arr[i][j]=i;
else
arr[i][j]=j;
System.out.print(arr[i][j]);
}
System.out.println();
}

Get confused with nested loops

I know the rationale behind nested loops, but this one just make me confused about the reason it wants to reveal:
public static LinkedList LinkedSort(LinkedList list)
{
for(int k = 1; k < list.size(); k++)
for(int i = 0; i < list.size() - k; i++)
{
if(((Birth)list.get(i)).compareTo(((Birth)list.get(i + 1)))>0)
{
Birth birth = (Birth)list.get(i);
list.set( i, (Birth)list.get( i + 1));
list.set(i + 1, birth);
}
}
return list;
}
Why if i is bigger then i + 1, then swap i and i + 1? I know for this coding, i + 1 equals to k, but then from my view, it is impossible for i greater then k, am i right? And what the run result will be looking like? I'm quite confused what this coding wants to tell me, hope you guys can help me clarify my doubts, thank you.
This method implements a bubble sort. It reorders the elements in the list in ascending order. The exact data to be ordered by is not revealed in this code, the actual comparison is done in Birth#compare.
Lets have a look at the inner loop first. It does the actual sorting. The inner loop iterates over the list, and compares the element at position 0 to the element at position 1, then the element at position 1 to the element at position 2 etc. Each time, if the lower element is larger than the higher one, they are swapped.
After the first full run of the inner loop the largest value in the list now sits at the end of the list, since it was always larger than the the value it was compared to, and was always swapped. (try it with some numbers on paper to see what happens)
The inner loop now has to run again. It can ignore the last element, since we already know it contains the largest value. After the second run the second largest value is sitting the the second-to-last position.
This has to be repeated until the whole list is sorted.
This is what the outer loop is doing. It runs the inner loop for the exact number of times to make sure the list is sorted. It also gives the inner loop the last position it has to compare to ignore the part already sorted. This is just an optimization, the inner loop could just ignore k like this:
for(int i = 0; i < list.size() - 1; i++)
This would give the same result, but would take longer since the inner loop would needlessly compare the already sorted values at the end of the list every time.
Example: you have a list of numbers which you want to sort ascendingly:
4 2 3 1
The first iteration do these swap operations: swap(4, 2), swap(4, 3), swap(4, 1). The intermediate result after the 1st iteration is 2 3 1 4. In other words, we were able to determine which number is the greatest one and we don't need to iterate over the last item of the intermediate result.
In the second iteration, we determine the 2nd greatest number with operations: swap(3, 1). The intermediate result looks then 2 1 3 4.
And the end of the 3rd iteration, we have a sorted list.

For loop stopping prematurely

I'm trying to solve problem #299 - Train Swapping in website UVa Online judge. The code I have works fine for independent test cases. However, when I use the sample input they provide, my program omits one of the test cases, the last one to be more specific:
Here is my code:
import java.util.Scanner;
public class Tester {
void problem(){
Scanner imput = new Scanner(System.in);
int numT =imput.nextInt();
int numL, aux, swaps=0;
int [] train = new int [50];
for (int i =0; i<numT; i++) {
numL = imput.nextInt();
for (int m =0; m< numL; m++) {
train[m]=imput.nextInt();
}
for (int j=0; j<numL; j++) {
if (train[j]>train[j+1]) {
for (int k =j; k<numL-1;k++) {
aux = train[k];
train[k]=train[k+1];
train[k+1]=aux;
swaps++;
}
}
}
System.out.println("Optimal train swapping takes "+swaps+" swaps.");
swaps = 0;
}
}
}
Example Input:
3
3
1 3 2
4
4 3 2 1
2
2 1
Example Output:
Optimal train swapping takes 1 swaps.
Optimal train swapping takes 6 swaps.
Optimal train swapping takes 1 swaps.
My code prints until the second solution, then for some reason stops. I've tried to debug it and check what's going on step by step but it has driven me to a migraine point. Any insight is highly appreciated.
...
To be more precise it stops at the second for loop the third time around without taking anything into the array...and I don't know why!
Another thing I found out is that to solve this problem the number of swaps for the case of the middle is 6, therefore the bubble sort wont be useful here, since it makes over 10 swaps thus yielding a wrong output, this is a separate issue to the original one I presented however. I still haven't figure out why it stops the third time around the loop where I assign values to the array for the third time.
The input consists of:
first line is number of cases.
this line enters the length of a train ex: 4
this line enters the number of the wagons ex: 2 4 3 1
the next following lines correspond to the following test cases whose structure is the same as the example.
They ask you to arrange the train and tell the number of swaps made to make the train in order.

Categories