Attempting to create distinct match matchups for every team in a manner reminiscent of the Swiss system format used in the 2024/25 UEFA Champion League

I've been working on devising a tournament pairing system modeled after the updated UEFA Champion League structure. The league phase involves 36 teams, categorized into 4 different pots. Each team is scheduled to play a total of 8 matches against 2 opponents from each pot, resulting in a grand total of 144 matches. While attempting to implement this logic, I encountered challenges with developing a function incorporating effective backtracking. Here's the code I've attempted, but unfortunately failed to execute successfully:

https://jsfiddle.net/4cgm1Lo8/5/

const pots = [
    ["A1", "A2", "A3", "A4", "A5", "A6", "A7", "A8", "A9"],
    ["B1", "B2", "B3", "B4", "B5", "B6", "B7", "B8","B9"],
    ["C1", "C2", "C3", "C4", "C5", "C6", "C7", "C8","C9"],
    ["D1", "D2", "D3", "D4", "D5", "D6", "D7", "D8","D9"],
];

const MATCH_COUNT = 144;
const MAX_ROUNDS = 8

function run() {
    const teamIds = _.flatten(pots)
    return teamIds.reduce((matches,thisTeamId) => {
        for (let round = 0; round < MAX_ROUNDS; round++) {
            const thisTeamMatches = matches.filter(match => match.includes(thisTeamId))
            if (thisTeamMatches.length >= MAX_ROUNDS) {
                break;
            }
            const pool = teamIds.filter(poolTeamId => {
                const encounteredBefore = thisTeamMatches.find(match => match.includes(poolTeamId))
                const potEncounterCount = thisTeamMatches.filter(match => {
                    const opponentId = match.find(m => m != thisTeamId)
                    return getTeamPot(opponentId, pots) === getTeamPot(poolTeamId, pots)
                })
                const poolTeamIdMatches = matches.filter(match => match.includes(poolTeamId))
                return poolTeamId != thisTeamId && !encounteredBefore && potEncounterCount.length < 2 && poolTeamIdMatches.length < MAX_ROUNDS
            })
            matches.push([thisTeamId, _.sample(pool)])
        }
        return matches
    }, [] as string[][])
}



function getTeamPot(teamId: string, pots: string[][]) {
    return pots.findIndex((pot) =>
        pot.find((potTeamId) => potTeamId === teamId),
    );
}

function getOpponent(yourTeamId: string, match: string[][]){
    return match.find(m => m != thisTeamId)                 
}

console.log(run())

The current function falls short of creating all 144 matches required. Some matchups generated have undefined opponents due to certain limitations within the code. It struggles to handle scenarios where a suitable opponent cannot be found for a particular team.

What approach would you suggest implementing a robust backtracking method capable of filling in the missing matchups with undefined opponents?

Answer №1

One way to approach this problem is by exhaustively trying out all possible team combinations and excluding any team that already has 2 matches in a pot.

It seems there is an error in your total match count calculation - you have 32 teams, not 36, so the correct answer is 128

const pots = [
    ["A1", "A2", "A3", "A4", "A5", "A6", "A7", "A8"],
    ["B1", "B2", "B3", "B4", "B5", "B6", "B7", "B8"],
    ["C1", "C2", "C3", "C4", "C5", "C6", "C7", "C8"],
    ["D1", "D2", "D3", "D4", "D5", "D6", "D7", "D8"],
];

let set = new Set, counts = {}, matches = [], potMatchCount = 2;

const shuffle = arr => {
  const copy = arr.slice();
  return Array.from({length: arr.length}, () => copy.splice(Math.random()*copy.length|0, 1)[0]);
};

