Reputation: 169
I have the following code but it takes 20sec to process the 52957 inputs of type BigInteger. This is the question that i want to solve https://www.hackerearth.com/problem/algorithm/girlfriends-demands/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Numerics;
namespace girldfriends_demands
{
class Program
{
private static string inputString = String.Empty;
private static int testCases=0;
private static BigInteger[,] indexArray;
static void Main(string[] args)
{
initialize();
printDemand();
Console.ReadLine();
}
private static void initialize()
{
inputString = Console.ReadLine();
testCases = int.Parse(Console.ReadLine());
indexArray = new BigInteger[testCases, 2];
for (int i = 0; i < testCases; i++)
{
string[] tokens = Console.ReadLine().Split();
indexArray[i, 0] = BigInteger.Parse(tokens[0]);
indexArray[i, 1] = BigInteger.Parse(tokens[1]);
}
}
private static void printDemand()
{
char[] convertedString = inputString.ToCharArray();
for (int i = 0; i < testCases; i++)
{
BigInteger length=inputString.Length;
BigInteger startf, endf; ;
BigInteger.DivRem(indexArray[i, 0] - 1,length,out startf);
BigInteger.DivRem(indexArray[i, 1]-1,length,out endf);
char c=convertedString[((int)startf)];
char e=convertedString[((int)endf)];
if(c==e)
{
Console.WriteLine("Yes");
}
else
{
Console.WriteLine("No");
}
}
}
}
}
Please specify how to reduce the time complexity of the code.This program gets the letters at the specified position in a string and prints true if they are same else false. Also computing the range at prior to the loop isn't helping
Upvotes: 1
Views: 1003
Reputation: 63732
Console.ReadLine().Split()
is the biggest of your problems. For every single line in the file, you create an array of strings, one letter per string. This is a huge performance drain, and almost certainly not what you intended - in particular, it would be wholy unnecessary to use BigInteger
to store a single-digit number...
I assume that you actually want to split the line in two based on some delimiter. For example, if your numbers are separated by a comma, you can use
Console.ReadLine().Split(',')
Even then, there is little reason to use BigInteger
at all. The operation you're trying to perform is distinctly string-based, and very easy to do with strings. However, I can't really help you more specifically, because your problem description is incredibly ambiguous for such a simple task, and the code is so obviously wrong it's entirely useless to guess at what exactly you're trying to do.
EDIT:
Okay, your link confirmed my assumptions - you are massively overcomplicating this. For example, code like this will do:
var word = Console.ReadLine();
var items = int.Parse(Console.ReadLine());
for (var _ = 0; _ < items; _++)
{
var indices =
Console.ReadLine()
.Split(' ')
.Select(i => (int)((long.Parse(i) - 1) % word.Length))
.ToArray();
Console.WriteLine(word[indices[0]] == word[indices[1]] ? "Yes" : "No");
}
First, note that the numbers will always fit in a long
, which allows you to avoid using BigIntever
. Second, you need to use Split
properly - in this case, the delimiter is a space. Third, there's no reason not to do the whole processing in a single stream - waiting for the whole input, collecting it in memory and then outputting everything at once is a waste of memory. Fourth, note how easy it was to avoid most of the complex checks while incorporating the whole necessary mechanism in simple arithmetic operations.
This runs under 2 seconds on each of the input data, only using ~80kiB of memory.
I think that ideologically, this fits the site perfectly - it's very simple and straightforward and works for all the expected inputs - the perfect hack. Of course, you'd want extra checks if this was for an end-user application, but the HackerEarth site name implies hacks are what's expected, really.
Upvotes: 3
Reputation: 885
Myabe by removing casts in these line and using string.compare you cand decrease execution time
if(string.Compare(startf.ToString(), endf.ToString()))
{
Console.WriteLine("Yes");
continue;
}
Console.WriteLine("No");
Upvotes: 0
Reputation: 2604
Why you use BigInteger
?
In any case string.length
is typeof int
.
It mean that if your string exceed 2147483647 (2^31 -1)
your program will be broken.
I think changing BigInteger
to int
will help.
Upvotes: 4
Reputation: 3719
In my experience, frequent Console.WriteLine
calls can lead to huge execution times.
Instead of calling that function whenever you want to add some output, I think you should use a StringBuilder
object, and append all your output to it. Then, after the for
-loop, call Console.WriteLine
once to print the StringBuilder
's contents.
This might not be your program's biggest problem, but it will help quite a bit.
Upvotes: 1