15,845,744 members
4.00/5 (1 vote)
See more:
Given a pair of table tennis score.
In how many ways final score can be achieved.

for e.g
input is
10 11 14 12

where 10 is player1 current score , 11 is player2 current score
14 is player1 final score , 12 is player2 final score.

Thus the 2 ways are:
10:11 -> 11:11-> 12:11-> 12:12-> 13:12 ->14:12
10:11 -> 11:11-> 11:12-> 12:12-> 13:12-> 14:12

Moved by PIEBALDconsult

I tried the following code but it just iterates .
I am not able to look for an condition where I can find that the number of ways can be more than one.
Code :

C#
```class Program
{
static void Main(string[] args)
{
int T = 0;
String[] values = new String[4];
List listScore = new List();

int caseNo=0;
for(int i=0;i 2 && (s.player1Final >= 11 || s.player2Final >= 11)))
{
while (!(s.player1Initial== s.player1Final && s.player2Initial==s.player2Final))
{
if(((s.player1Initial+1) -s.player2Initial) <=2 && s.player1Initial!=s.player1Final)
{
s.player1Initial = s.player1Initial + 1;
}
if (((s.player2Initial + 1) - s.player1Initial) <= 2 && s.player2Initial != s.player2Final)
{
s.player2Initial = s.player2Initial + 1;
}
if (s.player1Initial == s.player2Initial && ((s.player1Initial + 1) - s.player2Initial <= 2) && ((s.player2Initial + 1) - s.player1Initial) <= 2)
{
countWays = countWays + 1;
}
}
}

Console.WriteLine("Case {0}: {1}", caseNo, countWays);
}

}

}
class Score
{
public int player1Initial { get; set; }
public int player2Initial { get; set; }
public int player1Final { get; set; }
public int player2Final { get; set; }
}
```
Posted
Updated 6-Dec-14 9:46am
v2
Kornfeld Eliyahu Peter 6-Dec-14 13:31pm
http://mattgemmell.com/what-have-you-tried/
Member 10867467 6-Dec-14 13:38pm
-- Moved to question
PIEBALDconsult 6-Dec-14 13:55pm
Emre Ataseven 6-Dec-14 15:12pm
Question is not clear, you need to give more details.
George Jonsson 6-Dec-14 22:42pm
More homework? :)

## Solution 1

This is not a programming problem but a mathematical (Combinatorics[^]) problem.
Problem: Player 1 goes from 10 to 14, player 2 from 11 to 12.
Analysis of the possible solutions:

1. you have the following possible individual match results
a1) 10:11
a2) 10:12

b1) 11:11
b2) 11:12

c1) 12:11
c2) 12:12

d1) 13:11
d2) 13:12

e1) 14:11
e2) 14:12
2. Find an way to go over all possible (meaningful) match results for the given situation, e.g.

abcde
11111 2
1111 22
111 222
11 2222
1 22222

