How to make the variable of an if statement dynamic - c#

Hi I am trying to loop through a set of int variables and do an if on each one. I.e.
int a0, a1, a2,a3;
for (int I=0; I < 3; I++)
{
if("a" + I > 10)
{
// do something
}
}
Is this possible?

If you want to iterate you need a collection
IEnumerable<int> numbers = new List<int> { 1, 2, 3, 10 };
foreach (var item in numbers)
{
if(item > 10)
{
// do something
}
}
When you write "a" + I all you are doing is create a string that is a concatenation of the two pieces and is not the parameter you defined before
You can then proceed and use linq:
var filtered = numbers.Where(item => item > 10)

You can use array as variable so you can iterate that :
int[] a = new int[3];
a[0] = 5;
a[1] = 10;
a[2] = 15;
for (int I = 0; I < 3; I++)
{
if (a[I] > 10)
{
// do something, example:
Console.WriteLine(a[I])
}
}
Result :
15

Related

How do i select an array range where array index is greater than a certain value C#

I am trying to select 15 events with each iteration of i.
In the first loop of i, I want to add validbatch[0 to 15].
Next loop validbatch[15 to 30] and so on.
How do I filter or select a subarray from valid batch where the index > i*15?
for (j = counter; j < i * 15; j++)
{
crm x = new crm();
x.EmailAddress = EMAILaddress[j];
Properties prop = new Properties();
prop.new_insideroptout = optin[j];
validBatch[j] = new SampleEventBody() { Id = Int64.Parse(ID[j]), Publication = subscriptionname[j], CrmProperties = x, Properties = prop };
counter++;
}
sendTasks.Add(client.SendEventBatchAsync(validBatch.Where<EventBody>(validbatch => validBatch[j] > validbatch[i * 15 - 1])
You could use the following generic method to split an array.
public static IEnumerable<IEnumerable<T>> SplitArray<T>(this T[] array, int size)
{
for (var i = 0; i < (float)array.Length / size; i++)
{
yield return array.Skip(i * size).Take(size);
}
}
And then you can call it like
var splitedArray = array.SplitArray(2);
I hope you are looking for this.

Digit difference sort

So I am trying to solve this task "Digit Difference Sort" on Codefights
Given an array of integers, sort its elements by the difference of their largest and smallest digits.
In the case of a tie, that with the larger index in the array should come first.
Example
For a = [152, 23, 7, 887, 243], the output should be digitDifferenceSort(a) = [7, 887, 23, 243, 152].
Here are the differences of all the numbers:
152: difference = 5 - 1 = 4;
23: difference = 3 - 2 = 1;
7: difference = 7 - 7 = 0;
887: difference = 8 - 7 = 1;
243: difference = 4 - 2 = 2.
23 and 887 have the same difference, but 887 goes after 23 in a, so in the sorted array it comes first.
I have an issue with two numbers having the same difference. Here's what I wrote so far:
int[] digitDifferenceSort(int[] a) {
return a.OrderBy(x => difference(x)).ToArray();
}
int difference(int x)
{
int min = 9, max = 0;
do
{
int tmp = x % 10;
min = Math.Min(min, tmp);
max = Math.Max(max, tmp);
} while ((x /= 10) > 0);
return max - min;
}
Didn't do much (for example the output is still [7, 23, 887, 243, 152] rather than [7, 887, 23, 243, 152])
How do I make element with larger index come first in result? What should I use instead of OrderBy?
I don't consider your difference method, i assume it works fine.
To your question: you have to keep revered order of the array (that the items with the same difference arrive will be sorted reverse). To do it, you could just reverse you input array: all items with not identical difference will be ordered correctly, and with the same differece will be ordered reversed:
int[] digitDifferenceSort(int[] a)
{
return a.Reverse().OrderBy(x => difference(x)).ToArray();
}
Following is my code for the above question digit difference sort. I am also getting output when running in Eclipse but when I paste the code on code signal it gives me a null pointer exception.
package NormalPrograms;
import java.util.ArrayList;
import java.util.Collections;
public class DigitDifferenceSort {
// For index wise sorting in descending order
public static int[] sortingnumberindexwise(int[] a, ArrayList<Integer> index) {
int k = 0;
int[] res = new int[index.size()];
int[] finalres = new int[index.size()];
for (int i = a.length - 1; i >= 0; i--) {
for (int j = 0; j < index.size(); j++) {
if (a[i] == (int) index.get(j)) {
res[k] = i;
index.remove(j);
k++;
break;
}
}
}
int g = 0;
k = 0;
for (int i = 0; i < res.length; i++) {
finalres[g] = a[res[k]];
g++;
k++;
}
return finalres;
}
public static int[] finddigitDifferenceandSort(int[] p) {
int[] finres = new int[p.length];
for (int i = 0; i < finres.length; i++) {
finres[i] = p[i];
}
// This finres array act as an temp array and reused to make final result array
int digit = 0;
ArrayList<Integer> A = new ArrayList<Integer>();
ArrayList<ArrayList<Integer>> B = new ArrayList<ArrayList<Integer>>();
for (int i = 0; i < 10; i++) {
B.add(new ArrayList<Integer>());
}
for (int i = 0; i < p.length; i++) {
int temp = 0;
temp = p[i];
while (p[i] > 0) {
digit = p[i] % 10;
p[i] /= 10;
A.add(digit);
}
int b = Collections.max(A);
int c = Collections.min(A);
int diff = b - c;
B.get(diff).add(temp);
A.clear();
}
for (int i = 0; i < B.size(); i++) {
if (B.get(i).size() > 1) {
ArrayList<Integer> C = new ArrayList<Integer>();
for (int k = 0; k < B.get(i).size(); k++) {
C.add(B.get(i).get(k));
}
B.get(i).clear();
for (int j : sortingnumberindexwise(finres, C)) {
B.get(i).add(j);
}
} else {
continue;
}
}
int k = 0;
for (int i = 0; i < B.size(); i++) {
for (int j = 0; j < B.get(i).size(); j++) {
if (B.get(i).size() == 0)
continue;
else {
finres[k] = B.get(i).get(j);
k++;
}
}
}
return finres;
}
public static void main(String[] args) {
int[] a = { 12, 21, 1, 1, 1, 2, 2, 3 };
for (int i : finddigitDifferenceandSort(a)) {
System.out.print(i + " ");
}
}
}

Better way of inserting numbers into an array while sorting it

Let's say I want to insert values into an array while at the same time sorting it.
This was my solution:
int[] arr = new int[5];
int k;
arr[0] = int.Parse(Console.ReadLine());
for (int i = 1; i < arr.Length; i++)
{
int num = int.Parse(Console.ReadLine());
for (k = i; k > 0 && num < arr[k - 1];--k) arr[k] = arr[k - 1];
arr[k] = num;
}
I know I didn't handle exceptions, I'm just talking about the code itself.
Is there a better way of doing this?
You can use a SortedSet<>, that gets automatically sorted as you add items.
var numbers = new SortedSet<int>()
{
4,
9,
6,
3
};
foreach (var number in numbers)
{
Console.WriteLine(number);
}
If it doesn't have to be array you could do this:
static void Main(string[] args)
{
List<int> list = new List<int>
{
1,
2,
7,
10
};
int k = int.Parse(Console.ReadLine());
list.Add(k);
list.Sort();
}
Edit: if you want to sort when inserting you could do this:
int k = int.Parse(Console.ReadLine());
int i = list.Where(x => x > k).Min();
int index = list.IndexOf(i);
list.Insert(index, k);
You can use a List and convert it into an array. When you maintain your list ordered at all time you can use the list's BinarySearch method to get the insert index:
const int length = 5;
List<int> result = new List<int>(length);
for (int i = 0; i < length; i++) {
int num = int.Parse(Console.ReadLine());
int insertIndex = result.BinarySearch(num);
if (insertIndex < 0) {
insertIndex = ~insertIndex;
}
result.Insert(insertIndex, num);
}
int[] arr = result.ToArray();
The binary search is much faster than the linear search you are currently performing. You won't see that with your current 5 values. You would defenitely see it with larger lists (hundrets or thousands of values).

Adding all possible sum, from a list of values to that same list of values in a list

I have a List containing values 10, 20, 30, 50,30
i would like to add all possible sum of the values present in the list that is:
10+20 = 30
10+30 = 40
10+50 = 60
20+30 = 50
10+20+30+50+30
the list i declared is something like this:
List list = new List();
and values(i.e 10, 20, 30, 50, 30) were added using a for loop.
Done so far:
List<int> list = new List<int>();
list.Add(3);
list.Add(7);
list.Add(8);
list.Add(1);
var length = list.Count();
for (int i = 0; i < length; i++)
{
var sum = 0;
sum = sum + list[i];
for (int j = i + 1; j < length; j++)
{
sum = sum + list[j];
list.Add(list[i] + list[j]);
}
list.Add(sum);
}
This works for me:
Func<IEnumerable<int>, IEnumerable<int>> getAllSelectionSums = null;
getAllSelectionSums = xs =>
{
if (!xs.Any())
{
return new [] { 0 };
}
else
{
return
from h in xs.Take(1).Concat(new [] { 0 })
from t in getAllSelectionSums(xs.Skip(1))
select h + t;
}
};
So, given var source = new [] { 3, 7, 8, 1 }; as the input I get the following result:
This is typically done with two for loops if you want only 2 elements. However, if you wanted to pick all combinations from 1 to all elements, you are looking for the power set.
I will answer it for just picking 2
List<int> sums = new List<int>();
for(int first = list.Length - 1; first >= 1; first--)
{
for(int second = first - 1; second >= 0; second--)
{
sums.Add(list[first] + list[second]);
}
}
You should also bracket this to make sure your list has at least 2 items in it...
Edit:
Since you've updated your question to show your implementation, I'll include code to generate power sets
public IEnumerable<IEnumerable<int>> PowerSet(IEnumerable<int> initialSet)
{
foreach (IEnumerable<int> set in PowerSetRecursive(initialSet, initialSet.Count() - 1))
{
yield return set;
}
}
private IEnumerable<IEnumerable<int>> PowerSetRecursive(IEnumerable<int> initialSet, int index)
{
if (index == 0)
{
yield return new int[] { };
yield return new int[] { initialSet.ElementAt(index) };
}
else
{
foreach (IEnumerable<int> set in PowerSetRecursive(initialSet, index - 1))
{
yield return new HashSet<int>(set);
yield return new HashSet<int>(set) { initialSet.ElementAt(index) };
}
}
}
You would then loop like this
foreach (IEnumerable<int> set in PowerSet(new int[] { 1, 2, 3, 4 }))
{
Console.WriteLine(set.Sum());
}

Order an array in a specific order

I have this array of integers:-
int[] numbers = new int[] { 10, 20, 30, 40 };
I am trying to create an array which will have first element, last element, second element, second-last element and so on..
So, my resulting output will be:-
int[] result = {10,40,20,30};
This was my approach, in one loop start from first and go till the middle & in second loop start from last and get to the middle and select items accordingly, but I totally messed it up. Here is my attempted code:-
private static IEnumerable<int> OrderedArray(int[] numbers)
{
bool takeFirst = true;
if (takeFirst)
{
takeFirst = false;
for (int i = 0; i < numbers.Length / 2; i++)
{
yield return numbers[i];
}
}
else
{
takeFirst = true;
for (int j = numbers.Length; j < numbers.Length / 2; j--)
{
yield return numbers[j];
}
}
}
Need Help.
You might try this:
int[] result = numbers.Zip(numbers.Reverse(), (n1,n2) => new[] {n1, n2})
.SelectMany(x =>x)
.Take(numbers.Length)
.ToArray();
Explanation: This approach basically pairs up the elements of the original collection with the elements of its reverse ordered collection (using Zip). So you get a collection of pairs like [first, last], [second, second from last], etc.
It then flattens those collection of pairs into a single collection (using SelectMany). So the collection becomes [first, last, second, second from last,...].
Finally, we limit the number of elements to the length of the original array (n). Since we are iterating through twice as many elements (normal and reverse), it works out that iterating through n elements allow us to stop in the middle of the collection.
As a different approach, this is a modification on your existing method:
private static IEnumerable<int> OrderedArray(int[] numbers)
{
var count = (numbers.Length + 1) / 2;
for (int i = 0; i < count; i++)
{
yield return numbers[i];
int reverseIdx = numbers.Length - 1 - i;
if(i != reverseIdx)
yield return numbers[reverseIdx];
}
}
ok,
public static class Extensions
{
public static IEnumerable<T> EndToEnd<T>(this IReadOnlyList<T> source)
{
var length = source.Count;
var limit = length / 2;
for (var i = 0; i < limit; i++)
{
yield return source[i];
yield return source[length - i - 1];
}
if (length % 2 > 0)
{
yield return source[limit];
}
}
}
Which you could use like this,
var result = numbers.EndToEnd().ToArray();
more optimally,
public static class Extensions
{
public static IEnumerable<T> EndToEnd<T>(this IReadOnlyList<T> source)
{
var c = source.Count;
for (int i = 0, f = 0, l = c - 1; i < c; i++, f++, l--)
{
yield return source[f];
if (++i == c)
{
break;
}
yield return source[l];
}
}
}
no divide or modulus required.
With a simple for;
int len = numbers.Length;
int[] result = new int[len];
for (int i = 0, f = 0, l = len - 1; i < len; f++, l--)
{
result[i++] = numbers[f];
if (f != l)
result[i++] = numbers[l];
}
Based on Selman22's now deleted answer:
int[] numbers = new int[] { 10, 20, 30, 40 };
int[] result = numbers
.Select((x,idx) => idx % 2 == 0
? numbers[idx/2]
: numbers[numbers.Length - 1 -idx/2])
.ToArray();
result.Dump();
(The last line is LinqPad's way of outputting the results)
Or in less LINQy form as suggested by Jeppe Stig Nielsen
var result = new int[numbers.Length];
for (var idx = 0; idx < result.Length; idx++) {
result[idx] = idx % 2 == 0 ? numbers[idx/2] : numbers[numbers.Length - 1 -idx/2];
}
The principle is that you have two sequences, one for even elements (in the result) and one for odd. The even numbers count the first half of the array and the odds count the second half from the back.
The only modification to Selman's code is adding the /2 to the indexes to keep it counting one by one in the right half while the output index (which is what idx basically is in this case) counts on.
Came up with this
static void Main(string[] args)
{
List<int> numbers = new List<int>() { 10, 20, 30, 40, 50, 60, 70};
List<int> numbers2 = new List<int>();
int counter1 = 0;
int counter2 = numbers.Count - 1;
int remainder = numbers.Count % 2 == 0 ? 1: 0;
while (counter1-1 < counter2)
{
if (counter1 + counter2 % 2 == remainder)
{
numbers2.Add(numbers[counter1]);
counter1++;
}
else
{
numbers2.Add(numbers[counter2]);
counter2--;
}
}
string s = "";
for(int a = 0; a< numbers2.Count;a++)
s+=numbers2[a] + " ";
Console.Write(s);
Console.ReadLine();
}
This late answer steals a lot from the existing answers!
The idea is to allocate the entire result array at once (since its length is known). Then fill out all even-indexed members first, from one end of source. And finally fill out odd-numbered entries from the back end of source.
public static TElement[] EndToEnd<TElement>(this IReadOnlyList<TElement> source)
{
var count = source.Count;
var result = new TElement[count];
for (var i = 0; i < (count + 1) / 2; i++)
result[2 * i] = source[i];
for (var i = 1; i <= count / 2; i++)
result[2 * i - 1] = source[count - i];
return result;
}
Came up with this
public int[] OrderedArray(int[] numbers)
{
int[] final = new int[numbers.Length];
var limit=numbers.Length;
int last = numbers.Length - 1;
var finalCounter = 0;
for (int i = 0; finalCounter < numbers.Length; i++)
{
final[finalCounter] = numbers[i];
final[((finalCounter + 1) >= limit ? limit - 1 : (finalCounter + 1))] = numbers[last];
finalCounter += 2;
last--;
}
return final;
}

Categories

Resources