C# Infinite color loop [duplicate] - c#

I am looking to create a program like the following (c# btw):
int[] arr = new int[9]
//some code that puts values 1, 0, or 2 in each array element
for(int i = 0; i < arr.Length; i++)
{
if (arr[i] == arr[i + 3]) { return true; }
}
So, for each value in the array I am applying a formula that does something with that value and the value 3 indexes ahead of it. Of course, this runs into an out of range exception once i+3>8.
What I'd like to do is if the the desired index is out of range then loop the index values back around to the beginning of the array. So, in an array of length 9 where the last index is 8, if on a given loop i = 7, and i+3 then = 10, I would like i+3 to 'become,' by whatever means, 1, and then when i = 8, and i+3 = 11, I want i+3 to become 2.
So, the index pairs being evaluated would be something like:
i , i+3
0 3
1 4
2 5
3 6
4 7
5 8
6 0
7 1
8 2
how can I go about doing this?
Thanks for any help.

Use the modulo operator like this:
if (arr[i] == arr[(i + 3) % arr.Length]) { return true; }

You could try the following expression inside your if statement.
arr[i] == arr[(i + 3) % arr.Length];
The % Operator
Divides the value of one expression by the value of another, and
returns the remainder.

Related

C# Code to print out prime numbers from 5 to N

Prime Number Generator Code
Do know that this question should be quite basic but i have spent hours trying to figure out why my code is stuck in the loop as below. Have added a Console.WriteLine($"{counttemp} , {count1} "); in the if loop to check the 2 numbers and seems like it is not breaking out of the if condition when the condition is true
this is the console output for the writeline in the if loop
5 , 5
6 , 2
7 , 7
8 , 2
9 , 3
10 , 2
11 , 11
12 , 2
13 , 13
14 , 2
15 , 3
16 , 2
17 , 17
18 , 2
19 , 19
Problematic Loop??
for (count1 = 2; count1 <= counttemp ; ++count1)
{
if(counttemp % count1 == 0)
{
Console.WriteLine($"{counttemp} , {count1} ");
Console.ReadKey();
primetest1 = 0;
break;
}
}
full code sequence
static void Main(string[] args)
{
int prime1 = 10000, count1, primetest1, counttemp;
for (counttemp = 5; counttemp <= prime1; counttemp++)
{
primetest1 = 1;
for (count1 = 2; count1 <= counttemp ; ++count1)
{
if(counttemp % count1 == 0)
{
Console.WriteLine($"{counttemp} , {count1} ");
Console.ReadKey();
primetest1 = 0;
break;
}
}
if (primetest1 == 1)
{
Console.Write($"{counttemp}");
}
}
}
You're almost there. The problem is that you're checking if your candidate number is a prime by getting the remainder when divided by each number up to and including the number itself.
I think you'll find that N is a factor of N for all values of N. To fix this, you should only be checking up to but excluding the number.
And, as an aside, you don't really need to check all the way up to N - 1. You only need to go to the square root of N, adjusted up to the nearest integer. That's because, if it has a factor above the square root, you would already have found a factor below it.
Consider 24 as an example. It has 6, 8, and 12 as factors above the square root, but the matching values below the square root are 4, 3, and 2 respectively.
And there's a another trick you can use by realising that if a number is a multiple of a non-prime, it's also a multiple of every prime factor of that non-prime. In other words, every multiple of 12 is also a multiple of 2 and 3.
So you only need to check prime numbers up to the square root, to see if there's a factor. And prime numbers, other than two or three, are guaranteed to be of the form 6x-1 or 6x+1, so it's quite easy to filter out a large chunk of candidates very quickly, by checking only for those values.
In other words, check two and three as special cases. Then start at 5 and alternately add 2 and 4: 5, 7, 11, 13, 17, 19, .... Not every number in that set is prime (e.g, 25) every prime is guaranteed to be in that set.
You can check out an earlier answer of mine for more detail on why this is so, and how to do this sequence efficiently.

c# foreach loop not able to add literals in an array

Firstly I know that I can't use a foreach loop in C# to add values in let's say an array... But why? Why for example I can't do this
int[] numbers = { 1, 4, 3, 5, 7, 9 };
foreach (int item in numbers)
{
numbers[item] = 2;
}
Does it have something to do with the actual realisation of the foreach loop in the back-end? And how does the foreach loop exactly work? I know that it goes through the whole collection(array) but how exactly?
You are passing in the value of an item (your variable, item, will be the value of the array at each position in sequence, not the index) in the array as the index. The index used there is meant to be the position of the item you are attempting to access, not the value. So each iteration of the loop you are calling:
numbers[1]
numbers[4]
numbers[3]
numbers[5]
numbers[7]
numbers[9]
The array has 6 numbers, so when you get to numbers[7], you are asking for a value that is not there, hence the exception.
A better method of doing what you are trying to do would be:
for(int i = 0; i < numbers.Length; i++)
{
numbers[i] = 2;
}
On each iteration of this loop you would be accessing:
numbers[0]
numbers[1]
numbers[2]
numbers[3]
numbers[4]
numbers[5]
I'm looking at this:
numbers[item] = 2;
In this expression, you're using the item variable like an index, as if it had the values 1, 2, 3, 4, etc. That's not how the foreach iteration variable works for C#. The only language I know that does it this way is Javascript.
Remember that foreach and for are not the same thing. Just about every other language, including C#, gives you the actual array values in the item variable of a foreach loop: 1,4, 3, 5 etc. Now, these are integers, so you could try to use them as indexes. You can run the loop for a while like that... until you get to the value 7. At this point, your array only has six values. You're trying to do this:
numbers[7] = 2;
for an array where the largest valid index you can use is 5.
This is true even taking your modification of the array into account. Let's look at the array after each iteration through the loop:
{ 1, 4, 3, 5, 7, 9 } //initial state
{ 1, 2, 3, 5, 7, 9 } // after 1st iteration (index 0). Value at index 0 is 1, so item as index 1 is set to 2
{ 1, 2, 2, 5, 7, 9 } // after 2nd iteration (index 1). Value at index 1 is now 2, so item at index 2 is set to 2
{ 1, 2, 2, 5, 7, 9 } // after 3rd iteration (index 2). Value at index 2 is now 2, so item at index 2 is set to 2
{ 1, 2, 2, 5, 7, 2 } // after 4th iteration (index 3). Value at index 3 is 5, so item at index 5 is set to 2
// The 5th iteration (index 4). Value at index 4 is 7, which is beyond the end of the array
For the why of this... it sounds like you're used to a more dynamic language. Some these other languages, like php or Javascript, don't have real arrays at all in the pure computer science sense. Instead, they have collection types they'll call an array, but when you get down to it are really something different.
C# has real arrays, and real arrays have a fixed size. If what you really want is a collection, C# has collections, too. You can use List<T> objects, for example, to get an array-like collection you can append to easily.
For the other languages, the results vary depending on what you're talking about, but for the most permissive the result of your 5th iteration is something like this:
{ 1, 2, 2, 5, 7, 2, ,2 }
Note the missing value at index 6. That kind of things leads to mistakes that slip through your tests and don't show up until run-time. You also need to start wondering just how densely or sparsely the array will be filled, because the best strategy for handling these arrays can vary wildly depending on your answer... everything from just a big backing array with empty nodes that the programmer has to know about all the way to Hashtables and Dictionaries. And, by the way, C# again has these options available to you.
You need to step through your code in a debugger.
A for statement is more like a while statement, not like a foreach.
The line int[] numbers = { 1, 4, 3, 5, 7, 9 }; create this:
numbers[0] = 1;
numbers[1] = 4;
numbers[2] = 3;
numbers[3] = 5;
numbers[4] = 7;
numbers[5] = 9;
Your foreach statement does this:
numbers[1] = 2;
numbers[4] = 2;
numbers[3] = 2;
numbers[5] = 2;
numbers[7] = 2; <- this line overflows your array!
numbers[9] = 2; <- and so would this.
You have to learn the difference between an array index and an array value.
You need to create counter, in other case you trying to access item outside of array
int[] numbers = new int[]{ 1, 4, 3, 5, 7, 9 };
int i = 0;
foreach (int item in numbers)
{
numbers[i] = 2;
i++;
}
// Print the items of the array
foreach (int item in numbers)
{
Console.WriteLine(item);
}

Divide List<string> into sublists of equal size N

I'm trying to slice a List of strings (size N) and return a range based on the list being sliced into equal parts (X).
So for instance, if I have a list of say 10 elements, and my number of tiers is 5.
Elements 0 and 1 are tier 1. Elements 2 and 3 are tier 2. At the end of the method I return the tier specified in the params.
What I'm struggling with is if the list count isn't divisible by the number of tiers. For instance, 23 / 5 = 4.6. So that means they'll be 5 sets of 4, and then 3 left over. I'd like the result to be 5 tiers of 5, 5, 5, 5, 3 (with the final tier just the remaining number of elements).
I've included my code so far, but I'm really stuck on how to ensure the list sizes are as equal as possible and how to handle remainders.
// Gets a list and returns a range by the tier specified
public List<string> GetRangeByTierIndex(List<string> listToDivide, int numOfTiers, int tierIndexToGet)
{
int numOfElementsPerList = listToDivide.Count / numOfTiers;
int index = (tierToGet - 1) * numOfElementsPerList;
return listToDivide.GetRange(index, numOfElementsPerList);
}
Note: Forgot to mention, I can't use LINQ for this either (AOT and iOS problems).
The idea is to use modulo which is remainder of division of listToDivide.Count by numOfTiers. If that remainder is greater than zero all tiers which index is less or equal to that remainder will have one more element. Because of that, start index of every tier must be corrected also. Note that I haven't wrote any checks (like if number of elements in main list is zero, numOfTiers < tierIndexToGet, etc... but you can add those checks if you need). Also, this will, for your example, give lists with 5, 5, 5, 4, 4 elements instead of 5, 5, 5, 5, 3 but I think this is even better. Anyway I hope it will be good for your needs. Code should look something like:
public List<string> GetRangeByTierIndex(List<string> listToDivide, int numOfTiers, int tierIndexToGet)
{
int remaining = listToDivide.Count % numOfTiers;
int numOfElementsPerList = listToDivide.Count / numOfTiers;
int index = (tierIndexToGet - 1) * numOfElementsPerList;
if (remaining > 0)
{
// most increase position of index because of numOfElementsPerList correction bellow
index += tierIndexToGet > remaining ? remaining : tierIndexToGet - 1;
// first 'remaining-th' tiers will have +1 element
numOfElementsPerList += tierIndexToGet <= remaining ? 1 : 0;
}
return listToDivide.GetRange(index, numOfElementsPerList);
}
Example: 23 and 5.
23/5 = 4 // 4 tiers of 5 - use integer division
23%5 = 3 // 1 tier of 3

Assigning list with one value after index

is it possible to block set a list with a value after a particular index, fast?
How is the below logic can be written in C#?. I could use a different collection if I can do the same.
List<int> mylist = new List<int>(10);
int index = 3;
int value = 11;
mylist.SetValuesafterIndex(index, value);
EDIT:
Clarification: I mean, I want indices 3 to 9 inclusive to be set to value 11
The method that you want is not provided by List<T>. So, whilst it is something of a statement of the obvious, you could perfectly well write:
for (int i = index; i < list.Count; i++)
list[i] = value;
The only other option that springs to mind is to use RemoveRange to remove all items from Index to the end, and then call AddRange to add your new values.
Since you state performance as being an issue, you should carry out some measurements of the options with your real-world usage scenarios.
Try the following
mylist[index] = value;
It's unclear if you want it to be at index or index + 1. Just adjust the above as appropriate
Not so sure about performance, but an one line answer could be:
myList.AddRange(Enumerable.Repeat(0, index).Concat(Enumerable.Repeat(value, 10 - index)));
You can write a generic method like this:
static void SetRangeValues<T>(List<T> list,int start,int end,T value)
{
if(end > list.Count() || start < 0)
throw new ArgumentOutOfRangeException();
for(int i=start;i<end;i++)
{
list[i] = value;
}
}
And you can use it like this:
var list = new List<int>();
list.AddRange(Enumerable.Range(0,10));
Console.WriteLine("Before: ");
list.ForEach(Console.WriteLine);
SetRangeValues(ref list, 3, 10, 2000);
Console.WriteLine("After: ");
list.ForEach(Console.WriteLine);
// Output:
Before:
0
1
2
3
4
5
6
7
8
9
After:
0
1
2
2000
2000
2000
2000
2000
2000
2000
If you want to set values until the end of the List, simply you can pass list.Count as end parameter:
SetRangeValues(list, 3, list.Count(), 2000);

How do I find sequential integers in a list in C#?

How do I find the longest increasing sub-sequence of integers from a list of integers in C#?
You just need to break in down into a smaller problem, that of finding the length of an increasing sequence given a starting point.
In pseudo-code, that's something like:
def getSeqLen (int array[], int pos):
for i = pos + 1 to array.last_element:
if array[i] <= array[i-1]:
return i - pos
return array.last_element + 1 - pos
Then step through the array, looking at these individual sequences. You know that the sequences have to be separated at specific points since otherwise the sequences would be longer. In other words, there is no overlap of these increasing sequences:
def getLongestSeqLen (int array[]):
pos = 0
longlen = 0
while pos <= array.last_element:
len = getSeqLen (array, pos)
if len > longlen:
longlen = len
pos = pos + len
return longlen
By way of graphical explanation, consider the following sequence:
element#: 0 1 2 3 4 5 6 7 8 9 10 11 12
value: 9 10 12 7 8 9 6 5 6 7 8 7 8
^ ^ ^ ^ ^
In this case, the ^ characters mark the unambiguous boundaries of a subsequence.
By starting at element 0, getSeqLen returns 3. Since this is greater than the current longest length of 0, we save it and add 3 to the current position (to get 3).
Then at element 3, getSeqLen returns 3. Since this is not greater than the current longest length of 3, we ignore it but we still add 3 to the current position (to get 6).
Then at element 6, getSeqLen returns 1. Since this is not greater than the current longest length of 3, we ignore it but we still add 1 to the current position (to get 7).
Then at element 7, getSeqLen returns 4. Since this is greater than the current longest length of 3, we save it and add 4 to the current position (to get 11).
Then at element 11, getSeqLen returns 2. Since this is not greater than the current longest length of 4, we ignore it but we still add 2 to the current position (to get 13).
Then, since element 13 is beyond the end, we simply return the longest length found (4).
You want what is known as patience sorting. It can compute the length, and find the sequence.
Here is my solution:
public static int[] FindLongestSequence(int[] seq)
{
int c_min = 0, c_len = 1;
int min = 1, len = 0;
for (int i = 0; i < seq.Length - 1; i++)
{
if(seq[i] < seq[i+1])
{
c_len++;
if (c_len > len)
{
len = c_len;
min = c_min;
}
} else
{
c_min = i+1;
c_len = 1;
}
}
return seq.Skip(min).Take(len).ToArray();
}
}
Create three variables: two integer lists and an integer. Set the integer initially to int.MinValue. As you iterate the list, if the current value is greater than your integer variable, append it to list 1. When this is not the case, clear list 1, but first copy list 1 to list 2 if it is longer than list 2. When you finish the sequence, return the longer list (and it's length).
As a performance tip too, if your current longest substring is longer than the remainder of the string, you can call it quits there!
I have solved this in O(n log n) time here:
http://www.olhovsky.com/2009/11/extract-longest-increasing-sequence-from-any-sequence/
An item in the final sequence, used to form a linked list.
class SeqItem():
val = 0 # This item's value.
prev = None # The value before this one.
def __init__(self, val, prev):
self.val = val
self.prev = prev
Extract longest non-decreasing subsequence from sequence seq.
def extract_sorted(seq):
subseqs = [SeqItem(seq[0], None)] # Track decreasing subsequences in seq.
result_list = [subseqs[0]]
for i in range(1, len(seq)):
result = search_insert(subseqs, seq[i], 0, len(subseqs))
# Build Python list from custom linked list:
final_list = []
result = subseqs[-1] # Longest nondecreasing subsequence is found by
# traversing the linked list backwards starting from
# the final smallest value in the last nonincreasing
# subsequence found.
while(result != None and result.val != None):
final_list.append(result.val)
result = result.prev # Walk backwards through longest sequence.
final_list.reverse()
return final_list
Seq tracks the smallest value of each nonincreasing subsequence constructed.
Find smallest item in seq that is greater than search_val.
If such a value does not exist, append search_val to seq, creating the
beginning of a new nonincreasing subsequence.
If such a value does exist, replace the value in seq at that position, and
search_val will be considered the new candidate for the longest subseq if
a value in the following nonincreasing subsequence is added.
Seq is guaranteed to be in increasing sorted order.
Returns the index of the element in seq that should be added to results.
def search_insert(seq, search_val, start, end):
median = (start + end)/2
if end - start < 2: # End of the search.
if seq[start].val > search_val:
if start > 0:
new_item = SeqItem(search_val, seq[start - 1])
else:
new_item = SeqItem(search_val, None)
seq[start] = new_item
return new_item
else: # seq[start].val <= search_val
if start + 1 < len(seq):
new_item = SeqItem(search_val, seq[start])
seq[start + 1] = new_item
return new_item
else:
new_item = SeqItem(search_val, seq[start])
seq.append(new_item)
return new_item
if search_val < seq[median].val: # Search left side
return search_insert(seq, search_val, start, median)
else: #search_val >= seq[median].val: # Search right side
return search_insert(seq, search_val, median, end)
Use the code like so:
import random
if __name__ == '__main__':
seq = []
for i in range(100000):
seq.append(int(random.random() * 1000))
print extract_sorted(seq)
One way to do it is with help from the Aggregate method:
var bestSubSequence = listOfInts.Skip(1).Aggregate(
Tuple.Create(int.MinValue, new List<int>(), new List<int>()),
(curr, next) =>
{
var bestList = curr.Item2.Count > curr.Item3.Count ? curr.Item2 : curr.Item3;
if (curr.Item1 > next)
return Tuple.Create(next, new List<int> {next}, bestList);
curr.Item2.Add(next);
return Tuple.Create(next, curr.Item2, bestList);
}).Item3;
It did not turn out as well as I had hoped when I started writing it and I think the other more direct ways to do it is better and easier to follow, but it might give a different perspective on how these kinds of tasks can be solved.

Categories