3. deduce a general algorithm for the given approach to traverse all meaningful results (iterative or recursive). This is left for you as exercise. ;-)
[EDIT]
Ok, not really. After BillWoodruff's comments, I provide a solution here that is based on recursion.
C#
```static void playMatches(string[] scores, int iToPlay, int iCurr1, int iCurr2, int iEnd1, int iEnd2)
{
// play this match
scores[scores.Length - iToPlay] = string.Format("{0}:{1}", iCurr1, iCurr2);
// play the rest...
// ...1st: all possible scores from this point on
// when applying here all remaining permutations of player 1 scores
for(int i = iCurr1+1; i <= iEnd1; ++i)
{
playMatches(scores, iToPlay-1, i, iCurr2, iEnd1, iEnd2);
}
// ...2nd: all possible scores from this point on
// when applying here all remaining permutations of player 2 scores
for (int i = iCurr2+1; i <= iEnd2; ++i)
{
playMatches(scores, iToPlay-1, iCurr1, i, iEnd1, iEnd2);
}
// last match: write whole score sequence
if (iToPlay == 1)
{
Console.WriteLine(string.Join(" -> ", scores));
}
}```
Call it like this:
C#
```int iScore1 = ...;
int iScore2 = ...;
int iEnd1 = ...;
int iEnd2 = ...;
int iMatches = iEnd1 + iEnd2 + 1 - iScore1 - iScore2;
string[] scores = new string[iMatches];
playMatches(scores, iMatches, iScore1, iScore2, iEnd1, iEnd2);```
The resulting output for your given data is
```10:11 -> 11:11 -> 12:11 -> 13:11 -> 14:11 -> 14:12
10:11 -> 11:11 -> 12:11 -> 13:11 -> 13:12 -> 14:12
10:11 -> 11:11 -> 12:11 -> 12:12 -> 13:12 -> 14:12
10:11 -> 11:11 -> 11:12 -> 12:12 -> 13:12 -> 14:12
10:11 -> 10:12 -> 11:12 -> 12:12 -> 13:12 -> 14:12```
[/EDIT]

Cheers
Andi

v4
BillWoodruff 6-Dec-14 23:13pm
Well, yes, the essence of the OP's challenge/task/problem is combinatorial, but this is a question about how to program this particular set of combinatorial outcomes, given the initial data, and the range of possible final results.

So, I do not consider this a "solution," although it's a valuable "comment."
Andreas Gieriet 6-Dec-14 23:20pm
I agree that I do not provide a ready-to-use solution. The essence is that the problem is not really understood from that I see in the code. So I provide a starting point for the analysis.
Cheers
Andi
BillWoodruff 6-Dec-14 23:42pm
Hi Andreas, I just modified my comment before I saw this response: imho, the problem is very well understood; it's how-to-code that is not well understood here.

And, as I said, I consider your post, indeed, valuable, but, not a "solution."

If I really thought your post wasn't valuable at all, I would down-vote your post. In the past, I have voted what I perceive as valuable-but-not-solution-posts a #3, but, then, some people get very upset, because they consider a #3 as a negative vote, which I do not :)
Andreas Gieriet 7-Dec-14 1:11am
Cheers
Andi
BillWoodruff 7-Dec-14 1:54am
If the OP finds your solution valuable and usable, then I think that matters a lot more than what Bill thinks :)

In general, I think implementing something that "naturally" maps to simple iteration using recursion is over-kill, and renders code obscure for readers/maintainers who do not have strong skills in understanding recursion.

By the way, my second computer language, after 6809 assembler (if you call that a "language"), was LISP where recursion is as natural as apple pie :)

## Solution 2

At the risk of describing a "solution" that uses some features of C# that many newcomers to the language may have not encountered, or understood how to use, I'm going to offer some code here:
C#
```// required in addition to whatever else is required
using System.Collections.Generic;
using System.Linq;

// data for one Match
public struct MatchData
{
public int ID;

public int player1Score;
public int player2Score;

public MatchData(int id, int s1, int s2)
{
ID = id;
player1Score = s1;
player2Score = s2;
}
}

// given parameters that specify starting scores for two players
// create a Dictionary whose Key is an integer Match ID
// and whose Value is an instance of the struct 'MatchData
{
IEnumerable<int> player1Scores = Enumerable.Range(p1Start, p1MaxPointsToAdd + 1);
IEnumerable<int> player2Scores = Enumerable.Range(p2Start, p2MaxPointsToAdd + 1);

var dctMatchIDToScores = new Dictionary<int,>();

int currentMatchID = 0;

foreach (int score1 in player1Scores)
{
foreach (int score2 in player2Scores)
{
}
}

return dctMatchIDToScores;
}```
Now: test by executing this code in some Method, or EventHandler:
C#
```Dictionary<int,> Matches = CalculatePossibleMatches(10, 4, 11, 1);

foreach (var kvp in Matches)
{
MatchData scores = kvp.Value;

Console.WriteLine("Match: #{0} Player 1: {1} Player2: {2}", kvp.Key, scores.player1Score,
scores.player2Score);
}```
Observe the result in the 'Output window (WinForms), or Console. Put a break-point in the test code before the 'foreach loop and examine the value of the Dictionary object returned from 'CalculatePossibleMatches.

