Merge Sort Iterative Implementation - Not working - mergesort

I have the below merge sort iterative implementation, but somehow, it is not working. I debugged it, but couldn't find the cause.
Merge'ing function would remain the same as the recursive case, only the array dividing logic would be different, if I'm correct.
Please rectify, if I'm going in wrong direction.

I think you have a problem when you try to use the same object to represent different intervals:
At MergeSort_Iterative loop , when you are adding new elements to list1 you are using "info" object as temporal variable and then you add it to list1 collection.
In Java, all object variables are references so when you add the object to the collection you are not adding a copy of it but a reference which is being modified and inserted again.
info.left = left;
info.right = mid;
list1.add(info);
info.left = mid + 1;
info.right = right;
list1.add(info);
To fix that you should create two objects in order two perform the inserctions:
info = new MergePosInfo();
info.left = left;
info.right = mid;
list1.add(info);
info = new MergePosInfo();
info.left = mid + 1;
info.right = right;
list1.add(info);
On the other hand, once the problem described above is solved, you should iterate over list2 from shorter to wider intervals and from left to right positions and your algorithm is not generating list2 in that order.
You need to modify MergeSort_Iterative:
public static void MergeSort_Iterative(int[] numbers, int left, int right) {
int mid;
if (right <= left)
return;
LinkedList<MergePosInfo> list1 = new LinkedList<MergePosInfo>();
LinkedList<MergePosInfo> list2 = new LinkedList<MergePosInfo>();
for(int i = left; i <= right; i+=2)
{
MergePosInfo info = new MergePosInfo();
info.left = i;
info.right = (i+1<=right)?(i+1):i;
info.mid = -1;
list1.add(info);
list2.add(info);
}
int l = right-left+1;
for(int partsSize = 2; partsSize <= l/2; partsSize*=2)
{
int ll1 = list1.size();
for(int i = 0; i < ll1; i+=2)
{
MergePosInfo info2 = new MergePosInfo();
info2.left = list1.get(0).left;
info2.right = list1.get(1).right;
info2.mid = (info2.left+info2.right)/2;
list1.remove(0);
list1.remove(0);
list1.add(info2);
list2.addLast(info2);
}
}
for (int i = 0; i < list2.size(); i++) {
System.out.println("Merge [" + Integer.toString(list2.get(i).left) + " , " + Integer.toString(list2.get(i).right) + "]" );
DoMerge(numbers, list2.get(i).left, list2.get(i).mid+1,
list2.get(i).right);
}
}
As well as to add some lines to DoMerge:
public static void DoMerge(int[] numbers, int left, int mid, int right) {
int[] temp = new int[25];
int i, left_end, num_elements, tmp_pos;
left_end = (mid - 1);
tmp_pos = left;
num_elements = (right - left + 1);
if(num_elements == 2)
{
if(numbers[left]>numbers[right])
{
int buffer = numbers[left];
numbers[left] = numbers[right];
numbers[right] = buffer;
}
return;
}
...
As you can see the solution I provided only works when "numbers" length is 2^k. You can try to fix it by yourself and if you can't I will give you the last change.
I left
System.out.println("Merge [" + Integer.toString(list2.get(i).left) + " , " + Integer.toString(list2.get(i).right) + "]" );
line so you can understand how merge sort works.

info.left = left;
info.right = mid;
list1.add(info);
info.left = mid + 1;
info.right = right;
list1.add(info);
You are operating on the same object. Use a different object for each iteration, the same way you are doing with info2

Related

Holes in Mesh only showing from one side

For a sailing game I'm working on, I've added functionality to programmatically create damage holes in a mesh (e.g. cannonball holes in a sail). This is largely based on the method here (link to the example code here)
private void MessWithMesh() {
filter = this.transform.parent.gameObject.GetComponent<MeshFilter>();
mesh = filter.mesh;
filter.mesh = GenerateMeshWithHoles();
}
private IEnumerator GenerateTrisWithVertex() {
// Destroying the sail won't work until this has finished, but it only takes a second or two so I don't think anybody will notice.
trisWithVertex = new List<int>[origvertices.Length];
for (int i = 0; i <origvertices.Length; ++i)
{
trisWithVertex[i] = ArrayHelper.IndexOf(origtriangles, i);
yield return null;
}
yield return null;
}
Mesh GenerateMeshWithHoles()
{
float damageRadius = 1f;
Transform parentTransform = this.transform.parent.transform;
Hole[] holes = this.GetComponentsInChildren<Hole>();
foreach (Hole hole in holes) {
Vector3 trackPos = hole.transform.position;
float closest = float.MaxValue;
int closestIndex = -1;
int countDisabled = 0;
damageRadius = hole.diameter;
for (int i = 0; i <origvertices.Length; ++i)
{
Vector3 v = new Vector3(origvertices[i].x * parentTransform.localScale.x, origvertices[i].y * parentTransform.localScale.y, origvertices[i].z * parentTransform.localScale.z) + parentTransform.position;
Vector3 difference = v - trackPos;
if (difference.magnitude < closest)
{
closest = difference.magnitude;
closestIndex = i;
}
if (difference.magnitude < damageRadius)
{
for (int j = 0; j <trisWithVertex[i].Count; ++j)
{
int value = trisWithVertex[i][j];
int remainder = value % 3;
trianglesDisabled[value - remainder] = true;
trianglesDisabled[value - remainder + 1] = true;
trianglesDisabled[value - remainder + 2] = true;
countDisabled++;
}
}
}
// If no triangles were removed, then we'll just remove the one that was closest to the hole.
// This shouldn't really happen, but in case the hole is off by a bit from where it should have hit the mesh, we'll do this to make sure there's at least a hole.
if (countDisabled == 0 && closestIndex > -1) {
Debug.Log("Removing closest vertex: " + closestIndex);
for (int j = 0; j < trisWithVertex[closestIndex].Count; ++j)
{
int value = trisWithVertex[closestIndex][j];
int remainder = value % 3;
trianglesDisabled[value - remainder] = true;
trianglesDisabled[value - remainder + 1] = true;
trianglesDisabled[value - remainder + 2] = true;
}
}
}
triangles = ArrayHelper.RemoveAllSpecifiedIndicesFromArray(origtriangles, trianglesDisabled).ToArray();
mesh.SetTriangles(triangles, 0);
for (int i = 0; i <trianglesDisabled.Length; ++i)
trianglesDisabled[i] = false;
return mesh;
}
When a cannonball hits the sail, I add a Hole object at the location of the impact, and I call MessWithMesh. The holes are often generated correctly, but many times they're only visible from one side of the sail (it looks fully intact from the other side). It's often visible from the opposite side of the sail that the cannonball impacted (the far side, not the near side), if that's at all helpful. The ship I'm using is this free asset.
I'm not really familiar with meshes, so I don't really understand what's going on.

Object does not return to original position when released cs4

I am making a drag and drop activity where multiple items are to be placed at the same target. I have action code on the main time line and then code attached to a sprite.
Problems:
When I release the object if it is correct it should snap to the top of that section. If it is incorrect it should return to its original orientation to be picked up again. Unfortunately it stays where I placed it, and does not move back to original place when it is incorrect. I have fixed other issues with this flash file as to if code is supposed to be on the main time line or in the sprite, but this does not seem to have an effect after the object is released. Near the end of the script there is _root.rlamp1.gotoAndPlay(1) this is a buzzer that goes off if the answer is incorrect. This is working correctly.
I do not know if these are related Items but if the correct placement is given I want the next item to start in the original position, but it is starting where my mouse is instead of the original position. I am relatively new to coding and am trying to make an activity for my science class to get instant feedback to see if they understand to concept.
Thanks for your help.
// [Action in Frame 1]
answername = Array();
answerdest = Array();
answername[0] = "gravel";
answerdest[0] = "1";
answername[1] = "nuts and bolts";
answerdest[1] = "1";
answername[2] = "oxygen";
answerdest[2] = "2";
answername[3] = "helium";
answerdest[3] = "2";
answername[4] = "gold";
answerdest[4] = "2";
dbCount = 0;
dbutton.duplicateMovieClip("dbutton" + dbCount,dbCount * 100);
dbutton.visible = false;
dbutton0.answer = answerdest[dbCount];
dbutton0.theText.text = answername[dbCount];
// This code is on the sprite and not on the main actionscript
onClipEvent (load)
{
this.defx = _x;
this.defy = _y;
if (this.theText.text.length > 20)
{
this.theText._height = 31;
this.theBox._height = 27;
}
else
{
this.theText._height = 19;
this.theBox._height = 19;
} // end else if
}
on (press)
{
if (this.noDrag !=true)
{
startDrag (this,false);
}
}
on (release)
{
if (this.noDrag != true)
{
stopDrag ();
if(this.hitTest(_root["dz" + this.answer]))
{
totalHeight = 0;
for (v = 0; v < _root.dbCount; v++)
{
if (_root["dbutton" + v].answer == this.answer)
{
totalHeight = totalHeight + _root["button" + v].theBox._height ;
} // end if
} // end of for
++_root.dbCount;
this .duplicateMovieClip("dbutton" + _root.dbCount, _root.dbCount * 100);
_root["dbutton" + _root.dbCount]._x = this.defX;
_root["dbutton" + _root.dbCount]._y = this.defY;
_root["dbutton" + _root.dbCount].answer = _root.answerdest[_root.dbCount + 1];
_root["dbutton" + _root.dbCount].theText.text = _root.answername[_root.dbCount +1];
if (_root["dbutton" + _root.dbCount].theText.text == "undefined")
{
_root["dbutton" + _root.dbCount].theText.text = "Finished!";
_root["dbutton" + _root.dbCount].noDrag = true;
} // end if
this.noDrag = true;
this._y = _root["dz" + this.answer]._y + totalHeight;
this._x = _root["dz" + this.answer]._x - _root["dz" + this.answer]._width / 2;
++_root["dz" + this.answer].numItems;
_root.glamp1.gotoAndPlay (1);
}
else
{
this.X = this.defX;
this._Y = this.defY;
_root.rlamp1.gotoAndPlay(1);
} // end if
} // end else if
}
The problem is that there are misspelled variable names and properties in the sprite code.
Replace these lines
this.X = this.defX;
this._Y = this.defY;
with those lines
this._x = this.defx;
this._y = this.defy;
and your code should work.

Why am I getting this dynamic IndexOutOfBounds Exception?

I am trying to write a program where text is translated into hexadecimal, then into decimal, and then into an (R, G, B) format. However, when trying to incorporate ClickableRectangle, I get an ArrayIndexOutOfBounds exception that changes dynamically with the sign of rects.
Any thoughts on my problem/optimization?
char[] colors; //Array of characters to be translated into hexadecimal
String r = ""; //Red value of color
String g = ""; //Green value of color
String b = ""; //Blue value of color
int x = 0; //X-coordinate of rectangle
int y = 0; //Y-coordinate of rectangle
int q; //Character count
ClickableRectangle[] rects = new ClickableRectangle[400*400]; //Rectangles
void settings() {
size(displayWidth, displayHeight);
}
void setup() {
background(0);
colors = new char[3];
String s = ([INSERT TRANSCRIPT HERE]); //Too long to be in post//
for (int i = 0; i < s.length(); i+=3) {
for (int j = i; j < i+3; j++) {
colors[j-i] = s.charAt(j);
}
r = hex(colors[0], 2);
g = hex(colors[1], 2);
b = hex(colors[2], 2);
drawAPoint(r, g, b, i);
println(i);
q++;
}
save("SlachtochtFeuf.png"); //Ignore this, using for testing purposes
println("q = " + q);
println("x = " + x);
println("y = " + y);
}
void draw() {
for (int i = 0; i < rects.length; i++) {
if (rects[i].isClicked()) {
println(rects[i].getValue()); //Prints char representation of color
}
}
}
void drawAPoint(String r2, String g2, String b2, int i) {
noStroke();
fill(unhex(r2), unhex(g2), unhex(b2));
rects[i] = new ClickableRectangle(x, y, r2, g2, b2);
rects[i].display();
if (x >= width) {
x = 0;
y += 6;
} else {
x+=6;
}
}
class ClickableRectangle {
int x = 0;
int y = 0;
String r = "";
String g = "";
String b = "";
public ClickableRectangle(int x, int y, String r, String g, String b) {
this.x = x;
this.y = y;
this.r = r;
this.g = g;
this.b = b;
}
public void display() {
fill(unhex(r), unhex(g), unhex(b));
rect(x, y, 6, 6);
}
public void setRGB(String r, String g, String b) {
this.r = r;
this.g = g;
this.b = b;
}
public String getValue() {
return ""+char(unhex(r))+char(unhex(g))+char(unhex(b));
}
public boolean isClicked() {
return mouseX > x && mouseY > y && mouseX < x+6 && mouseY < y+6;
}
}
For future reference, you should tell us exactly which line throws the exception, and you should include all of the code needed to repeat the problem. If the text is too long to post, then narrow it down to a smaller MCVE.
But judging from what I can see, the problem appears to be here:
String s = "test";
for (int i = 0; i < s.length(); i+=3) {
for (int j = i; j < i+3; j++) {
colors[j-i] = s.charAt(j);
}
//other stuff
}
Just run through this in your head:
When i=0 and j=0, you access charAt 0.
When i=0 and j=1, you access charAt 1.
When i=0 and j=2, you access charAt 2.
When i=3 and j=3, you access charAt 3.
When i=3 and j=4, you access charAt 4.
You could also use println() statements to better see what's going on:
for (int i = 0; i < s.length(); i+=3) {
println("i: " + i);
for (int j = i; j < i+3; j++) {
println("j: " + j);
colors[j-i] = s.charAt(j);
}
//other stuff
}
That prints out:
i: 0
j: 0
j: 1
j: 2
0
i: 3
j: 3
j: 4
That last part is the problem- the String I'm using is "test", so it only has 4 characters: charAt(0), charAt(1), charAt(2), and charAt(3). So when you try to access charAt(4), it throws a StringIndexOutOfBoundsException!
I don't know exactly what you're trying to do here, but you'll have to rework your code so that it doesn't try to access characters outside the bounds of the String.
As a side note: it looks like you're trying to code your whole project all at once. Don't do that. Instead, develop this in small increments- try to get smaller pieces working by themselves before you combine them into your whole project. Can you write a separate sketch that simply loops over a String and prints out the characters you're trying to extract? Then if you get stuck, you can use that smaller sketch as your MCVE, and it'll be easier for us to help you.

User input with linear and binary searching in java

I'm trying to write a program that asks the user to input the size of the array the user wants to create, and then asks the user to fill the array with elements, and then it should display the array with its elements and, ask the user to conduct a search for an integer. It should conduct a linear and binary search, while displaying how many probes it took to determine is the element is in the array. So far the only output i have gotten is that the element has not been found. If you could look at my code and see what the problem is, because i have tried for hours and i have changed everything i can think of. Any help would be greatly appreciated.
import java.util.Scanner;
public class Searching
{
public static int[] anArray = new int[100];
private int numberOfElements;
public int arraySize = numberOfElements;
public String linearSearch(int value)
{
int count = 0;
boolean valueInArray = false;
String indexOfValue = "";
System.out.print("The Value was Found in: ");
for(int i = 0; i < arraySize; i++)
{
if(anArray[i] == value)
{
valueInArray = true;
System.out.print(i + " ");
indexOfValue += i + " ";
}
count ++;
}
if(!valueInArray)
{
indexOfValue = " None found";
System.out.print(indexOfValue);
}
System.out.println("\nIt took " + count + " probes with a linear search to find");
return indexOfValue;
}
public void binarySearch(int value)
{
int min = 0;
int max = arraySize - 1;
int count = 0;
while(min <= max)
{
int mid = (max + min) / 2;
if(anArray[mid] < value) min = mid + 1;
else if(anArray[mid] > value) max = mid - 1;
else
{
System.out.println("\nFound a Match for " + value + " at Index " + mid);
min = max + 1;
}
count ++;
}
System.out.println("It took " + count + " probes with a binary search to find");
}
public static void main(String[] args)
{
#SuppressWarnings("resource")
Scanner scan = new Scanner(System.in);
System.out.println("Input the number of elements in your Array");
int numberOfElements = scan.nextInt();
if(numberOfElements <= 0)
{
System.exit(0);
}
int[] anArray = new int[numberOfElements];
System.out.println("\nEnter " + numberOfElements + " Integers");
for(int i = 0; i < anArray.length; i ++)
{
System.out.println("Int # " + (i + 1) + ": ");
anArray[i] = scan.nextInt();
}
System.out.println("\nThe integers you entered are: ");
for(int i = 0; i < anArray.length; i ++) // for loop used to print out each element on a different line
{
System.out.println(anArray[i]);
}
System.out.println("Which element would you like to find?");
int value = scan.nextInt();
Wee3Q2JOSHBALBOA newArray = new Wee3Q2JOSHBALBOA();
newArray.linearSearch(3);
newArray.binarySearch(value);
}
}
hmm I am not sure you are using an array the correct way, you see an Array is a set size and I dont think you can expand like they way you are doing...
Instead try setting the size of the array to certain length.
Or use vectors

C# Quickly checking if two pictureboxes touch each other?

I'm creating my first non-console game in Visual C#.
I have a player which is a picturebox, and obstacles which are also pictureboxes.
Now when I create an obstacle (picturebox) at a random position, I would like to check if it already touches an other obstacle.
Here's what I have now:
Picturebox obstacles = new Picturebox[20];
for (int i = 0; i < obstacles.Length; i++)
{
DateTime date = DateTime.Now;
Random randomNumber = new Random(date.Second * (date.Minute / 2) ^ 2 + date.Hour * 123 + (i ^ 9 + i / 2));
obstacles[i] = new PictureBox();
obstacles[i].Image = Properties.Resources.es;
obstacles[i].Size = new Size(25, 50);
obstacles[i].Location = new Point(randomNumber.Next(640 - obstacles[i].Image.Width), randomNumber.Next(topBar.Height, 480 - obstacles[i].Image.Height));
if (IsTouching(obstacles[i], player))
{
i--;
}
else
{
bool tmp = true;
for (int j = 0; j < obstacles.Length; j++)
{
if (obstacles[j] != null && j != i)
{
if (IsTouching(obstacles[j], obstacles[i]))
{
tmp = false;
break;
}
}
}
if (tmp)
{
Controls.Add(obstacles[i]);
}
else
{
i--;
}
}
}
So that's my way, but I know it's not really effective, so any better ideas, cause it takes a while (~5 seconds) to create those obstacles.
And here's my IsTouching method, which also kinda sucks, anyone have better ideas?
private bool IsTouching(PictureBox obj1, PictureBox obj2)
{
Point[] obj1Points = new Point[(obj1.Width * obj1.Height) - ((obj1.Width - 2) * (obj1.Height - 2))];
int count = 0;
for (int x = obj1.Left + 1; x < obj1.Left + obj1.Width - 1; x++)
{
obj1Points[count] = new Point(x, obj1.Top);
obj1Points[count + 1] = new Point(x, obj1.Top + obj1.Height);
count += 2;
}
for (int y = obj1.Top; y < obj1.Top + obj1.Height; y++)
{
obj1Points[count] = new Point(obj1.Left, y);
obj1Points[count + 1] = new Point(obj1.Left + obj1.Width, y);
count += 2;
}
Point[] obj2Points = new Point[(obj2.Width * obj2.Height) - ((obj2.Width - 2) * (obj2.Height - 2))];
count = 0;
for (int x = obj2.Left + 1; x < obj2.Left + obj2.Width - 1; x++)
{
obj2Points[count] = new Point(x, obj2.Top);
obj2Points[count + 1] = new Point(x, obj2.Top + obj2.Height);
count += 2;
}
for (int y = obj2.Top; y < obj2.Top + obj2.Height; y++)
{
obj2Points[count] = new Point(obj2.Left, y);
obj2Points[count + 1] = new Point(obj2.Left + obj2.Width, y);
count += 2;
}
for (int obj2Point = 0; obj2Point < obj2Points.Length; obj2Point++)
{
for (int obj1Point = 0; obj1Point < obj1Points.Length; obj1Point++)
{
if (obj2Points[obj2Point].X == obj1Points[obj1Point].X && obj2Points[obj2Point].Y == obj1Points[obj1Point].Y)
{
return true;
}
}
}
return false;
}
What it does: Checks if the given two parameters edges touch each other. So basically just a collision-detection, anyone have any ideas, cause I'm kinda new at this stuff?
If we assume that all the obstacles are solid (i.e. 2 obstacles touch if the other is inside the other), you can use the following method:
private bool IsTouching(PictureBox p1, PictureBox p2)
{
if (p1.Location.X + p1.Width < p2.Location.X)
return false;
if (p2.Location.X + p2.Width < p1.Location.X)
return false;
if (p1.Location.Y + p1.Height < p2.Location.Y)
return false;
if (p2.Location.Y + p2.Height < p1.Location.Y)
return false;
return true;
}
I tested your current IsTouching method and found out that it fails in some corner cases, such as in this one (it claims they are not touching although they are). My method works in these corner cases too.
There is one simple line of code for this but it might also fail for some corner pieces sometimes.
if(player1.Bounds.IntersectWith(player2.Bounds){
//Do something
}
Replace player1 with the name of the picture box and the same with player2 ofc.