C# loop going back and forth - c#

I'd like to make a for loop that goes backwards after it reaches the end.
So when "i" reaches 10, instead of "i++" it should do "i--".
I've looked online for a little bit and couldn't find anything in C#. There's this post here, yet it's in JavaScript. I've rarely coded in JavaScript before, so I'm not sure how to translate that code into C# (if that even is possible).
I've successfully achieved this using the code below, yet it's lacking in the "readability" department. It also requires an extra variable, which I don't think is the most elegant solution.
Here's the code that I've written:
static void Main(string[] args)
{
bool reverse = false;
for(int i = 0; i <= 10;)
{
Console.WriteLine(i);
if(i == 10) reverse = true;
if(i == 0) reverse = false;
if(reverse == false) i++;
if(reverse == true) i--;
// Slow down the output
Thread.Sleep(20);
}
}
Again, this code works fine, yet I'm looking for a better solution than this mess.
Thanks in advance!

As small readability improvement I would suggest to change from the boolean flag to an integer increment value:
int increment = 1;
for (int i = 0; i >= 0 && i <= 10; i += increment)
{
Console.WriteLine(i);
if (i == 10) increment = -1;
else if (i == 0) increment = 1;
}

Related

Why doesn't Debug.Log work in this for loop?

Here is what I have. This DrawPoints() method is called in an Update() method, meaning it is called repeatedly if it doesn't have extra conditions if I understand correctly. So basically I'm trying to make the for loop only run once by putting the outside if (iTrack == 0) check on it.
What is weird is that the Debug.Log commands will not run at all (the text "Here 1" or "Here2" never show up in Console), BUT the other code inside like var lerpedPosition and whatToSpawnClone run.
Why don't the Debug Log commands work? Is there something obviously wrong I'm doing with this code? This is very confusing.
int iTrack = 0;
int matricesNumber = 2;
public void DrawPoints()
{
int startIndex = 0;
int endIndex = mesh.vertexCount;
float t = Mathf.Clamp((Time.time % 2f) / 2f, 0f, 1f);
if (iTrack == 0) {
if (matricesNumber == 2)
{
for (int i = startIndex; i < endIndex; i++)
{
Debug.Log("Here 1");
var lerpedPosition = Vector3.Lerp(matrices1[i].position, matrices2[i].position, t);
whatToSpawnClone = Instantiate(whatToSpawnPrefab, lerpedPosition, matrices2[i].rotation) as GameObject;
if (i == (endIndex - 1))
{
Debug.Log("Here 2");
iTrack = 1;
}
}
}
}
}
Based on the description of your question I will assume that you are creating a script for Unity from here on out. Take a look at this. It offers two solutions that would be worth a try, mainly the second one as it is as simple as a check to make sure you have Debug output enabled for the console.

Find lowest period of a string (given array of string) to create a substring and return an array of integers

