Get the max count of an array inside array? - c#

I have an array inside the array and I want to get the Highest count of that Array,
List<int> badnumber = new List<int>() { 5,4,2, 15 };
int lower = 1;
int upper = 10;
int count = 0;
List<int> goodnumber = new List<int>();
List<List<int>> myList = new List<List<int>>();
for (int i = lower; i <= upper; i++)
{
if (!badnumber.Contains(i))
{
if (!goodnumber.Contains(i))
goodnumber.Add(i);
}
else
{
myList.Add(goodnumber);
goodnumber = new List<int>();
}
if (i == upper) {
myList.Add(goodnumber);
}
}
in myList values are like this
Array 1 : { 1 }
Array 2 : { 3 }
Array 3 : { 0 }
Array 4 : { 6, 7, 8, 9, 10 }
I want to get the count of the highest sequence which is Array 4. and return the count of it which is 5.
how would I get that?

Use following sample
var maxCount = myList.Max(l => l.Count);

Try following :
List<List<int>> myList = new List<List<int>>() {
new List<int> { 1},
new List<int> { 3},
new List<int> { 0},
new List<int> { 6,7,8,9,10}
};
int results = myList.Max(x => x.Count);

Basically your task boils down to the following:
How to get the greatest number in a list
In order to achieve that, you have to iterate that (outer) list, get every elements member you want to compare - in your case the Count - and check if it is greater the current Max:
int max = 0;
foreach(var l in myList)
{
if(l.Count > max)
max = l.Count;
}
or even simpler using linq, see jdweng.

Try below lambda to get index position with count:
int index = 0;
var result = myList.Select(x => new { indexPos = ++index, x.Count }).OrderByDescending(x => x.Count).First();

Related

algorithm searching through dictionary

Im working from the Q https://www.testdome.com/for-developers/solve-question/10282
Write a function that, given a list and a target sum, returns zero-based indices of any two distinct elements whose sum is equal to the target sum. If there are no such elements, the function should return null.
For example, FindTwoSum(new List<int>() { 1, 3, 5, 7, 9 }, 12) should return a Tuple<int, int> containing any of the following pairs of indices:
1 and 4 (3 + 9 = 12)
2 and 3 (5 + 7 = 12)
3 and 2 (7 + 5 = 12)
4 and 1 (9 + 3 = 12)
So far iv got:
class TwoSum
{
public static Tuple<int, int> FindTwoSum(IList<int> list, int sum)
{
//throw new NotImplementedException("Waiting to be implemented.");
IList<int> duplicateList = list;
foreach (int i in list)
{
foreach (int j in duplicateList)
{
if (i != j)
{
if (i + j == sum)
{
return Tuple.Create(i, j);
}
}
}
}
return null;
}
public static void Main(string[] args)
{
Tuple<int, int> indices = FindTwoSum(new List<int>() { 1, 3, 5, 7, 9 }, 12);
Console.WriteLine(indices.Item1 + " " + indices.Item2);
}
}
This returns the correct answer in my code but is failing 3 out of 4 cases in the quesitong because:
Example case: Wrong answer
No solution: Correct answer
One solution: Wrong answer
Performance test with a large number of elements: Wrong answer
Ive looked at the hints
Hint 1: Nested for loops can iterate over the list and calculate a sum in O(N^2) time.
Hint 2: A dictionary can be used to store pre-calculated values, this may allow a solution with O(N) complexity.
So im using nested loops but Im guessing in this instance in order to pass hint2 I need to use a dictionary...How can I refactor this into using a dictionary?
Thanks for any help!
You are not returning indexes, you are returning values. for loops are not foreach loops.
A nested for loops solution would be something like this:
for(int i=0; i<list.Count-1; i++)
{
for(int j=i+1;j<list.Count;j++)
{
if(list[i]+list[j] == sum)
{
return Tuple.Create(i, j);
}
}
}
return null;
I'll leave the dictionary solution for you to create.
Hi this one received 50%
public static Tuple<int, int> FindTwoSum(IList<int> list, int sum)
{
int n = list.Count-1;
while(n != 0)
{
for (int i = 0; i <= list.Count-1 ; i++)
{
if (list[n] + list[i] == sum)
{
return Tuple.Create(i, n);
}
}
n--;
}
return null;
}
// get list value:
var aat = (from l1 in list
from l2 in list
where l1 + l2 == 12
group new { l1, l2} by new { l1, l2 } into gp
select new {gp.Key}).ToDictionary( a => a.Key.l1, b => b.Key.l2 );
// get list index of the value:
var aav = (from l1 in list
from l2 in list
where l1 + l2 == 12
group new { l1, l2 } by new { l1, l2 } into gp
select new { gp.Key })
.ToDictionary( a => list.IndexOf(a.Key.l1), b => list.IndexOf(b.Key.l2)
);