1. we use Linq's strongly typed IEnumerable here to hold a Range of possible scores, given the input data. The Enumerable.Range method returns a sequence; that sequence must be stored in a variable of Type IEnumerable ... don't ask me why, ask Microsoft :)

2. one 'foreach loop inside another 'foreach loop does the right thing to access every possible pair of scores.

3. a new instance of the 'MatchData struct is created, the data for each Match is inserted into it via its constructor, and a new entry is made in the Dictionary with the Key set to the Match ID number, and the Value set to the instance of MatchData.

1. what are the benefits of building a Dictionary, and using a 'Struct ?

a. we can then use Linq in very powerful ways to query that Dictionary, and produce summary results of any type, or select items based on one, or many, criteria.

b. imho, the techniques shown here clearly express the "intent" of the code, that is the "nature" of problem-solving required.

v4
Andreas Gieriet 7-Dec-14 1:29am
Hello BillWoodruff,
the `Enumberable.Range(...)` has a count as second argument, not a sentry element (as it is in C++). The `Range` returns a respective iterator, i.e. an object providing a `GetEnumerator()` method. See also C# Iterator Pattern demystified.
[EDIT] Ah, I see, you did not pass the End Score but some count that you increment for some reason. I confused p1Max to be end score as mentioned in the OP. [/EDIT]
Cheers
Andi
BillWoodruff 7-Dec-14 1:48am
Hi Andreas, I do understand the Enumerable.Range, and use it frequently; examining my code, I think the only thing that could suggest that I am using the second argument as a range-limit, rather than a count, is the names I chose for the variables.

I always welcome any feedback that helps me improve the readability of my code.

thanks, Bill
Andreas Gieriet 7-Dec-14 7:41am
Hello Bill,
you are welcome. Now the OP has the choice between recursive and iterator based approach. No matter what approach he selects, he will have to put some effort into it to explain the solution to the teacher. ;-)
Cheers
Andi

## Solution 3

Here i have created a simple console application to get your output.Hope this helps you :-)

C#
```bool minCurrScoreIsP1 = false;

Console.WriteLine("Enter Player1 Current Score...");
Console.WriteLine("Enter Player2 Current Score...");

Console.WriteLine("Enter Player1 Final Score...");
Console.WriteLine("Enter Player2 Final Score...");

int P1PointDiff = lastP1 - currP1;
int P2PointDiff = lastP2 - currP2;

int minDiffP = -1;
int MinCurrIter = -1;

int maxDiffP = -1;
int MaxCurrIter = -1;

if(currP1 < currP2)
{
minDiffP = currP1;
maxDiffP = currP2;
MinCurrIter = lastP1 - currP1;
MaxCurrIter = lastP2 - currP2;
minCurrScoreIsP1 = true;
}
else
{
minDiffP = currP2;
maxDiffP = currP1;
MinCurrIter = lastP2 - currP2;
MaxCurrIter = lastP1 - currP1;
minCurrScoreIsP1 = false;
}

for (int k = 0; k <= MinCurrIter; k++)
{
for (int i = 0; i <= MaxCurrIter; i++ )
{
if ((minDiffP + k + 1) == maxDiffP && (i + 1 + maxDiffP) == maxDiffP)
{
break;
}
else
{
if (minCurrScoreIsP1)
Console.WriteLine("Combinations >> " + "P1 " + (minDiffP + k) + ":" + "P2 " + (i + maxDiffP));
else
Console.WriteLine("Combinations >> " + "P2 " + (minDiffP + k) + ":" + "P1 " + (i + maxDiffP));
}
}
}