4
\$\begingroup\$

The program below takes inputs for the temperature in various cities in a span of multiple days. It then outputs the ones where the minimal temperature is closer to the average than the maximal temperature, prefaced by the number of cities where this happens.

For example: "3 5 10 15 12 10 10

11 11 11 11 20

12 16 16 16 20"

returns "2 1 2".

I've ran it with various particularly large inputs a few times, and the program seems to slow down with larger numbers. Is there any way to make the program faster?

class Program
    {
        static void Main(string[] args)
        {
            string input = Console.ReadLine();
            string[] inputs = input.Split();
            int cities = Convert.ToInt32(inputs[0]);
            int days = Convert.ToInt32(inputs[1]);
            int[] content = new int[days];
            int i = 0;
            int y = 0;
            float max = 0;
            float average = 0;
            float min = 50;
            int how_many = 0;
            List<int> which = new List<int>();
            for (i = 0; i < cities; i++)
            {
                input = Console.ReadLine();
                inputs = input.Split();
                for (y = 0; y < days; y++)
                {
                    content[y] = Convert.ToInt32(inputs[y]);
                    average += content[y];
                    if (content[y] > max)
                    {
                        max = content[y];
                    }
                    if (content[y] < min)
                    {
                        min = content[y];
                    }
                }
                average = (float)average / days;

                if (max - average > average - min)
                {
                    how_many += 1;
                    int position = i + 1;
                    which.Add(position);
                }
                max = 0;
                average = 0;
                min = 50;
                y = 0;

            }
            Console.Write(how_many + " ");
            i = 0;
            for (i = 0; i < which.Count(); ++i)
            {
                Console.Write(which[i] + " ");
            }

            Console.ReadKey();
        }
    }
\$\endgroup\$
2
  • \$\begingroup\$ How big is a "particularly large inputs"? 100 cities? 1,000 cities? 300 days? I fixed some small memory issues in your code testing it but it runs pretty quick. \$\endgroup\$ Dec 30, 2019 at 21:06
  • \$\begingroup\$ 1,000 cities, 1,000 days. Could you send me the code if possible? \$\endgroup\$
    – Pizza64210
    Dec 30, 2019 at 21:14

1 Answer 1

2
\$\begingroup\$

If you want to see how performance is you need to get the user input out of the loop. I'm assuming you don't want to measure the time it takes someone to type in or paste in the data elements.

You don't need the variable how_many as it will always be the same as the Count of which, which by the way isn't a good name for a variable even something like results would be better name.

You also don't need the context array variable. Just need to store the current value not save each element as it loops through.

The variables i, y, max, average, min can all be declared in the loop scope and not need to be reset.

Calling Count() on which.Count() is the Linq Count method, should just call the list Count property

I'm also assuming this is a beginner question and won't get into Console as input and validating the data coming from it is valid.

I personally didn't want to type in all the data so I made the computer generate random data, if in debug mode

    static void Main(string[] args)
    {
#if DEBUG
        var random = new Random();
        var inputs = "1000 1000".Split();
#else
        var inputs = Console.ReadLine().Split();
#endif
        var cities = Convert.ToInt32(inputs[0]);
        var days = Convert.ToInt32(inputs[1]);

        var data = new List<int[]>(cities);
        for (var i = 0; i < cities; i++)
        {
#if DEBUG
            var cityData = Enumerable.Range(0, days)
                .Select(_ => random.Next(100))
                .ToArray();
#else
            var cityData = Console.ReadLine()
                .Split()
                .Select(x => Convert.ToInt32(x))
                .ToArray();
#endif
            if (cityData.Length != days)
            {
                Array.Resize(ref cityData, days);
            }
            data.Add(cityData);
        }

        var timer = new Stopwatch();
        timer.Start();
        var results = new List<int>();
        for (var i = 0; i < cities; i++)
        {
            float max = float.MinValue;
            float average = 0;
            float min = float.MaxValue;
            for (var y = 0; y < days; y++)
            {
                var content = data[i][y];
                average += content;
                if (content > max)
                {
                    max = content;
                }
                if (content < min)
                {
                    min = content;
                }
            }
            average = average / days;

            if (max - average > average - min)
            {
                int position = i + 1;
                results.Add(position);
            }
        }

        Console.Write(results.Count + " ");
        Console.WriteLine(string.Join(" ", results));
        timer.Stop();
        Console.WriteLine();
        Console.WriteLine($"Total Processing Time: {timer.Elapsed}");
        Console.ReadKey();
    }

This code runs in less than a second on my machine. I assume waiting for user input was what was taking the longest time in pervious one and not actually the processing of the data.

\$\endgroup\$
2
  • 1
    \$\begingroup\$ Thank you very much for the answer! This will help me a lot in learning programming. \$\endgroup\$
    – Pizza64210
    Dec 30, 2019 at 21:40
  • \$\begingroup\$ @Pizza64210 FYI I fixed bug in the code. Needed Split() after the "1000 1000" \$\endgroup\$ Dec 30, 2019 at 22:14

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.