const push = (a, b) => {
  if(a === b) return;
  const key = [a,b].sort().join('');
...

console.log('milliseconds spent:', performance.now() - start);
console.log('total matches:', matches.length);
console.log('trials:', trial);
//console.log(JSON.stringify(matches));

const grouped = pots.flat().map(team => [team, matches.filter(arr => arr.includes(team)).map(arr => arr.filter(t => t !== team)[0])]);
grouped.forEach(team => console.log(team[0], ':', ...team[1].sort()));
.as-console-wrapper{max-height:100%!important}

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

What steps should one take to address issues related to Datatables in Laravel and Vue?

I encountered an issue while trying to fetch data into a datatable in Laravel. I am receiving an error message stating "Uncaught ReferenceError: $ is not defined" on the console of the page. Is there a solution to resolve this problem? index.blade.php ...

Different approach to loading Handlebars template instead of using fs.readFile with res.json in Express

In my efforts to create a straightforward live API endpoint (using res.json()) within an Express 4 application that merges Handlebars templates with data and sends back a string for client-side HTML replacement, I've encountered a challenge. The curr ...

Retrieving data from a textbox using JavaScript within an Excel VBA setting

I'm encountering an issue with a Macro in Excel where I need to retrieve the value of an "input type="text"" on a JavaScript webpage. However, the value is not specified in the code (value=""), and it remains unchanged even when the webpage displays t ...

CSS: Strategies for eliminating empty cells within a grid layout by filtering out rows that contain partial or incomplete content

I am in need of creating a grid layout where each div is a specific width, and the number of rows depends on how many items there are. The twist is that I am unsure of the width of the outer container. My initial solution was to use CSS grid: #container ...

Get a list of images by incorporating NextJs and Strapi to create a dynamic slider feature

[] I need help creating a slider as I am encountering an error when trying to output an array of objects. The error can be seen here: . Can someone assist me in resolving this issue? Thank you. Here is a screenshot from the admin panel: 1 Below is the c ...

Is Nuxt's FingerprintJS Module the Ultimate Server and Client Solution?

I am currently using fingerprintJS in my NuxtJS+Firebase project VuexStore. When I call the function on the client side, I can retrieve the Visitor ID. However, I am encountering issues when trying to use it on the server side, such as in nuxtServerInit. ...

Executing pure JavaScript code in Grails using Groovy

this is a duplicate of Executing groovy statements in JavaScript sources in Grails with a slight variation, my intention is to only render the js-code without enclosing it in script tags picture someone loading a script from my server within their html l ...

Retrieve the URL with a GET request and remove a specific object

Currently, I am working on developing a CRUD (Create, Read, Update, Delete) App using Express and LowDB. So far, I have successfully implemented the create and read functions, but I am facing issues with the delete function. This is an example of what th ...

The functionality of the custom file upload button is experiencing issues on Microsoft Edge

I've been working on creating a unique custom image upload button that functions perfectly in Chrome, Firefox, and Opera based on my testing. However, I'm facing an issue where it doesn't work properly in Microsoft Edge. Feel free to check ...

Struggling to create a TypeScript definition file - the JSX element 'SideMenu' lacks any construct or call signatures

I am currently working on creating a type definition file for react-native-side-menu in order to properly declare it. I have integrated it into a TypeScript project, but unfortunately, there are no TypeScript definitions available. Normally, my approach i ...

Obtain unfinished designs from resolver using GraphQL Code Generator

In order to allow resolvers to return partial data and have other resolvers complete the missing fields, I follow this convention: type UserExtra { name: String! } type User { id: ID! email: String! extra: UserExtra! } type Query { user(id: ID! ...

Issue when activating Materialize Bootstrap

I'm facing an issue with my code. I have implemented a feature where a modal should be triggered after a user successfully adds a new user. However, I am using Materialize and the modal is not being triggered. Below is a snippet of my code: <div i ...

The findOneAndUpdate function in MongoDB is adding a new record into the database

Whenever I make an update API call, I just need to update the serviceActiveFlag status. After the update API call, a new document with an empty vehicle array is created, as shown below: _id:59c76073c11d3929148f500f vehicle:Array _v:0 The ID field will ov ...

Error encountered while attempting to generate migration in TypeORM entity

In my project, I have a simple entity named Picture.ts which contains the following: const { Entity, PrimaryGeneratedColumn, Column } = require("typeorm"); @Entity() export class Picture { @PrimaryGeneratedColumn() ...

Display HTML instead of text in print mode

Hello, I need help with printing HTML code, specifically an iframe. When I try to add my HTML iframe code, it only prints as plain text. I want to be able to see the actual iframe with its content displayed. Thank you. <script> const messages = [&apo ...

How can the node version be set globally in NVM?

While utilizing Node Version Manager, setting the node version to the latest one in the current directory can be done using nvm use node. But how can you specify a specific version to use? ...

What is the proper way to invoke a function that is part of a child component as a property in a React application?

In my app.js file, I have included a unique component called "SigningComponent" with the following code: onSign = () => { this.setState({ route: "home" }); }; registerFunction = () => { this.setState({ route: "registration" }); }; render() { ...

The directive in Angular compels the webpage to carry out the added HTML attribute

There is a custom directive in my code that applies the spellcheck attribute to two div elements as shown below: (function(){ 'use strict'; app.directive('spellchecker', spellchecker); spellchecker.$inject = ['$timeout&a ...

The custom form input in Angular2 is throwing an error because it is trying to access the property 'name' of an

Upon switching to the latest Angular version 2 final, I encountered the following error Uncaught TypeError: Cannot read property 'name' of undefined This is my customized input import { Component, EventEmitter, Provider, forwardRef } from &a ...

The spring submission function requires the use of two parameters

As a beginner in spring web applications, I am facing an issue where the request mapping receives a "dual" parameter when I submit a form. The form structure is as follows: <form action="" method="post" name="myform"> ...... </form> To submit ...