static void PrintPartOfArray(int[] array, int from, int to)
{
int x = array.Length;
if (from > x && from < 0)
{
Console.WriteLine("there is an exeption!");
}
if (to > x && to < 0)
{
Console.WriteLine("there is an exeption!");
}
else
{
for (int i = from; i <= to; i++)
{
Console.WriteLine(array[i]);
}
}
}
static void Main(string[] args)
{
int[] array2 = new int[] { 3, 6, 54, 24, -90, 7, 4 };
PrintPartOfArray(array2,2,7);
}
it supposes to show the "exception error when the function receives a number outside the length of the array, for some reason it not working, when I checked with the debugger it simply skipped the if loops, what have I done wrong?
Consider "early return" for things like this.
if (from > array.Length - 1 || to > array.Length - 1 || from < 0 || to < 0)
{
Console.WriteLine("One of your arguments is out of range.");
return;
}
// Normal, error-free code goes here.
If from and to are greater than x, they can't possibly also be less than 0. Recall that x is the length of an array, which can't be negative. That being said, it's literally impossible for either of your if statements to evaluate to true. Did you mean || instead?
Also, the last index of the array is array.Length - 1, not array.Length. Similarly, the first item in the array is at index 0, not index 1. I think that your array indices are off by 1 here.
Related
so I have a list of Vector3's and I would like to loop through it and see if it equals another Vector3.
I've tried to do this but it won't work i get an error that says
Index was out of range. Must be non-negative and less than the size of the collection.
Here is my code:
int n = GameManager.instance.blocks.Count;
while (n > 1)
{
if (GameManager.instance.blocks[n] == new Vector3(Mathf.RoundToInt(this.transform.position.x), Mathf.RoundToInt(this.transform.position.y), 0))
{
GameManager.instance.blocks.Remove(new Vector3(Mathf.RoundToInt(this.transform.position.x), Mathf.RoundToInt(this.transform.position.y), 0));
}
n--;
}
But i get the error previously stated, what would I change here?
Thanks
You shouldn't set n to your array size it must be n-1 of your total item size.
int n = GameManager.instance.blocks.Count-1;//last index is n-1
while (n >= 0)//0 is the first index
{
if (GameManager.instance.blocks[n] == new
Vector3(Mathf.RoundToInt(this.transform.position.x),
Mathf.RoundToInt(this.transform.position.y), 0))
{
GameManager.instance.blocks.Remove(new Vector3(Mathf.RoundToInt(this.transform.position.x), Mathf.RoundToInt(this.transform.position.y), 0));
}
n--;
}
You shouldn't use "while" loops with Unity.
Vector3 vectorToRemove = new Vector3(Mathf.RoundToInt(this.transform.position.x), Mathf.RoundToInt(this.transform.position.y), 0);
for(int i = GameManager.instance.blocks.Count - 1; i >= 0; --i)
{
if(GameManager.instance.blocks[i] == vectorToRemove) GameManager.instance.blocks.Remove(vectorToRemove);
}
An exception:
Index was outside the bounds of the array
gets thrown in the if below or the else below that
public static Int64[] PrimeGenerator(Int64 length = 1)
{
Int64 pos = 0;
Int64[] primes = new Int64[length];
Int64 Cprime = 2;
Int64 controller = 0;//On evens it adds one less than, on odds it adds oone more than
while(length >= 0)
{
if(pos == 0)
{
primes[pos] = 2;
goto End;
}
if(controller % 2 == 0)
{
primes[pos] = (2 * Cprime - 1);
}
else
{
primes[pos] = (2 * Cprime + 1);
}
End:
Cprime = primes[pos];
controller++;
pos++;
length--;
}
return primes;
}
I have lookat the visual studio debugger and it says that Cprime is some crazy negative number and that length is 0 when it should not be
When I changed all the Int64's to UInt64's Cprime is some crazy positive integer and length is still zero
The code calling this code looks like this, print is a renamed Console.WriteLine
static void Main()
{
UInt64 p = 1000;
UInt64[] primes = PrimeGenerator(p);
bool[] truth = BadArrayTest(primes);
foreach(bool tru in truth)
{
print(tru);
}
System.Threading.Thread.Sleep(50000);
Environment.Exit(0);
}
just do this
while(length > 0)
index is zero base that means starts from zero but length is not like that
so you always have one more loop cycle which is out of array length.
Your array is of length, but you run thru the loop length+1 times. By the way, never ever use Goto.
i'm trying to make a recursive method to check if the last number (always 0) in an integer array (with all > 0 integers) is reachable by increasing (or decreasing) the index of the array with the value of the array element of the current index, while staying within the bounds of the array.
example:
say we have the following array, and the start index == 0:
int[] arr = {3, 6, 4, 1, 3, 4, 2, 5, 3, 0};
step 0 : index = 0, value = 3
step 1 : index = 3, value = 1
step 2 : index = 4, value = 3
step 3 : index = 7, value = 5
step 4 : index = 2, value = 4
step 5 : index = 6, value = 2
step 6 : index = 8, value = 3
step 7 : index = 5, value = 4
step 8 : index = 9, value = 0 -- end
my current code:
static bool Solveable(int index, int[] arr)
{
if (arr[index] == 0)
return true;
if (index + arr[index] < arr.Length)
return Solveable(index + arr[index], arr);
if (index - arr[index] >= 0)
return Solveable(index - arr[index], arr);
return false;
}
the thing with this is that it will only work with solveable cases, all other cases will result in a stackoverflow exception.
how would i be able to solve this problem WITHOUT using global variables to store previous results?
EDIT:
I can only use the parameters: (int index, int[] arr)
You are correct about stack overflow for unsolvable cases: the recursive code would behave like a dog chasing its own tail until, until it reaches the stack limit.
Fortunately, you can break this infinite recursion by observing that you have at most N steps to reach the end of the array, if you are to reach it at all. Therefore, you could add a third parameter to indicate how many steps you have taken already. If you reach zero before the number of steps passes N, you have a path; otherwise, you don't have a path.
static bool Solveable(int index, int[] arr, int stepsSoFar) {
if (arr[index] == 0)
return true;
if (stepsSoFar > arr.Length)
return false;
...
// The rest of your code; pass stepsSoFar+1 down to the next level
}
I can only use the two parameters i included in my code snippet
You can mark the indexes that you have visited in the arr itself by placing -1 into them. In order to preserve array's original state, store the old value in a local variable, and set it back into arr before returning:
static bool Solveable(int index, int[] arr) {
if (arr[index] == 0)
return true;
if (arr[index] == -1)
return false;
int oldArrAtIndex = arr[index];
arr[index] = -1;
try {
...
// The rest of your code
} finally {
arr[index] = oldArrAtIndex;
}
}
Pass a third argument that tracks the indices you've already traveled. Stop processing if you've already tried the current index.
Also, you may want to make a change to account for travelling in either direction:
var solvable = false;
//...
if (index + arr[index] < arr.Length)
solvable = Solveable(index + arr[index], arr);
if (!solvable && index - arr[index] >= 0)
solvable = Solveable(index - arr[index], arr);
return solvable;
School assignment or not, lesson on recursion without all the added complexity.
private static void Main()
{
int[] array = {3, 6, 4, 1, 3, 4, 2, 5, 3, 0};
Console.WriteLine(IsSolveable(array));
Console.ReadKey();
}
private static bool IsSolveable(int[] array)
{
if (array.Length <= 1)
return false;
int index = array[0];
if (index < array.Length && array[index] == 0)
return true;
// this is where the recursion magic happens
return IsSolveable(array.Skip(1).ToArray());
}
Instead of passing int index, you can pass an array, containing currently visited indexes, and if your next index is contained inside of array of visited, then you just break and return false.
High level idea of code is:
static void Main(string[] args)
{
int[] arr = { 3, 6, 4, 1, 3, 4, 2, 5, 3, 0 };
var result = Solveable(new[] {0}, arr);
Console.WriteLine(result);
Console.ReadLine();
}
static bool Solveable(int[] path, int[] arr)
{
var index = path.Last();
if (arr[index] == 0)
return true;
if (index + arr[index] < arr.Length)
{
var nextIndex = index + arr[index];
var nextStepPath = path.Concat(new[] { nextIndex }).ToArray();
if (path.Contains(nextIndex))
return false;
return Solveable(nextStepPath, arr);
}
if (index - arr[index] >= 0)
{
var nextIndex = index - arr[index];
var nextStepPath = path.Concat(new[] {nextIndex}).ToArray();
if (path.Contains(nextIndex))
return false;
return Solveable(nextStepPath, arr);
}
return false;
}
It need a bit of cleanup, but gives you high-level idea, and makes use of only 2 parameters without introducing classes/structs for your array.
Here is an algorithm that does not modify the state:
static bool Solveable(int index, int[] arr)
{
if (arr[index] == 0)
return true;
int nextIndex = index + arr[index];
if (nextIndex < arr.Length)
return Solveable(nextIndex, arr);
// Search for a previous index that leads to a different path
int prevIndex;
while (true)
{
prevIndex = index - arr[index];
if (prevIndex < 0)
return false; // Not found, we are done
if (prevIndex + arr[prevIndex] != index)
return Solveable(prevIndex, arr); // Process the other path
index = prevIndex; // Keep searching
}
}
The essential part is the non recursive back step processing part (see the comments inside the code).
I am trying to write a C# function that, given an argument like new int[] { 2, 3, 2 } which specifies the upper bound + 1 for each element, would return the following (via IEnumberable<int[]>):
0 0 0
0 0 1
0 1 0
0 2 0
1 0 0
0 1 1
0 2 1
1 0 1
1 1 0
1 2 0
1 1 1
1 2 1
Note that the order is important: all the permutations with 0 non-zero elements, followed by all those with 1 non-zero elements, etc. Within one of those groups the order doesn't matter.
I realize that these may not technically be permutations, but it's the closest term that I know of. Also I realize that one way would be to return all the permutations in some order and then sort them according to a function that counts how many non-zero elements there are, but I am hoping for something more elegant and efficient.
I wanted an answer that doesn't calculate everything first and then sort, while still only going through things the minimal amount of times. Here's what I've got. Note that externally modifying the int[] could screw up the results (alternately, could return a new int[]).
The first method tells the helper method how many 0's it wants in the output. The helper then calculates the results, stopping if it can't fill in enough 0's or if it runs through all the data.
static IEnumerable<int[]> Permutation(int[] bounds)
{
for(int num0s = bounds.Length; num0s >= 0; --num0s)
{
foreach(int[] ret in PermHelper(num0s, 0, bounds, new int[bounds.Length]))
yield return ret;
}
}
static IEnumerable<int[]> PermHelper(int num0s, int index, int[] bounds, int[] result)
{
//Last index.
if(index == bounds.Length - 1)
{
if(num0s > 0)
{
result[index] = 0;
yield return result;
}
else
{
for(int i = 1; i < bounds[index]; ++i)
{
result[index] = i;
yield return result;
}
}
}
//Others.
else
{
//still need more 0s.
if(num0s > 0)
{
result[index] = 0;
foreach(int[] perm in PermHelper(num0s - 1, index + 1, bounds, result))
yield return perm;
}
//Make sure there are enough 0s left if this one isn't a 0.
if(num0s < bounds.Length - index)
{
for(int i = 1; i < bounds[index]; ++i)
{
result[index] = i;
foreach(int[] perm in PermHelper(num0s, index + 1, bounds, result))
yield return perm;
}
}
}
}
I apologize if this code has syntax errors (not in a position to test) but hopefully you get the idea.
IEnumerable<int[]> Permutations(int[] upperBounds) {
int[] c = new int[upperBounds.Length] {};
while(true) {
int i = c.Length - 1;
while(i >= 0 && c[i] == upperBounds[i]) {
c[i] = 0;
i--;
}
if(i == -1) break;
c[i]++;
yield return (int[]) c.Clone();
}
}
It gets even better if you use a callback and keep the same array reference, but you asked for an IEnumerable. If not using Clone is possible, by all means, please use it - it will be much more efficient.
Given two arrays
int arr1[n]
int arr2[m]
where n > m
Need to write a union of two arrays into one.
For example, if the input arrays are:
int arr1[] = {1, 3, 4, 5, 7}
int arr2[] = {2, 3, 5, 6}
Then program should create new array Union as {1, 2, 3, 4, 5, 6, 7}
Implementation can be in C# or Java.
In order to solve it first of all need to to sort the arrays using Merge Sort
and then do the union
I looked in the net but did not find the elegant way . Every code that I looked
was full of IF's.
Please advice what is the most quick and elegant way to do it
You are correct that merging the two lists as is done in Merge Sort is the most efficient thing to do. This assumes that the two lists are already sorted, as in your example. Here is an example of how to implement merge:
function merge(left,right)
var list result
while length(left) > 0 or length(right) > 0
if length(left) > 0 and length(right) > 0
if first(left) ≤ first(right)
append first(left) to result
left = rest(left)
else
append first(right) to result
right = rest(right)
else if length(left) > 0
append first(left) to result
left = rest(left)
else if length(right) > 0
append first(right) to result
right = rest(right)
end while
return result
From here, simply do not include repeats in the final output.
If its an elegant MergeSort you are looking then nothing is more elegant than a recursive function :-)
Here it is :
This is a divide and conquer strategy. We basically divide the array into smaller arrays , sort the smaller arrays and merge them back.
public static void mergesort(int a[],int left, int right){
/*
* Time : O(n log n)
* Space : O(n)
*/
int b[] = new int[right -left+1];
domergesort(a,left,right,b);
}
public static void domergesort(int a[],int left,int right, int b[]){
if(left < right){
int mid = (left+right)/2;
domergesort(a,left,mid,b);
domergesort(a,mid+1,right,b);
merge(a,left,mid,a,mid+1,right,b);
for(int k=left;k<=right;k++)
a[k] = b[k-left];
}
}
Not many ifs too ..
Source : My Blog (http://cloudingitup.blogspot.com/p/reading-guide-arrays.html)
To merge them together as a Union :
public static void merge( int a[], int al, int ar, int b[], int bl, int br, int c[]){
// al : a's left index ar : a's right index c: merged array
int i= al;
int j = bl;
int k=0;
int prev = c[0];
while ( i<= ar && j <= br){
if (a[i] <= b[j])
if (prev != a[i]) // Too keep the union distinct
c[k++] = a[i++];
else
i++;
else
if (prev != b[j]) // Too keep the union distinct
c[k++] = b[j++];
else
j++;
prev = c[k-1];
}
while (i <= ar)
{
if (prev != a[i])
c[k++] = a[i++];
else
i++;
prev = c[k-1];
}
while (j <= br)
{
if (prev != b[j])
c[k++] = b[j++];
else
j++;
prev = c[k-1];
}
}
A driver code to illustrate the code :
int arr1[] = {1,1, 3, 4,4,4,5, 7};
int arr2[] = {2, 3, 5, 6,6,8};
int c[] = new int[8];
merge(arr1,0,7,arr2,0,5,c);
for(int i=0;i<8;i++)
System.out.print(c[i]);
Output: 12345678
public static void printUnion(int ar1[],int ar2[]) {
int m = ar1.length;
int n = ar2.length;
int i=0,j=0;
while(i<m && j<n) {
if( ar1[i] <ar2[j]) {
System.out.println(ar1[i]);
i++;
}else if(ar1[i] > ar2[j]) {
System.out.println(ar2[j]);
j++;
}else {
System.out.println(ar1[i]);
i++;
j++;
}
}
while(i < m)
System.out.println(ar1[i++]);
while(j < n)
System.out.println(ar2[j++]);
}
Same code will work for intersection with minimal changes....
In interviews, they usually want to see you solve the problem, rather than using library calls (e.g. arr1.union(arr2) probably wouldn't cut it.)
This is off the top of my head, but something like this should work, and I think is O(n^2). It assumes both arrays are sorted.
union.rb
arr1 = [0,2,4,9,11,12,13]
arr2 = [3,4,7,9,10,11]
def union(n, m)
if n.last > m.last
arr1 = n; arr2 = m
else
arr1 = m; arr2 = n
end
union_array = []
j = 0
arr1.each do |x|
while j < arr2.length && arr2[j] < x
if arr2[j] < x
union_array << arr2[j] unless arr2[j] == union_array.last
j += 1
end
end
union_array << x
end
union_array
end
puts union(arr1, arr2)
this method should work fairly well, and it will decide which array is bigger so there doesn't need to necessarily be a defined order.
Java:
public static <T> T[] combine(T[] a1, T[] a2)
{
return combine(a1, a2, a1.length + a2.length);
}
public static <T> T[] combine(T[] a1, T[] a2, int maxlength)
{
T[] front = null;
T[] back = null;
if(a1.length >= a2.length)
{
front = a1;
back = a2;
}
else
{
front = a2;
back = a1;
}
int len = front.length + back.length;
if(len > maxlength)
{
len = maxlength;
}
int n = 0;
T[] result = Arrays.copyOf(front, len);
int c = 0;
for(int i = 0;i < front.length;i++)
{
if(i < front.length && c < result.length)
{
result[c] = front[i];
c++;
}
if(i < back.length && c < result.length)
{
result[c] = back[i];
c++;
}
}
return result;
}
this is obviously not the most efficient method, but it does completely work. It also includes a capping, if you want to merge them, but only get the first, let's way 5 items, then you can add a parameter of 5 to the method.
You can actually get rid of a lot of waste, there's a lot of messy stuff in here, I'm away from my IDE so it's off my head, I may have stuff that's not needed.