I appreciate your help in advance in this exercise in which the truth I have not discovered how to solve it
How to dynamically generate possible encounters between teams?
Having the following input fields
- start date
- teams
- fields
- days to play
With for example the following data
const startDate = "03-08-2020";
const teams = ["A", "B", "C", "D", "E", "F"];
const fields = ["Field1", "Field2"];
const daysToPlay = ["Monday", "Wednesday"];
Now and from this data I need to dynamically generate the game days with their game matching, the playing fields must be interchanged like the days from date to date. Starting from startDate value
An example of output is as follows
const output = [
{
number: 1,
date: "03-08-2020", // Monday
field: "Field1",
matches: [
["A", "B"],
["C", "D"],
["E", "F"],
],
},
{
number: 2,
date: "05-08-2020", // Wednesday
field: "Field2",
matches: [
["A", "C"],
["B", "E"],
["C", "F"],
],
},
];
In this way, according to the number of unique possible encounters between teams.
Update 0
- All teams must play on each date
- The number of teams is always even
- The tournament ends when each team has played against all the others,
Update 1
I am following Oliver suggestion but in the last set of matches I am getting a single match, here I am expecting two matches like the previous ones
const teams = ["A", "B", "C", "D"];
const getCombinations = (data) => {
let output = [];
for (let i = 0; i < teams.length - 1; i++) {
for (let j = i + 1; j < teams.length; j++) {
output = [...output, [data[i], data[j]]];
}
}
return output;
};
const getMatches = (data) => {
let matches = [];
let i = 0;
while (data.length) {
for (const [index, entry] of data.entries()) {
if (index === 0) {
matches.push([entry]);
data.splice(index, 1);
continue;
}
const [team1, team2] = entry;
const idx = matches[i].findIndex(
(value) => value.includes(team1) || value.includes(team2)
);
if (idx !== -1) {
continue;
}
matches[i].push(entry);
data.splice(index, 1);
}
i++;
}
return matches;
};
const combinations = getCombinations(teams);
const matches = getMatches(combinations);
console.log(matches);
Update 2
Fix to the previous update
const teams = ["A", "B", "C", "D"];
const getCombinations = (data) => {
let output = [];
for (let i = 0; i < teams.length - 1; i++) {
for (let j = i + 1; j < teams.length; j++) {
output = [...output, [data[i], data[j]]];
}
}
return output;
};
const getMatches = (data) => {
let matches = [];
let i = 0;
while (data.length) {
for (const [index, entry] of data.entries()) {
if (data.length === 1) {
matches[i - 1].push(entry);
data.splice(index, 1);
break;
}
if (index === 0) {
matches.push([entry]);
data.splice(index, 1);
continue;
}
const [team1, team2] = entry;
const idx = matches[i].findIndex(
(value) => value.includes(team1) || value.includes(team2)
);
if (idx !== -1) {
continue;
}
matches[i].push(entry);
data.splice(index, 1);
}
i++;
}
return matches;
};
const combinations = getCombinations(teams);
console.log(combinations);
const matches = getMatches(combinations);
console.log(matches);
Update 3
I am almost there
I am having problems to implement the task related to date, how do I get correct date. In order to make the solution easier, I have managed to change the input of game days by the number of the day of the week instead of the name of the day, in this way
Sunday 0
...
Saturday 6
In the example, the days correspond to Monday (1)
and Wednesday (3)
I appreciate your comment
const startDate = "2020-08-03";
const matchDays = [1, 3];
const fields = ["Field 1", "Field 2"];
const teams = ["A", "B", "C", "D"];
const getCombinations = (data) => {
let output = [];
for (let i = 0; i < teams.length - 1; i++) {
for (let j = i + 1; j < teams.length; j++) {
output = [...output, [data[i], data[j]]];
}
}
return output;
};
const getMatches = (data) => {
let matches = [];
let i = 0;
while (data.length) {
for (const [index, entry] of data.entries()) {
if (data.length === 1) {
matches[i - 1].push(entry);
data.splice(index, 1);
break;
}
if (index === 0) {
matches.push([entry]);
data.splice(index, 1);
continue;
}
const [team1, team2] = entry;
const idx = matches[i].findIndex(
(value) => value.includes(team1) || value.includes(team2)
);
if (idx !== -1) {
continue;
}
matches[i].push(entry);
data.splice(index, 1);
}
i++;
}
return matches;
};
const getGameDays = (data) => {
const options = {
year: "numeric",
month: "2-digit",
day: "2-digit",
};
return data.map((entry, index) => {
return {
number: index + 1,
date:
index === 0
? new Date(startDate).toLocaleDateString("es-ES", options)
: new Date(startDate).toLocaleDateString("es-ES", options), // Here I need to move on every target day of week in matchDays
field:
fields.length === 1
? fields[0]
: index === 0
? fields[0]
: index % 2 === 0
? fields[0]
: fields[1],
matches: [...entry],
};
});
};
const combinations = getCombinations(teams);
console.log(combinations);
const matches = getMatches(combinations);
console.log(matches);
const gameDays = getGameDays(matches);
console.dir(gameDays, { depth: null, color: true });
At this time set the starting date on each day
Thank you