So I was looking through interview questions that unfortunately didn't have any solutions, and one of them seemed interesting (mostly because I had no idea how to do it). However now I have hit a roadblock and am not sure how to proceed. The objective of the program is to take any amount of strings and spit out the periods of the lowest repeated characters to form the substring in an integer array.
Ex: "abbabbabba","abcdabcddabcdabc","aeiouuaeioouaei" would be 5, 8, 5.
I kind of looked at it as doing Indian runs. The first character runs to the front, if it equals the next character than continue running, etc.
This is the code I have compiled and I tried to take a look at the algorithm for finding periods as well (http://monge.univ-mlv.fr/~mac/REC/text-algorithms.pdf#page=345). I just can't seem to pinpoint the problem in the code
namespace Interview36{
public class PeriodicStrings
{
public static int[] process(string[] input)
{
if (input == null || input.Length == 0 || input[0].Length == 0)
{
Console.WriteLine("Result is null");
}
int length = 0;
int[] list = new int[input.Length];
for (int i = 0; i < input.Length; i++) {
while (i < input[i].Length)
{
if (input[i] == input[length])
{
length++;
list[i] = length;
i++;
}
else
{
if (length != 0)
{
length = list[length - 1];
}
else
{
list[i] = 0;
i++;
}
}
}
}
return list;
}
}
}
My best guess is that my logic is WAY off, or the loop isn't running through properly and I'm just not catching it in debug. Thank you in advance for any insight!

Is this Levenshtein Distance algorithm correct?

I have written the algorithm below to compute the Levenshtein distance, and it seems to return the correct results based on my tests. The time complexity is O(n+m), and the space is O(1).
All the existing algorithms I've seen only for this have space complexity O(n*m), as they create a matrix. Is there something wrong with my algorithm?
public static int ComputeLevenshteinDistance(string word1, string word2)
{
var index1 = 0;
var index2 = 0;
var numDeletions = 0;
var numInsertions = 0;
var numSubs = 0;
while (index1 < word1.Length || index2 < word2.Length)
{
if (index1 == word1.Length)
{
// Insert word2[index2]
numInsertions++;
index2++;
}
else if (index2 == word2.Length)
{
// Delete word1[index1]
numDeletions++;
index1++;
}
else if (word1[index1] == word2[index2])
{
// No change as word1[index1] == word2[index2]
index1++;
index2++;
}
else if (index1 < word1.Length - 1 && word1[index1 + 1] == word2[index2])
{
// Delete word1[index1]
numDeletions++;
index1++;
}
else if (index2 < word2.Length - 1 && word1[index1] == word2[index2 + 1])
{
// Insert word2[index2]
numInsertions++;
index2++;
}
else
{
// Substitute word1[index1] for word2[index2]
numSubs++;
index1++;
index2++;
}
}
return numDeletions + numInsertions + numSubs;
}
Was a comment, but I feel it is probably suitable as an answer:
Short answer is "no", if you want the true shortest distance for any given inputs.
The reason your code appears more efficient (and the reason that other implementations create a matrix instead of doing what you're doing) is that your stepwise implementation ignores a lot of potential solutions.
Examples #BenVoigt gave illustrate this, another perhaps clearer illustration is ("aaaardvark", "aardvark") returns 8, should be 2: it's getting tripped up because it's matching the first a and thinking it can move on, when in fact a more optimal solution would be to consider the first two characters insertions.

Why when making a loop it's all the time reset to 0 on next iterations?

I have a method with some loops inside:
private void RefreshListBox()
{
int i = 0, j = 0, index, count;
Boolean bl = false;
index = listBox1.SelectedIndex;
count = windowsHandles.Count;
for (i = 0; i < count; i++)
{
if (!Constants.IsWindow(windowsHandles[j]))
{
windowsHandles.RemoveAt(j);
windowsText.RemoveAt(j);
windowsBitmaps.RemoveAt(j);
rectanglesList.RemoveAt(j);
isCroppedList.RemoveAt(j);
canDrawNormallyList.RemoveAt(j);
if (j < index)
{
index--;
}
else if (j == index)
{
}
else
{
}
}
else { j++; }
}
if (index == windowsHandles.Count)
{
index--;
}
for (int x = 0; x < windows.Count; x++)
{
for (j = 0; j < windowsHandles.Count; j++)
{
if (windowsHandles[j] == windows[x].Handle) { bl = true; break; }
}
if (bl == false && Constants.IsIconic(windows[x].Handle))
{
windowsHandles.Add(windows[x].Handle);
windowsText.Add(windows[x].Title);
windowsBitmaps.Add(null);
rectanglesList.Add(new Rectangle(0, 0, 0, 0));
isCroppedList.Add(false);
canDrawNormallyList.Add(false);
}
bl = false;
}
if (windowsHandles.Count > 0 && index == -1)
{
index = 0;
}
if (listBox1.Items.Count > 0) { listBox1.Items.Clear(); }
for (i = 0; i < windowsHandles.Count; i++)
{
listBox1.Items.Add(windowsText[i]);
}
if (index != -1)
{
listBox1.SelectedIndex = index;
}
textBoxIndex.Text = windowsHandles.Count.ToString();
drawPicBox(index);
}
private void listBox1_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
var item = listBox1.IndexFromPoint(e.Location);
if (item >= 0)
{
listBox1.SelectedIndex = item;
drawPicBox(listBox1.SelectedIndex);
}
}
}
The problem start when it's getting to the loop at this line:
for (int x = 0; x < windows.Count; x++)
The Count of windows List is 21 in this case.
Then it's entering first time but if i put a break point on this line and click continue all the time i see that x is 0.
When i put a break point on this line:
windowsHandles.Add(windows[x].Handle);
It stop there each time i click on continue but then i see that the variable x it's value is 20 all the time. And the List windowsHandles contain only 1 item.
Then i put a break point on the line:
listBox1.Items.Add(windowsText[i]);
And when i make continue it stop on the line but even if it does the line there are no items on the listBox1.
If i don't use any break points and just make continue to let it run it's never show/get to the form it's like stuck somewhere in this method can't figure out where and why.
In the constructor i'm calling two methods.
First GetWindows then RefreshList
GetWindows();
RefreshListBox();
In GetWindows:
private List<Window> windows = new List<Window>();
private void GetWindows()
{
windows = new List<Window>();
Constants.EnumWindows(Callback, 0);
}
private bool Callback(IntPtr hwnd, int lParam)
{
try
{
if (this.Handle != hwnd && (Constants.GetWindowLongA(hwnd, Constants.GWL_STYLE) & Constants.TARGETWINDOW) == Constants.TARGETWINDOW)
{
StringBuilder sb = new StringBuilder(100);
Constants.GetWindowText(hwnd, sb, sb.Capacity);
Window t = new Window();
t.Handle = hwnd;
t.Title = sb.ToString();
windows.Add(t);
}
}
catch(Exception err)
{
StreamWriter w = new StreamWriter(#"e:\errors.txt");
w.Write(err.ToString());
w.Close();
}
return true;
}
In the end of the GetWindows operation i see that windows contain 21 items.
The problem seems to be somewhere in the RefreshList method but i can't figure out where is the problem.
The goal of all this in the end is to add all the items in windowsText to the listBox1.
I just noticed something else:
windowsHandles.Add(windows[x].Handle);
windowsText.Add(windows[x].Title);
windowsBitmaps.Add(null); // <------
rectanglesList.Add(new Rectangle(0, 0, 0, 0));
isCroppedList.Add(false);
canDrawNormallyList.Add(false);
Is this a correct guess - The reason you're adding a null to windowsBitmaps is so that all six of these collections stay in sync. The items across each collection are related somehow if they have the same index.
It would be much easier if you created one class with properties for windowsHandle, windowsText, windowsBitmaps, etc, and then had a collection of that type. That way instead of managing six collections and trying to keep them in sync you only have one.
This isn't a direct answer, but I think it's a necessary step if you're going to get to the answer: break this up into smaller methods.
You could start with the loops. You could put each of those loops in a separate method and name the method very clearly so that it indicates what it's doing and what it's doing it to. (It might even be worthwhile to put some of the functions in separate classes.)
One of the reasons is that no one - not you or the programmer who works on this later - can expect to be able to hold the complexity of one long method in their head and follow through 'what if this happens, what if that happens.'
Same thing for variable names. It's okay if variable names and method names are long if they help make it clear what they are for. I find myself seeing x and having to scroll back up to see what x is, and then I lose track of where I was.
I know that's not a direct answer. But if you do that then the answer will likely be easier to see. If you break it up into smaller functions (or even write separate classes) then you can also write unit tests. That way instead of running the whole thing from top to bottom you can just test one part at a time.
More directly related
Somewhat more directly related to the code: If you do need to iterate through a collection and possibly remove items as you go, it's better to start from the Count and work backwards. That way your index stays in bounds.
An even easier way is to use Linq to query the elements and create a new collection. For example
Thing[] arrayOfSomething = GetAnArrayOfSomething();
var arrayWithElementsRemoved = arrayOfSomething.Where(
item => !item.DeleteThisOne).ToArray();
The second statement takes an array of Thing and returns a new array containing only the ones where DeleteThisOne is false. It's all in one statement, no looping or bounds to worry about.

what's wrong with this code (.net 2.0)

I am trying to get latest date using code below, but it goes into infinte loop and displays nothing in console,
public static void sortsortyMyDates()
{
int i = 1;
DateTime[] dtList = new DateTime[20];
DateTime LatestDate = dtList[1];
dtList[1] = Convert.ToDateTime("28/05/2013 13:00:00");
dtList[2] = Convert.ToDateTime("23/04/2013 13:00:00");
dtList[3] = Convert.ToDateTime("25/03/2013 13:00:00");
dtList[4] = Convert.ToDateTime("08/04/2013 13:00:00");
while(i < dtList.Length)
{
int result = DateTime.Compare(LatestDate, dtList[i]);
if (result < 0)
continue;
else
LatestDate = dtList[i];
++i;
}
Console.WriteLine(LatestDate.ToString());
}
You have a problem with your loop logic:
if (result < 0)
continue;
If result < 0 then you don't increment i, and so the loop doesn't progress.
Also, your comparison is the wrong way around. result < 0 would mean that the currently-tested date is later than the current maximum. The reason you're getting 01/01/0001 as an output is because you're current code actually finds the earliest date, and most of your array is unintialised (and therefore a lot earlier than your test values!).
Switch your if to this instead (and remove the else entirely):
if (result < 0)
LatestDate = dtList[i];
If continue is executed, i is no longer incremented, and the loop will not terminate.

Categories

Resources