Click here to Skip to main content
15,890,506 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Hello. The goal of this problem is to represent a given positive integer 𝑛 as a sum of as many pairwise distinct positive integers as possible. That is, to find the maximum π‘˜ such that 𝑛 can be written as π‘Ž1 + π‘Ž2 + Β· Β· Β· + π‘Žπ‘˜ where π‘Ž1, . . . , π‘Žπ‘˜ are positive integers and π‘Žπ‘– ΜΈ= π‘Žπ‘— for all 1 ≀ 𝑖 < 𝑗 ≀ π‘˜.
Here is my code:

C#
static long[] MaximumNumberOfPrizes(long n)
{
    if (n == 1)
    {
        return new long[]{1};
    }
    long tmp = n;
    long sum = 0;
    int m = 1;
    List<long> mylist = new List<long>();

    for (long i = n; i > 0; i--)
    {
        if (sum >= tmp)
        {
            break;
        }
        n = n - m;
        if (n <= 0)
        {
            break;
        }
        sum = sum + m;
        if (mylist.Contains(m))
        {
            m++;
        }
        else
        {
            mylist.Add(m);
            m++;
        }
    }

    long total = mylist.Sum(s => Convert.ToInt64(s));
    if (total == tmp)
    {
        return mylist.ToArray();
    }

    else
    {
        long rem = tmp - total;
        long max = mylist.AsQueryable().Max();
        if (mylist.Contains(rem))
        {
            mylist.Remove(max);
            mylist.Add(max + rem);
        }
        else
        {
            mylist.Add(rem);
        }
    }
    return mylist.ToArray();
}


And in
C#
Main

C#
int n = Convert.ToInt32(Console.ReadLine());
            long[] myarray = MaximumNumberOfPrizes(n);
            System.Console.WriteLine(myarray.Length);
            for (int i = 0; i < myarray.Length; i++)
            {
                System.Console.Write(myarray[i] + " ");
            }


What I have tried:

When I submit my code the test case which is related to the time limit fails:
Failed case #35/42: time limit exceeded (Time used: 3.08/1.50, memory used: 26767360/2147483648.)


I think because of the operations on the list my code works slowly. But I don't know how to decrease the Big-O of my code. Actually, I don't want to change my code a lot because the algorithm is correct but it is slow.
I will be grateful for your help and advice. Thanks.
Posted
Updated 3-Oct-21 1:54am
Comments
PIEBALDconsult 30-Sep-21 11:39am    
Don't use Linq
Don't use lambdas
Don't use Convert.ToInt32
Don't use Convert.ToInt64
Don't use .ToArray()
Don't use .Contains
...
Aylin Naebzadeh 30-Sep-21 18:45pm    
I thought that LINQ and lambdas are faster than for and foreach, but now I understand they are in this case slower and actually they have a hidden loop. And in fact the biggest advantage is that they are easy to read.
PIEBALDconsult 30-Sep-21 18:47pm    
Yes, readability at the cost of performance.
Dave Kreskowiak 3-Oct-21 11:34am    
LINQ is nothing but syntaxic sugar, meaning it's a shorthand way of expressing a larger, standardized block of code, that does the job for you. It does NOT make anything faster.
Aylin Naebzadeh 6-Oct-21 16:44pm    
That's rightπŸ‘Œ

You have to rethink your approach to the problem. Challenges like this are setup so the straight forward approach you are using will always be too slow to beat the time constraint.

There's more than one way to approach this problem and that's the point behind the challenge.
 
Share this answer
 
Comments
Aylin Naebzadeh 30-Sep-21 10:26am    
Yes, I have to think more about it.
Quote:
Actually, I don't want to change my code a lot because the algorithm is correct but it is slow.

And there is your problem.
It's not the code that is slow, but the whole way your are doing it - brute force.

The whole idea of code challenges is not to just get it working, but to do it elegantly, so that it isn't a brute force approach.
You need a better algorithm, then better code to implement that.
 
Share this answer
 
Comments
Aylin Naebzadeh 30-Sep-21 10:25am    
You are right. I will think more about it.
OriginalGriff 30-Sep-21 11:05am    
Excellent!
That takes less than one millisecond!

1) The largest k will be achieved by using the smallest possible a-values.
2) The sum S(x) of 1,2,3,...,x equals x*(x+1)/2
3) You can find the smallest x that satisfies S(x)>=n with a simple square root plus some extra check
4) finally, if S(x) exceeds n by d, then drop the a-value that equals d !!!

Hence, you don't need any loops, lists, arrays, whatever, to solve the problem. A few simple formulae are all it takes. You will only need one array and one loop to stuff the solution in the format the API specified.

And yes, that basically means throwing away all of your code no matter how correct it may be.
 
Share this answer
 
Comments
Aylin Naebzadeh 30-Sep-21 11:50am    
I will try itπŸ‘
To find max k with brute force or by quadratic equasion and print numbers with console application:



using System;

namespace Code_project_answer
{
	class Program
	{
		public static void Main(string[] args)
		{
			Console.WriteLine(" Hello World! ");
			Console.WriteLine(" ************ ");
			
			Console.Write(" n = ");
			int n = int.Parse(Console.ReadLine());
			Console.WriteLine(" ************ ");
			
			int k = 0;
			int i = 0;
			
			//
			// For next loop
			//
			Console.WriteLine(" for..next ");
			Console.WriteLine(" ************ ");
			
			for (i = 1; i <= n; i++)
			{
				k += i;
				if (n <= k + i)
				{
					k = i;
					Console.WriteLine(" k = " + k.ToString());
					Console.WriteLine(" ************ ");
					break;
				}
			}
			
			//
			// While loop
			//
			Console.WriteLine(" while loop ");
			Console.WriteLine(" ************ ");
			i = 0;
			k = 0;
			while (n > k + i)
			{
				i++;
				k += i;
			}
			
			k = i;
			
			Console.WriteLine(" k = " + k.ToString());
			Console.WriteLine(" ************ ");
			
			//
			// Use quadratic equasion
			// a*x^2 + b*x + c = 0;
			//
			Console.WriteLine(" Quadratic equasion ");
			Console.WriteLine(" ****************** ");
			
			int a = 1;
			int b = 1;
			int c = -2 * n;
			
			int d = (b * b) - (4 * a * c);
			
			if (d >= 0)
			{
				int x1 = (-b + ((int)Math.Sqrt(d))) / 2 * a;
				int x2 = (-b - ((int)Math.Sqrt(d))) / 2 * a;

				Console.WriteLine(" x1 = " + x1.ToString());
				Console.WriteLine(" x2 = " + x2.ToString());
				Console.WriteLine(" ************ ");
				
				k = x1;
				
				Console.WriteLine(" k = " + k.ToString());
				Console.WriteLine(" ************ ");
			}
			else
			{
				Console.WriteLine(" There is no solution for quadratic formula. ");
				Console.WriteLine(" ******************************************* ");
			}
			
			//
			// Print one of many possible combinations
			//
			int ln = 0;
			ln = n - (((k - 1) * k) / 2);
			Console.Write(" " + ln);
			k--;
			while (k > 0)
			{
				Console.Write("+" + k);
				k--;
			}
			Console.WriteLine();
			Console.WriteLine(" ************ ");
			
			Console.Write("Press any key to continue . . . ");
			Console.ReadKey(true);
		}
	}
}


All the best,
Željko Perić
 
Share this answer
 
v2

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900