Unique Values from a list of of items in C#

I am having a list:
list = { 1,1,1,2,3,3,3,4,4,5,6,6,6}
Now I want to extract list of unique values.
Final list contains {2,5} only.
How can I do that through LINQ or any other function.
One way would be to use the GroupBy method and filter only those which have a count of 1:
var unique = list.GroupBy(l => l)
.Where(g => g.Count() == 1)
.Select(g => g.Key);
Try This:
List<int> list = new List<int>(new int[]{ 1, 1, 1, 2, 3, 3, 3, 4, 4, 5, 6, 6, 6});
List<int> unique=new List<int>();
int count=0;
bool dupFlag = false;
for (int i = 0; i < list.Count; i++)
{
count = 0;
dupFlag = false;
for(int j=0;j<list.Count;j++)
{
if (i == j)
continue;
if (list[i].Equals(list[j]))
{
count++;
if (count >= 1)
{
dupFlag = true;
break;
}
}
}
if (!dupFlag)
unique.Add(list[i]);
}
Try this code:
var lstUnique =
from t1 in list
group t1 by t1 into Gr
where Gr.Count() == 1
select Gr.Key;

How to iterate through Dictionary<MyEnum, List<int>> and each time return part of values of each list?

Each key in dictionary has list of MANY integers. I need to iterate through each key and each time to take n items from list and do it until I iterate through all items in all lists. What is the best way to implement it? Do I need to implement some Enumerator?
The code:
enum ItemType { Type1=1, Type2=2, Type3=3 };
var items = new Dictionary<ItemType, List<int>>();
items[ItemType.Type1] = new List<int> { 1, 2, 3, 4, 5 };
items[ItemType.Type2] = new List<int> { 11, 12, 13, 15 };
items[ItemType.Type3] = new List<int> { 21, 22, 23, 24, 25, 26 };
For example: n=2.
1st iteration returns 1,2,11,12,21,22
2nd iteration returns 3,4,13,15,23,24
3rd iteration returns 5,25,26
UPDATED:
at the end I have to get list of this items in that order : 1,2,11,12,21,22, 3,4,13,15,23,24, 5,25,26
Here is how it might be done:
enum ItemType { Type1 = 1, Type2 = 2, Type3 = 3 };
Dictionary<ItemType, List<int>> items = new Dictionary<ItemType, List<int>>();
items[ItemType.Type1] = new List<int> { 1, 2, 3, 4, 5 };
items[ItemType.Type2] = new List<int> { 11, 12, 13, 15 };
items[ItemType.Type3] = new List<int> { 21, 22, 23, 24, 25, 26 };
// Define upper boundary of iteration
int max = items.Values.Select(v => v.Count).Max();
int i = 0, n = 2;
while (i + n <= max)
{
// Skip and Take - to select only next portion of elements, SelectMany - to merge resulting lists of portions
List<int> res = items.Values.Select(v => v.Skip(i).Take(n)).SelectMany(v => v).ToList();
i += n;
// Further processing of res
}
You don't need to define your custom enumerator, just use the MoveNext manually:
Step 1, convert you Dictionary<ItemType, List<int>> into Dictionary<ItemType, List<IEnumerator<int>>:
var iterators = items.ToDictionary(p => p.Key, p => (IEnumerator<int>)p.Value.GetEnumerator());
Step 2: handle MoveNext manually:
public List<int> Get(Dictionary<ItemType, IEnumerator<int>> iterators, int n)
{
var result = new List<int>();
foreach (var itor in iterators.Values)
{
for (var i = 0; i < n && itor.MoveNext(); i++)
{
result.Add(itor.Current);
}
}
return result;
}
Calling Get multiple times will give you the expected result. The enumerator itself will keep the current position.
This will do it for you:
var resultList = new List<int>();
items.ToList().ForEach(listInts => resultList.AddRange(listInts.Take(n));
This is letting LINQ extensions do the hard work for you. Take() will take as much as it can without throwing an exception if you request more than what there is. In this case I'm adding the results to another list, but you could just as easily tag another ForEach() on the end of the Take() in order to iterate the results.
I notice from the example sequences that you are retriving n number of items from x starting point - if you edit your question to include how the starting point is decided then I will adjust my example.
Edit:
Because you want to take n number of items from each list each iteration until there are no more elements returned, this will do it:
class Program
{
static void Main(string[] args)
{
var items = new Dictionary<ItemType, List<int>>();
items[ItemType.Type1] = new List<int> { 1, 2, 3, 4, 5 };
items[ItemType.Type2] = new List<int> { 11, 12, 13, 15 };
items[ItemType.Type3] = new List<int> { 21, 22, 23, 24, 25, 26 };
int numItemsTaken = 0;
var resultsList = new List<int>();
int n = 2, startpoint = 0, previousListSize = 0;
do
{
items.ToList().ForEach(x => resultsList.AddRange(x.Value.Skip(startpoint).Take(n)));
startpoint += n;
numItemsTaken = resultsList.Count - previousListSize;
previousListSize = resultsList.Count;
}
while (numItemsTaken > 0);
Console.WriteLine(string.Join(", ", resultsList));
Console.ReadKey();
}
enum ItemType { Type1 = 1, Type2 = 2, Type3 = 3 };
}
This is one of the few times you'll use a do while loop, and it will work regardless of the size of n or the size of your lists or how many lists there are.
The "best way" depends on your goal, e.g. readability or performance.
Here's one way:
var firstIter = items.Values.SelectMany(list => list.Take(2));
var secondIter = items.Values.SelectMany(list => list.Skip(2).Take(2));
var thirdIter = items.Values.SelectMany(list => list.Skip(4).Take(2));
var finalResult = firstIter.Concat(secondIter).Concat(thirdIter);
Edit: Here's a more general version:
var finalResult = Flatten(items, 0, 2);
IEnumerable<int> Flatten(
Dictionary<ItemType, List<int>> items,
int skipCount,
int takeCount)
{
var iter = items.Values.SelectMany(list => list.Skip(skipCount).Take(takeCount));
return
iter.Count() == 0 ? // a bit inefficient here
iter :
iter.Concat(Flatten(items, skipCount + takeCount, takeCount));
}

how to sort number to desired in c#?

for each element that their difference with former is less than three, order them in descending
numbers = {1,2,3,4,5,6,13,18,25,30,31,32,33}
desired = {6,5,4,3,2,1,13,18,25,33,32,31,30}
for example in numbers list ,Because difference between 6 and 5 is less than 3 sort them in descending
You can use LINQ:
var numbers = new int[] { 1, 2, 3, 4, 5, 6, 13, 18, 25, 30, 31, 32, 33 };
var result = numbers.GroupAdjacent((x, y) => y - x < 3)
.SelectMany(g => g.OrderByDescending(x => x))
.ToArray();
// result == { 6, 5, 4, 3, 2, 1, 13, 18, 25, 33, 32, 31, 30 }
with
static IEnumerable<IEnumerable<T>> GroupAdjacent<T>(
this IEnumerable<T> source, Func<T, T, bool> adjacent)
{
var g = new List<T>();
foreach (var x in source)
{
if (g.Count != 0 && !adjacent(g.Last(), x))
{
yield return g;
g = new List<T>();
}
g.Add(x);
}
yield return g;
}
hello that is too complex..
As i dont have the Visual studio so i wrote the code in javascript that will cover your requirement
<script>
var a = [1,2,3,4,5,6,13,18,25,30,31,32,33];
alert(custom_sort(a));
function custom_sort(a) {
var objArrayList = {};
var index = 0;
var where_i_am = 0;
objArrayList[index] = Array();
if(a[1]-a[0] < 3){
where_i_am = 1;
objArrayList[index].push(a[0]);
} else {
where_i_am = 2;
objArrayList[index].push(a[0]);
}
for(var i=1;i<a.length;i++) {
if(a[i]-a[i-1] < 3) {
if(where_i_am ==2) {
where_i_am = 1;
index++;
objArrayList[index] = Array();
}
if(where_i_am==1)
objArrayList[index].push(a[i]);
} else {
if(where_i_am==1) {
where_i_am =2;
index++;
objArrayList[index] = Array();
}
if(where_i_am==2) {
objArrayList[index].push(a[i]);
}
}
}
var new_array = new Array();
for(var obj in objArrayList) {
var array_val = objArrayList[obj];
if(array_val[1] - array_val[0] < 3) {
new_array = new_array.concat(sort_desc(array_val));
} else {
new_array = new_array.concat(sort_asc(array_val));
}
}
return new_array;
}
function sort_asc(array_val){
for(var i =0;i<array_val.length;i++) {
for(var j=0;j<array_val.length;j++) {
if(array_val[i] < array_val[j]) {
var temp = array_val[i];
array_val[i] = array_val[j];
array_val[j] = temp;
}
}
}
return array_val;
}
function sort_desc(array_val){
for(var i =0;i<array_val.length;i++) {
for(var j=0;j<array_val.length;j++) {
if(array_val[i] > array_val[j]) {
var temp = array_val[i];
array_val[i] = array_val[j];
array_val[j] = temp;
}
}
}
return array_val;
}
</script>
For me such algorithm looks very non standard so I feel there are few algorithms should be used to achieve good results in terms of complexity. There is one very important question - does an initial array already sorted?
Any way you can start by splitting array by sub arrays:
Split such array to multiple (with some indicator whether each one should be sorted
ASC or DESC)
Then if an initial array is not sorted:
Then sort all of sub arrays one by one using QuickSort, so you will get a set of sorted arrays
Then you can sort sub arrays using the first element of each so order of sub arrays should be saved (Hope I described it clear enough)
But if an initial array was sorted:
Merge sub arrays in initially preserved order

Selecting unique elements from a List in C#

How do I select the unique elements from the list {0, 1, 2, 2, 2, 3, 4, 4, 5} so that I get {0, 1, 3, 5}, effectively removing all instances of the repeated elements {2, 4}?
var numbers = new[] { 0, 1, 2, 2, 2, 3, 4, 4, 5 };
var uniqueNumbers =
from n in numbers
group n by n into nGroup
where nGroup.Count() == 1
select nGroup.Key;
// { 0, 1, 3, 5 }
var nums = new int{ 0...4,4,5};
var distinct = nums.Distinct();
make sure you're using Linq and .NET framework 3.5.
With lambda..
var all = new[] {0,1,1,2,3,4,4,4,5,6,7,8,8}.ToList();
var unique = all.GroupBy(i => i).Where(i => i.Count() == 1).Select(i=>i.Key);
C# 2.0 solution:
static IEnumerable<T> GetUniques<T>(IEnumerable<T> things)
{
Dictionary<T, int> counts = new Dictionary<T, int>();
foreach (T item in things)
{
int count;
if (counts.TryGetValue(item, out count))
counts[item] = ++count;
else
counts.Add(item, 1);
}
foreach (KeyValuePair<T, int> kvp in counts)
{
if (kvp.Value == 1)
yield return kvp.Key;
}
}
Here is another way that works if you have complex type objects in your List and want to get the unique values of a property:
var uniqueValues= myItems.Select(k => k.MyProperty)
.GroupBy(g => g)
.Where(c => c.Count() == 1)
.Select(k => k.Key)
.ToList();
Or to get distinct values:
var distinctValues = myItems.Select(p => p.MyProperty)
.Distinct()
.ToList();
If your property is also a complex type you can create a custom comparer for the Distinct(), such as Distinct(OrderComparer), where OrderComparer could look like:
public class OrderComparer : IEqualityComparer<Order>
{
public bool Equals(Order o1, Order o2)
{
return o1.OrderID == o2.OrderID;
}
public int GetHashCode(Order obj)
{
return obj.OrderID.GetHashCode();
}
}
If Linq isn't available to you because you have to support legacy code that can't be upgraded, then declare a Dictionary, where the first int is the number and the second int is the number of occurences. Loop through your List, loading up your Dictionary. When you're done, loop through your Dictionary selecting only those elements where the number of occurences is 1.
I believe Matt meant to say:
static IEnumerable<T> GetUniques<T>(IEnumerable<T> things)
{
Dictionary<T, bool> uniques = new Dictionary<T, bool>();
foreach (T item in things)
{
if (!(uniques.ContainsKey(item)))
{
uniques.Add(item, true);
}
}
return uniques.Keys;
}
There are many ways to skin a cat, but HashSet seems made for the task here.
var numbers = new[] { 0, 1, 2, 2, 2, 3, 4, 4, 5 };
HashSet<int> r = new HashSet<int>(numbers);
foreach( int i in r ) {
Console.Write( "{0} ", i );
}
The output:
0 1 2 3 4 5
Here's a solution with no LINQ:
var numbers = new[] { 0, 1, 2, 2, 2, 3, 4, 4, 5 };
// This assumes the numbers are sorted
var noRepeats = new List<int>();
int temp = numbers[0]; // Or .First() if using IEnumerable
var count = 1;
for(int i = 1; i < numbers.Length; i++) // Or foreach (var n in numbers.Skip(1)) if using IEnumerable
{
if (numbers[i] == temp) count++;
else
{
if(count == 1) noRepeats.Add(temp);
temp = numbers[i];
count = 1;
}
}
if(count == 1) noRepeats.Add(temp);
Console.WriteLine($"[{string.Join(separator: ",", values: numbers)}] -> [{string.Join(separator: ",", values: noRepeats)}]");
This prints:
[0,1,2,2,2,3,4,4,5] -> [0,1,3,5]
In .Net 2.0 I`m pretty sure about this solution:
public IEnumerable<T> Distinct<T>(IEnumerable<T> source)
{
List<T> uniques = new List<T>();
foreach (T item in source)
{
if (!uniques.Contains(item)) uniques.Add(item);
}
return uniques;
}

Categories