Related
There is a list of short. The values of it doesn't matter like:
List<short> resultTemp = new List<short>{1,2,3,4,5,6,7,8,9...};
This code should reduse the result list count by removing each Nth item from it.
Example 1:
List<short>{1,2,3,4,5,6,7,8,9,10}.Count == 10;
var targetItemsCount = 5;
result should be {1,3,5,7,9} and result.Count should be == 5
Example 2:
List<short>{1,2,3,4,5,6,7,8,9}.Count == 9;
var targetItemsCo:nt = 3;
result should be {1,4,7} and result.Count should be == 3
But it should stop to remove it, somewhere for make result count equal targetItemsCount (42 in this code, but its value else doesn't matter).
The code is:
var currentItemsCount = resultTemp.Count;
var result = new List<short>();
var targetItemsCount = 42;
var counter = 0;
var counterResettable = 0;
if (targetItemsCount < currentItemsCount)
{
var reduceIndex = (double)currentItemsCount / targetItemsCount;
foreach (var item in resultTemp)
{
if (counterResettable < reduceIndex ||
result.Count + 1 == currentItemsCount - counter)
{
result.Add(item);
counterResettable++;
}
else
{
counterResettable = 0;
}
counter++;
}
}
And the resault.Count in this example equals 41, but should be == targetItemsCount == 42;
Ho do I remove each N item in List untill List.Count more then target value with C#?
If my understanding is correct:
public static void run()
{
var inputs =
new List<Input>{
new Input{
Value = new List<int> { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 },`
TargetCount = 5, ExpectedOutput= new List<int>{1,3,5,7,9}
},
new Input{
Value = new List<int> { 1, 2, 3, 4, 5, 6, 7, 8, 9 },
TargetCount = 3, ExpectedOutput= new List<int>{1,4,7}
},
};
foreach (var testInput in inputs)
{
Console.WriteLine($"# Input = [{string.Join(", ", testInput.Value)}]");
var result = Reduce(testInput.Value, testInput.TargetCount);
Console.WriteLine($"# Computed Result = [{string.Join(", ", result)} ]\n");
}
}
static List<int> Reduce(List<int> input, int targetItemsCount)
{
while (input.Count() > targetItemsCount)
{
var nIndex = input.Count() / targetItemsCount;
input = input.Where((x, i) => i % nIndex == 0).ToList();
}
return input;
}
class Input
{
public List<int> ExpectedOutput;
public List<int> Value;
public int TargetCount;
}
Result :
Input = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
Computed Result = [1, 3, 5, 7, 9 ]
Input = [1, 2, 3, 4, 5, 6, 7, 8, 9]
Computed Result = [1, 4, 7 ]
To guarantee you get the expected number of selected items:
double increment = Convert.ToDouble(resultTemp.Count) / targetItemsCount;
List<short> result = Enumerable.Range(0, targetItemsCount).
Select(x => resultTemp[(int)(x * increment)]).
ToList();
Note that in the following case
List<short>{1,2,3,4,5,6,7,8,9}.Count == 9;
var targetItemsCount = 6;
The result will be [1, 2, 4, 5, 7, 8], i.e. rounding the index down when needed
Also, you'll need to add validation (targetItemsCount > 0, targetItemsCount < resultTemp.Count...)
Link to Fiddle
Give this a try:
var resultTemp = Enumerable.Range(1, 9).ToList();
var targetItemsCount = 3;
var roundingError = resultTemp.Count % targetItemsCount;
var reduceIndex = (resultTemp.Count - roundingError) / targetItemsCount;
List<int> result;
if (reduceIndex <= 1)
result = resultTemp.Take(targetItemsCount).ToList();
else
result = resultTemp.Where((a, index) => index % reduceIndex == 0).Take(targetItemsCount).ToList();
Tried it with your given example, also gave 42 a spin with a list of 1 to 100 it will remove every 2nd item till it reaches 42, so the last entry in the list would be 83.
As I said, give it a try and let me know if it fits your requirement.
Im new to c# then my supervisor ask me to find all possible combination of given set of numbers and I must set the maximum for the combinations. The combinations I already get but for set the maximum number can't be done.The maximum number is for the combinations. From my image it have 5,4 and 3 row that is all the possible combinations. but I just want to set only output that have 3 row only will be display. I have tried many way but still can't get it. Sorry for my bad english.
Here are the code.
class Program
{
static void Main(string[] args)
{
string input;
decimal goal;
decimal element;
int max = 2;
do
{
Console.WriteLine("Please enter the target:");
input = Console.ReadLine();
}
while (!decimal.TryParse(input, out goal));
Console.WriteLine("Please enter the numbers (separat`enter code here`ed by spaces)");
input = Console.ReadLine();
string[] elementsText = input.Split(' ');
List<decimal> elementsList = new List<decimal>();
foreach (string elementText in elementsText)
{
if (decimal.TryParse(elementText, out element))
{
elementsList.Add(element);
}
}
Solver solver = new Solver();
List<List<decimal>> results = solver.Solve(goal, elementsList.ToArray());
//foreach (List<decimal> result in results)
//{
// foreach (decimal value in result)
// {
// Console.Write("{0}\t", value);
// }
// Console.WriteLine();
//}
for (int i = 0; i <= results.Count; i++)
{
int x = results.SelectMany(list => list).Distinct().Count();
if (x <= max)
{
for (int j = 0; j <= max; j++)
{
Console.Write("{0}\t", results[i][j]);
}
Console.WriteLine();
}
}
Console.ReadLine();
}
}
here is the ouput
From the comments in the question and other answers, it seems to me that the OP already knows how to calculate all the combinations whose sum is a target number (that's probably what the Solver in the question does). What I think he wants is to get the combination with the least amount of numbers.
I have a couple of solutions, since I'm not really sure what you want:
1) If you want all the combinations with the least of amount of numbers, do this:
public static void Main()
{
// Here I have hard-coded all the combinations,
// but in real life you would calculate them.
// Probably using your `Solver` or any of the other answers in this page.
var combinations = new List<List<decimal>>{
new List<decimal>{ 1, 2, 3, 4, 5 },
new List<decimal>{ 1, 2, 5, 7 },
new List<decimal>{ 1, 3, 4, 7 },
new List<decimal>{ 1, 3, 5, 6 },
new List<decimal>{ 2, 3, 4, 6 },
new List<decimal>{ 2, 6, 7 },
new List<decimal>{ 3, 5, 7 },
new List<decimal>{ 4, 5, 6 }
};
// Filter the list above to keep only the lists
// that have the least amount of numbers.
var filteredCombinations = LeastNumbers(combinations);
foreach (var combination in filteredCombinations)
{
Console.WriteLine(string.Join("\t", combination));
}
}
public static List<List<decimal>> LeastNumbers(List<List<decimal>> combinations)
{
// First get the count for each combination, then get the minimum of those.
int smallestLength = combinations.Select(l => l.Count).Min();
// Second, only keep those combinations which have a count equals to the value calculated above.
return combinations.Where(l => l.Count == smallestLength).ToList();
}
Output:
2 6 7
3 5 7
4 5 6
2) If you only want one of the combinations with the least amount of numbers, do this instead:
public static void Main()
{
// Here I have hard-coded all the combinations,
// but in real life you would calculate them.
// Probably using your `Solver` or any of the answers in this page.
var combinations = new List<List<decimal>>{
new List<decimal>{ 1, 2, 3, 4, 5 },
new List<decimal>{ 1, 2, 5, 7 },
new List<decimal>{ 1, 3, 4, 7 },
new List<decimal>{ 1, 3, 5, 6 },
new List<decimal>{ 2, 3, 4, 6 },
new List<decimal>{ 2, 6, 7 },
new List<decimal>{ 3, 5, 7 },
new List<decimal>{ 4, 5, 6 }
};
// Filter the list above to keep only the first list
// that has the least amount of numbers.
var filteredCombination = LeastNumbers(combinations);
Console.WriteLine(string.Join("\t", filteredCombination));
}
public static List<decimal> LeastNumbers(List<List<decimal>> combinations)
{
// First get the count for each combination,
// then get the minimum of those.
int smallestLength = combinations.Select(l => l.Count).Min();
// Second, get only one of the combinations that have a count
// equals to the value calculated above.
return combinations.First(l => l.Count == smallestLength);
}
Output:
2 6 7
3) The OP also mentioned a max value of 3. So, if you know that number before-hand, you can do this:
public static void Main()
{
// Here I have hard-coded all the combinations,
// but in real life you would calculate them.
// Probably using your `Solver` or any of the answers in this page.
var combinations = new List<List<decimal>>{
new List<decimal>{ 1, 2, 3, 4, 5 },
new List<decimal>{ 1, 2, 5, 7 },
new List<decimal>{ 1, 3, 4, 7 },
new List<decimal>{ 1, 3, 5, 6 },
new List<decimal>{ 2, 3, 4, 6 },
new List<decimal>{ 2, 6, 7 },
new List<decimal>{ 3, 5, 7 },
new List<decimal>{ 4, 5, 6 }
};
// This must be known before hand.
// That's why I think my first solution is more usefull.
int max = 3;
// Filter the list above to keep only the lists
// that have a count less or equal to a predetermined maximum.
var filteredCombinations = FilterByMaxLength(combinations, max);
foreach (var combination in filteredCombinations)
{
Console.WriteLine(string.Join("\t", combination));
}
}
public static List<List<decimal>> FilterByMaxLength(List<List<decimal>> combinations, int max)
{
return combinations.Where(l => l.Count <= max).ToList();
}
2 6 7
3 5 7
4 5 6
Note: In a real scenario, you would also want to do some checking in those functions, like checking for null or empty lists.
Here is my try, you can tweak this depending on what you want:
using System.Collections.Generic;
using System.Linq;
private static void GetMaxPermutation(int max)
{
var numbers = new[] { 1, 2, 4, 6, 7 };
var results = new List<IEnumerable<int>>();
for (int i = 1; i <= numbers.Length; i++)
{
results.AddRange(GetPermutations(numbers, i));
}
Console.WriteLine("Result: " + string.Join(" ", results.Select(x => new { Target = x, Sum = x.Sum() }).Where(x => x.Sum <= max).OrderByDescending(x => x.Sum).FirstOrDefault().Target));
}
private static IEnumerable<IEnumerable<T>> GetPermutations<T>(IEnumerable<T> items, int count)
{
int i = 0;
foreach (var item in items)
{
if (count == 1)
yield return new T[] { item };
else
{
foreach (var result in GetPermutations(items.Skip(i + 1), count - 1))
yield return new T[] { item }.Concat(result);
}
++i;
}
}
I got this permutations method from here
Hard to find what you're trying to do, is something like this
List<string> numbers = new List<string>(){"1","2","3","4","5"};
List<string> possibleCombination = GetCombination(numbers, new List<string>(), "");
Console.Write(string.Join(", ",possibleCombination.Distinct().OrderBy(itm => itm)));
The method
static List<string> GetCombination(List<string> list, List<string> combinations, string sumNum, bool addNumberToResult = false)
{
if (list.Count == 0) {
return combinations;
}
string tmp;
for (int i = 0; i <= list.Count - 1; i++) {
tmp = string.Concat(sumNum , list[i]);
if(addNumberToResult){
combinations.Add(tmp);
}
List<string> tmp_list = new List<string>(list);
tmp_list.RemoveAt(i);
GetCombination(tmp_list,combinations,tmp, true);
}
return combinations;
}
C# Fiddle can help you?
I want to find how many values, in an array, are in sequence without sorting.
For Instance, if I have.
int[] arr = new int[] { 0, 1, 2, 3, 4, 5, 6, 9 } //0, 1, 2, 3, 4, 5, 6 are in sequence
int value = HighestSequence(arr);
//value prints 7
int[] arr = new int[] { 0, 4, 1, 2, 3, 4, 7, 9 } //1, 2, 3, 4 are in sequence
int value = HighestSequence(arr);
//value prints 4
int[] arr = new int[] { 0, 1, 2 } //0, 1, 2 is in sequence
int value = HighestSequence(arr);
//value prints 3
You don't specify what should happen if there is more than one subsequence in order, but I've assumed there will be only one.
Try this:
int length = 1;
int[] arr = new int[] { 0, 1, 2, 3, 4, 5, 6, 9 }; //0, 1, 2, 3, 4, 5, 6 are in sequence
//value prints 7
List<int> temp = arr.Zip(arr.Skip(1), (i1, i2) => length += (i2 - i1 == 1 ? 1 : 0)).ToList();
Length will contain the number of integers in sequence where arr[n] == arr[n+1] - 1
Cheers
EDIT:
In the case where there is more than one subsequence that is ordered such that arr[n] == arr[n+1] - 1, we'd need to decide how to handle it.
One way would be to reset the length when we find a value that doesn't meet the criteria:
arr = new int[] { 0, 1, 2, 5, 4, 5, 6, 9 }; //Possible bug ?
length = 1;
temp = arr.Zip(arr.Skip(1), (i1, i2) =>
{
if(i2 - i1 == 1)
{
length++;
}
else
{
length = 1;
}
return i1;
}).ToList();
But then this will not consider the "longest" subsequence, it will return the length of the "last" subsequence in the sequence.
The OP should specify what action he wants in such cases.
EDIT #2:
If we want to have the longest subsequence, then this could be used:
arr = new int[] { 0, 1, 2, 3, 4, 5, 6, 7, 5, 4, 5, 6, 7, 9 }; //Possible bug ?
length = 1;
int longest = length;
temp = arr.Zip(arr.Skip(1), (i1, i2) =>
{
if (i2 - i1 == 1)
{
if (++length > longest)
longest = length;
}
else
{
length = 1;
}
return i1;
}).ToList();
Caching the longest ordered subsequence length. Then use longest instead of length as the result.
EDIT #3:
Edits #1 & 2 should now contain the appropriate solution. I was obviously trying to come up with a solution to a comment from a user too quickly and I didn't realize that the current code in my VS solution was different than the code I posted here.
It is to be mentioned that the OP didn't have those additional constraints, and that I did mention right from the get go that my solution didn't address those additional constraints.
Nonetheless, it was an interesting problem to solve ;-)
Cheers
Try this out. I got the results of (7,4,3). Although Peter is correct about StackOverflow you should give your attempt and say your issue not just ask for an answer. I only provided it because it was a neat challenge.
var set1 = new [] { 0, 1, 2, 3, 4, 5, 6, 9 };
var result1 = HighestSequence(set1);
var set2 = new[] { 0, 4, 1, 2, 3, 4, 7, 9 };
var result2 = HighestSequence(set2);
var set3 = new [] { 0, 1, 2 };
var result3 = HighestSequence(set3);
public int HighestSequence(int[] values)
{
IList<int> sequenceCounts = new List<int>();
var currentSequence = 0;
for (var i = 0; i < values.Length; i++)
{
if (i == (values.Length - 1)) //End edge case
{
if (values[i] - values[i - 1] == 1)
{
currentSequence++;
sequenceCounts.Add(currentSequence);
}
}
else if ((values[i] + 1) == values[i + 1])
{
currentSequence++;
}
else
{
currentSequence++;
sequenceCounts.Add(currentSequence);
currentSequence = 0;
continue;
}
sequenceCounts.Add(currentSequence);
}
return sequenceCounts.Max();
}
Is it possible to iterate nested if statements with a new value with every single iteration? I am trying to build a 1-dimensional cellular automata (for homework, I cannot deny it) and I'm completely new to C# as the following code will no doubt assure. I have tried to create this program using the most straightforward, basic, DIY methods available and have run myself into a rut.
I've got a string of 1's and 0's of length 8, say
string y;
y = "11110000";
I want to break this set up in 8 substring sets of 3 with each set comprising of a value in y together with a single value on either side of it. So counting from 0, the 3rd set would be 110, the 7th would be 001. However substrings will only provide the 1st to 6th set as I can't loop them around y to my liking so I defined the following-
y1=y.Substring(7,1)+y+y.Substring(0,1);
Using y1 I was able to get out all the substrings necessary. These were defined pretty basically as follows-
string a0, a1, a2, a3, a4, a5, a6, a7;
a0 = y1.Substring(0, 3);
a1 = y1.Substring(1, 3);
a2 = y1.Substring(2, 3);
a3 = y1.Substring(3, 3);
a4 = y1.Substring(4, 3);
a5 = y1.Substring(5, 3);
a6 = y1.Substring(6, 3);
a7 = y1.Substring(7, 3);
The rules for the next generation of cellular automata are up to the user in this program- that is to say the user can choose whether or not a substring, say 111->0 or 1 for all iterations. I used (an awful lot of) if tables in the following way for each substring
{
if (a0=="000")
{
Console.Write(a);
}
else if (a0=="001")
{
Console.Write(b);
}
else if (a0 =="010")
{
Console.Write(c);
}
else if (a0 == "011")
{
Console.Write(d);
}
else if (a0 == "100")
{
Console.Write(e);
}
else if (a0 == "101")
{
Console.Write(f);
}
else if (a0 == "110")
{
Console.Write(g);
}
else if (a0 == "111")
{
Console.Write(h);
}
}
where a,b,c,d,e,f,g,h are ints and are rules chosen by the user. So say for instance the user decides that each set 000 should result in a 1 value, then a=1. b corresponds to {0,0,1}, c to {0,1,0} and so on. However the fairly obvious problem with this method is that I end up with only 1 generation in ints that I can't get at. I'd love to replace y1 with this new generation (converted into a string). If this isn't possible let me know!
This link might also clear things up a bit
and here's how you COULD have gotten an A+ :D
private static int[,] HipPriestsHomework()
{
string y = "11110000";
Console.WriteLine(y);
var rules = new[]
{
new {pattern = 0, result = 0},
new {pattern = 1, result = 1},
new {pattern = 2, result = 1},
new {pattern = 3, result = 1},
new {pattern = 4, result = 1},
new {pattern = 5, result = 0},
new {pattern = 6, result = 0},
new {pattern = 7, result = 0},
};
Dictionary<int, int> rulesLookup = new Dictionary<int, int>();
foreach(var rule in rules)
{
rulesLookup.Add(rule.pattern, rule.result);
}
int numGenerations = 10;
int inputSize = y.Length;
int[,] output = new int[numGenerations, inputSize];
int[] items = new int[y.Length];
for(int inputIndex = 0; inputIndex< y.Length; inputIndex++)
{
string token = y.Substring(inputIndex, 1);
int item = Convert.ToInt32(token);
items[inputIndex] = item;
}
int[] working = new int[items.Length];
items.CopyTo(working, 0);
for (int generation = 0; generation < numGenerations; generation++)
{
for (uint y_scan = 0; y_scan < items.Length; y_scan++)
{
int a = items[(y_scan - 1) % items.Length];
int b = items[y_scan % items.Length];
int c = items[(y_scan + 1) % items.Length];
int pattern = a << 2 | b << 1 | c;
var match = rules[pattern];
output[generation, y_scan] = match.result;
working[y_scan] = match.result;
Console.Write(match.result);
}
working.CopyTo(items, 0);
Console.WriteLine();
}
return output;
}
I have a ten element array of integers. I want to sum the elements by group, so for instance I want to add the value at element 0 with the value at element 1, then with the value at element 2, then 3, and so on through to element 9, then add the value at element 1 with the value at 2,3, through to 9 until every group of 2 values has been added together and stored in a variable. I then want to repeat the process with groups of 3, groups of 4, of 5, all the way through to group of 10. Each resultant total being stored in a separate variable. Thus far the only way I can figure out how to do it is thus :-
int i = 0;
int p = 1;
int q = 2;
int r = 3;
while (i < NumArray.Length - 3)
{
while (p < NumArray.Length - 2)
{
while (q < NumArray.Length-1)
{
while (r < NumArray.Length)
{
foursRet += NumArray[i] + NumArray[p] + NumArray[q]+ NumArray[r];
r++;
}
q++;
r = q + 1;
}
p++;
q = p + 1;
r = q + 1;
}
i++;
p = i + 1;
q = i + 2;
r = i + 3;
}
The above is an example of summing groups of 4.
I was wondering if anyone could be kind enough to show me a less verbose and more elegant way of achieving what I want. Many thanks.
Because everything is better with LINQ*:
using System; // Output is below
using System.Linq;
using System.Diagnostics;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
var inputArray = Enumerable.Range(0, 10).ToArray();
var grouped =
from Buckets in Enumerable.Range(1, inputArray.Length)
from IndexInBucket in Enumerable.Range(0, inputArray.Length / Buckets)
let StartPosInOriginalArray = IndexInBucket * Buckets
select new
{
BucketSize = Buckets,
BucketIndex = StartPosInOriginalArray,
Sum = inputArray.Skip(StartPosInOriginalArray).Take(Buckets).Sum()
};
foreach (var group in grouped)
{
Debug.Print(group.ToString());
}
Console.ReadKey();
}
}
} // SCROLL FOR OUTPUT
{ BucketSize = 1, BucketIndex = 0, Sum = 1 }
{ BucketSize = 1, BucketIndex = 1, Sum = 2 }
{ BucketSize = 1, BucketIndex = 2, Sum = 3 }
{ BucketSize = 1, BucketIndex = 3, Sum = 4 }
{ BucketSize = 1, BucketIndex = 4, Sum = 5 }
{ BucketSize = 1, BucketIndex = 5, Sum = 6 }
{ BucketSize = 1, BucketIndex = 6, Sum = 7 }
{ BucketSize = 1, BucketIndex = 7, Sum = 8 }
{ BucketSize = 1, BucketIndex = 8, Sum = 9 }
{ BucketSize = 1, BucketIndex = 9, Sum = 10 }
{ BucketSize = 2, BucketIndex = 0, Sum = 3 }
{ BucketSize = 2, BucketIndex = 2, Sum = 7 }
{ BucketSize = 2, BucketIndex = 4, Sum = 11 }
{ BucketSize = 2, BucketIndex = 6, Sum = 15 }
{ BucketSize = 2, BucketIndex = 8, Sum = 19 }
{ BucketSize = 3, BucketIndex = 0, Sum = 6 }
{ BucketSize = 3, BucketIndex = 3, Sum = 15 }
{ BucketSize = 3, BucketIndex = 6, Sum = 24 }
{ BucketSize = 4, BucketIndex = 0, Sum = 10 }
{ BucketSize = 4, BucketIndex = 4, Sum = 26 }
{ BucketSize = 5, BucketIndex = 0, Sum = 15 }
{ BucketSize = 5, BucketIndex = 5, Sum = 40 }
{ BucketSize = 6, BucketIndex = 0, Sum = 21 }
{ BucketSize = 7, BucketIndex = 0, Sum = 28 }
{ BucketSize = 8, BucketIndex = 0, Sum = 36 }
{ BucketSize = 9, BucketIndex = 0, Sum = 45 }
{ BucketSize = 10, BucketIndex = 0, Sum = 55 }
*Not everything is better with LINQ
If I understand you correctly you have an array of numbers with length n. You want to pick all combinations of m numbers from this. You then want to sum all these combinations and finally compute the sum of these sums.
For instance given n = 6 numbers you can pick m = 4 elements in 15 different ways (the numbers are indices in the array of numbers):
0 1 2 3
0 1 2 4
0 1 3 4
0 2 3 4
1 2 3 4
0 1 2 5
0 1 3 5
0 2 3 5
1 2 3 5
0 1 4 5
0 2 4 5
1 2 4 5
0 3 4 5
1 3 4 5
2 3 4 5
If n < 32 (no more than 31 numbers in your array) you can efficiently generate the indices using 32 bit arithmetic. The following function is based on Gosper's hack:
IEnumerable<UInt32> GetIndexBits(Int32 m, Int32 n) {
unchecked {
var i = (UInt32) (1 << m) - 1;
var max = (UInt32) (1 << n);;
while (i < max) {
yield return i;
var u = (UInt32) (i & -i);
var v = u + i;
i = v + (((v ^ i)/u) >> 2);
}
}
}
With m = 4 and n = 6 this function will generate these numbers (displayed in binary form):
001111
010111
011011
011101
011110
100111
101011
101101
101110
110011
110101
110110
111001
111010
111100
You can then create the sum using LINQ:
var m = 4;
var numbers = new[] { 1, 2, 3, 4, 5, 6 };
var sum = GetIndexBits(4, numbers.Length)
.Select(
bits => Enumerable
.Range(0, numbers.Length)
.Where(i => ((1 << i) & bits) != 0)
)
.Select(indices => indices.Sum(i => numbers[i]))
.Sum();
With the provided input the sum will be 210 which is the same result as foursRet in the question when NumArray contains the numbers 1 to 6.