Solving the UEFA Champions League problem on Code Chef with OOP

So I decided to try out code chef, and chose to solve the UCL problem listed on the home page of the ‘practice’ portion of code chef. The problem statement was detailed and easy to understand, you can view it here. It basically involves inputting the match results for a league in the following format:

<home team> <home team goals> vs. <away team goals> <away team>

for instance, fcbarca 5 vs. 1 realmadrid

12 match results are inputted, and match results for T leagues are taken in. The output for each league should be the names of the winning team and the runner-up. For instance, the output for the following league schedule/results,

manutd 8 vs. 2 arsenal
lyon 1 vs. 2 manutd
fcbarca 0 vs. 0 lyon
fcbarca 5 vs. 1 arsenal
manutd 3 vs. 1 fcbarca
arsenal 6 vs. 0 lyon
arsenal 0 vs. 0 manutd
manutd 4 vs. 2 lyon
arsenal 2 vs. 2 fcbarca
lyon 0 vs. 3 fcbarca
lyon 1 vs. 0 arsenal
fcbarca 0 vs. 1 manutd

would be

manutd fcbarca

Here are some basic rules we observe for football tournaments. Each victory gives you 3 points, each lose gives you 0 points, each draw gives you 1 point. If two teams have the same point tally, the team with the higher goal difference is placed first. For simplicity’s sake, we’re assuming here that no two teams with the same point total will have the same goal difference.

I defined two classes, League, and Team right at the start. The only attribute an instance of the League would have would be table, which is a dictionary wherein the key is a string pertaining to the team’s name and the value if a Team object containing all necessary information. I also put five methods inside the League class, which I’ll be explaining just in a bit.

League Class

The does_team_exist() method just returns true or false values pertaining to whether or not the inputted string is a key in the dictionary field. In my main code, if does_teaam_exist() returns False, the add_team() method is called and the self.table attribute is updated with a Team object being added to it. If does_team_exist() returns True, the program continues. match_won() and match_lost() are pretty well defined. The former calls the win() method for the Team object corresponding to the Team that won and the lose() method for the Team object corresponding to the Team that lost. You’ll notice that we also pass in the goal difference here. The latter calls the same draw() method for both, and no gd is passed in because it equals 0 for both times in the event of a drawn match.

return_top-two() is our most important method. It creates a list of all values in the table dictionary. Then, I used a lambda function to sort on the basis of two parameters, points and goal difference. You’ll notice that my first element in the lambda function inside the tuple is the number of points associated with that object, and the second is the goal difference for that team. After sorting all Team objects, I return the team names of the last and second last objects.

Now, I’ll show you the Team Class.

Team Class

This is much simpler. When initializing, the only argumentative input is the team name, while points and team difference are initialized to 0. The win() method increases points by 3 and goal difference by the argumentative input. the draw() method only increments points by 1, and the lose() method decrements goal difference by gd. This is followed by three get methods, two of which are used in the lambda function shown above, and one which is used to get the desired output for our program.

Now, the only part left is our main class or working code. Here it is.

Code

We take in T as our first input as defined by the problem statement, then iterate over each League. Before going into the results for each league, I’ve initialized league to an instance of the League class. I then iterate over each of the 12 fixtures in each league. Splitting the input and extracting certain indices (see code) gives us our values for each team’s name and the number of goals it scored. You can see that I have two “if not”s up there that initialize a new team object inside the table attribute of the League class if the team in question is not there already. Then, I compare home team goals and away team goals and call the appropriate method where needed. Our output is the value returned by the return_top_two().

You can check out the full code here.

Credits to code chef for the problem statement.