This is my code:
static int cardGameValue(List<int> D, int myScore, int opponentScore)
{
if (D.Count == 0) return myScore;
else if (D.Count == 1)
{
opponentScore += D[0];
return myScore;
}
else
{
if (D[0] <= D[D.Count - 1])
{
opponentScore += D[D.Count - 1];
D.RemoveAt(D.Count - 1);
}
else
{
opponentScore += D[0];
D.RemoveAt(0);
}
int left = cardGameValue(new List<int>(D.GetRange(1, D.Count - 1)), myScore + D[0], opponentScore);
int right = cardGameValue(new List<int>(D.GetRange(0, D.Count - 1)), myScore + D[D.Count - 1], opponentScore);
if (left >= right)
{
return left;
}
else
{
return right;
}
}
}
}
My code takes a set of cards and represents your maximum possible score when playing against a deterministic opponent. After each of your opponent’s plays you have 2 choices until cards are all picked. Is there a way to somehow store my results of the iterations so I can improve my algorithm? So the recursion doesn’t do unnecessary iterations? Because after 40 or 50 cards it becomes very slow.
You only access the first or the last element in the list
D. Rather than pass the exact list around, you can pass the full list of cards (or even better: as anintarray) together with the index of the first and last position.It’s much faster to calculate the opponent’s score after the calculation is complete:
myScoreandopponentScoreadd up to the sum of the values of the cards, so you can do this in O(n) time. This way, you can eliminate all the code that updatesopponentScore.You don’t need to pass
myScoreeither. If you letcardGameValuereturn the best score obtained from only the remaining cards.Finally, if you work with the first and last index, you can store the score in a 2D array, indexed by
firstandlast. If all the cards have positive values, then the score must be positive if there are at least two cards remaining.So at the beginning of the call, you check if the cached score is positive. If it is, you can return it right away. If not, you have to calculate it, and then store it in the cache array.
This is what you end up with:
Even for 300 cards, this runs in less than 1 millisecond on my machine.