0

[Image of the actual problem]

we have to choose the best item/items based on input3 which is items to be selected. the choice should be such that we don't take maximum item always. Instead we take items which are not having much difference.

input1: total items
input2: array of items
input3: items to be selected

Scenario 1:
input: 6, {44,55,605,100,154,190}, 1
output should be: {605}

input: 5, {15,85,32,31,2}, 2
output should be: {32,31}

as we increase the number of items to be selected, output should have more item in selected with minimum difference. Below is the code i am trying, i am new to this please help: i am stuck how to make this dynamic.

public static int[] Find(int totalItems, int[] values, int totalToBeSelected)
{
    var i = values;
    int[] results = new int[totalToBeSelected];

    var resultList = new List<int>();

    if (totalToBeSelected == 1)
    {
        resultList.Add(values.Max());
        return resultList.ToArray();
    }
    Array.Sort(i);
    var minmumDiff = (i[0] - i[1]) * -1;

    for (int k = 1; k < i.Length; k++)
    {
        var differnce = i[k] - i[k - 1];

        if (differnce < minmumDiff)
        {
            resultList.Add(i[k]);
            resultList.Add(i[k - 1]);
            minmumDiff = differnce;
        }
    }
    return resultList.ToArray();
}
under dog
  • 13
  • 2
  • Looks like a question from Techgig, isn't it? – sujith karivelil Oct 26 '17 at 13:10
  • 2
    Can you post the actual problem statement for the problem? It's not clear how you're getting that output from the input. Also, what input are you giving to your code, what output does it give and what output do you want? Can you post a [mcve]? Have you stepped through your code in a debugger or added print statements to see where it's differing from what you expect it to do? – Bernhard Barker Oct 26 '17 at 13:17
  • @Dukeling i have updated the question, let me know if you need more info, Thanks – under dog Oct 26 '17 at 13:40
  • Welcome to StackOverflow. Please read and follow the posting guidelines in the help documentation. [Minimal, complete, verifiable example](http://stackoverflow.com/help/mcve) applies here. We cannot effectively help you until you post your MCVE code and accurately describe the problem. We should be able to paste your posted code into a text file and reproduce the problem you described. – Prune Oct 26 '17 at 16:24
  • It's completely unclear what the rules of the game are. What if it asks you for three items from the array `{15,85,32,31,30,28}`? What is the expected result? What if the array is reversed? Are you supposed to take the absolute value of the difference? You need to update your question to clarify the problem. Otherwise we can't even attempt to help you design a solution – Jim Mischel Oct 26 '17 at 22:33
  • added the image link of the actual problem – under dog Oct 27 '17 at 05:53

2 Answers2

1

The conditions in the question are unclear, some assumptions had to be made.

class Program
{
        static void Main(string[] args)
        {
            var items = new[] {12,14,22,24,6};//new[] { 15, 85, 32, 31, 2};//new[] { 44, 55, 605, 100, 154, 190 };
            var totalItems = items.Count();
            var numberOfItemsToSelect = 3;

            var result = Find(totalItems, items, numberOfItemsToSelect);            

            PrintList(result);

            Console.ReadLine();
        }

        static void PrintList(IEnumerable<int> scoreList)
        {
            foreach (var score in scoreList)
            {
                Console.Write(score);
                Console.Write(" ");
            }
        }

        public static int[] Find(int totalItems, int[]values, int totalTobeSelected)
        {
            var result = new List<int>();
            if (totalTobeSelected <= 1)
            {
                result.Add(values.Max());

            }
            else if (totalTobeSelected == totalItems)
            {
                result.AddRange(values.OrderBy(i => i).ToList());
            }
            else
            {

                var mainSet = values.OrderBy(i => i).ToList();
                var setDic = new Dictionary<int, IEnumerable<int>>();

                for (int i = 0; (totalItems - i >= totalTobeSelected); i++)
                {
                    var set = mainSet.GetRange(i, totalTobeSelected);

                    //Inside a set, we choose the difference between the first and the second number
                    // ex: set = {2, 4, 9} => diff = |2-4| = 2.
                    var diff = Math.Abs(set[0] - set[1]);

                    // given two sets with the same diff, we select the first one base on the sort order of the main set:
                    // ex: main set = {2,4,8,10}. Both {2,4} and {6,8} have a diff of 2 so we select {2,4}
                    if (setDic.ContainsKey(diff)) continue;
                    setDic.Add(diff, set);

                }

                if (setDic.Count > 0)
                {
                    var minKey = setDic.Keys.Min();
                    result.AddRange(setDic[minKey]);
                }

            }
            return result.ToArray();
        }
    }
Iza Atsou
  • 181
  • 2
  • 6
1

You can look at this function.

    public static int[] Find(int totalItems, int[] values, int totalToBeSelected)
    {
        Array.Sort(values);
        Array.Reverse(values); // We need any value greater than max items diff. Max array item (first item after the sort) enough for it.
        int diff = values[0]; 
        int indx = 0;
        for (int i = 0; i < totalItems - totalToBeSelected +1; i++)
        {
            int temp_diff = values[i] - values[i + totalToBeSelected - 1]; // We are looking for any items group that max and min value difference is minimum 
            if (temp_diff < diff )
            {
                diff = temp_diff;
                indx = i;
            }
        }

        int[] results = new int[totalToBeSelected];
        Array.Copy(values, indx, results, 0, totalToBeSelected);

        return results;
    }

Sample:

        Find( 6, new int[] { 44, 55, 605, 100, 154, 190 }, 1 );
        Out: { 605 }

        Find( 5, new int[] { 15, 85, 32, 31, 2 }, 2 );
        Out: { 32, 31 }
Serkan Arslan
  • 13,158
  • 4
  • 29
  • 44