英文:
add a layer of function to create a sequencing
问题
目标是创建一个序列函数,其中一名选手的比赛应该在他之前的比赛后的3-4场比赛后匹配。
当前输出:(正如我们在这里所看到的,选手保罗的比赛编号为1,保罗的下一场比赛是比赛编号2...这不应该发生,因为保罗再次比赛之前必须有2-3场比赛的间隔。)
const data = [
{"id":"1","fighter1":"paul","fighter2":"anna","fightNumber":1},
{"id":"2","fighter1":"jack","fighter2":"paul","fightNumber":2}, // 错误,选手的比赛不应该连续。必须在再次匹配之前有2-3场比赛的间隔。
{"id":"3","fighter1":"roger","fighter2":"law","fightNumber":3},
{"id":"4","fighter1":"lee","fighter2":"law","fightNumber":4},
{"id":"5","fighter1":"law","fighter2":"paul","fightNumber":5},
{"id":"6","fighter1":"roger","fighter2":"anna","fightNumber":6},
{"id":"7","fighter1":"lee","fighter2":"jack","fightNumber":7},
{"id":"8","fighter1":"roger","fighter2":"anna","fightNumber":8},
{"id":"9","fighter1":"lee","fighter2":"jack","fightNumber":9}
];
目标输出:(正如我们在这里所看到的,保罗的比赛是比赛编号1和比赛编号4,之间有3场比赛的间隔。)
const new_result= [
{"id":"1","fighter1":"paul","fighter2":"anna","fightNumber":1},
{"id":"2","fighter1":"jack","fighter2":"paul","fightNumber":4},
{"id":"3","fighter1":"roger","fighter2":"law","fightNumber":2},
{"id":"4","fighter1":"lee","fighter2":"law","fightNumber":6},
{"id":"5","fighter1":"law","fighter2":"paul","fightNumber":7},
{"id":"6","fighter1":"roger","fighter2":"anna","fightNumber":5},
{"id":"7","fighter1":"lee","fighter2":"jack","fightNumber":3},
{"id":"8","fighter1":"roger","fighter2":"jack","fightNumber":8},
{"id":"9","fighter1":"lee","fighter2":"anna","fightNumber":9}
];
这是我使用的代码:
const usedFightNumbers = new Set();
const dataGroupedByName = data.reduce((groups, item) => {
const groupName = item.fighter1;
if (!groups[groupName]) {
groups[groupName] = [];
}
groups[groupName].push(item);
return groups;
}, {});
for (const groupName in dataGroupedByName) {
dataGroupedByName[groupName].sort((a, b) => parseInt(a.fightNumber) - parseInt(b.fightNumber));
}
let result = [];
let i = 0;
while (true) {
let done = true;
for (const groupName in dataGroupedByName) {
const group = dataGroupedByName[groupName];
if (i < group.length) {
const newItem = { ...group[i], fightNumber: String(result.length + 1) };
while (usedFightNumbers.has(newItem.fightNumber)) {
newItem.fightNumber = String(parseInt(newItem.fightNumber) + 0.5);
}
result.push(newItem);
usedFightNumbers.add(newItem.fightNumber);
done = false;
}
}
if (done) {
break;
}
i++;
}
console.log(result);
这段代码的问题在于,间隔有时很小,比如只有1-2场比赛的间隔,有时间隔太大,达到40场比赛的间隔。
是否有一种方法可以重构这段代码并实现我的目标?
谢谢。
英文:
My target is to create a sequence function where a fighter's fight should be matched after 3-4 fights after his previous fights.
Current output: (As we can see here, fighter paul had the fightNumber":1, paul's next match is fightNumber":2... This shouldn't happen because there must be a fightNumber gap of 2-3 fights before Paul can fight again.
const data = [
{"id":"1","fighter1":"paul","fighter2":"anna","fightNumber":1},
{"id":"2","fighter1":"jack","fighter2":"paul","fightNumber":2}, // wrong, fighter's fight should not be consecutively. there should be a gap of 2-3 fights before it can be matched again.
{"id":"3","fighter1":"roger","fighter2":"law","fightNumber":3},
{"id":"4","fighter1":"lee","fighter2":"law","fightNumber":4},
{"id":"5","fighter1":"law","fighter2":"paul","fightNumber":5},
{"id":"6","fighter1":"roger","fighter2":"anna","fightNumber":6},
{"id":"7","fighter1":"lee","fighter2":"jack","fightNumber":7},
{"id":"8","fighter1":"roger","fighter2":"anna","fightNumber":8},
{"id":"9","fighter1":"lee","fighter2":"jack","fightNumber":9}
];
Target output: (As we can see here, paul's fight was fightnumber 1 and fightNumber 4, there's a 3 gap of fightnumber before he matched again.
const new_result= [
{"id":"1","fighter1":"paul","fighter2":"anna","fightNumber":1},
{"id":"2","fighter1":"jack","fighter2":"paul","fightNumber":4},
{"id":"3","fighter1":"roger","fighter2":"law","fightNumber":2},
{"id":"4","fighter1":"lee","fighter2":"law","fightNumber":6},
{"id":"5","fighter1":"law","fighter2":"paul","fightNumber":7},
{"id":"6","fighter1":"roger","fighter2":"anna","fightNumber":5},
{"id":"7","fighter1":"lee","fighter2":"jack","fightNumber":3},
{"id":"8","fighter1":"roger","fighter2":"jack","fightNumber":8},
{"id":"9","fighter1":"lee","fighter2":"anna","fightNumber":9}
];
This is the code i used
const usedFightNumbers = new Set();
const dataGroupedByName = data.reduce((groups, item) => {
const groupName = item.fighter1;
if (!groups[groupName]) {
groups[groupName] = [];
}
groups[groupName].push(item);
return groups;
}, {});
for (const groupName in dataGroupedByName) {
dataGroupedByName[groupName].sort((a, b) => parseInt(a.fightNumber) - parseInt(b.fightNumber));
}
let result = [];
let i = 0;
while (true) {
let done = true;
for (const groupName in dataGroupedByName) {
const group = dataGroupedByName[groupName];
if (i < group.length) {
const newItem = { ...group[i], fightNumber: String(result.length + 1) };
while (usedFightNumbers.has(newItem.fightNumber)) {
newItem.fightNumber = String(parseInt(newItem.fightNumber) + 0.5);
}
result.push(newItem);
usedFightNumbers.add(newItem.fightNumber);
done = false;
}
}
if (done) {
break;
}
i++;
}
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-js -->
const data = [
{ id: "1", fighter1: "paul", fighter2: "anna", fightNumber: 1 },
{ id: "2", fighter1: "jack", fighter2: "paul", fightNumber: 2 },
{ id: "3", fighter1: "roger", fighter2: "law", fightNumber: 3 },
{ id: "4", fighter1: "lee", fighter2: "law", fightNumber: 4 },
{ id: "5", fighter1: "law", fighter2: "paul", fightNumber: 5 },
{ id: "6", fighter1: "roger", fighter2: "anna", fightNumber: 6 },
{ id: "7", fighter1: "lee", fighter2: "jack", fightNumber: 7 },
{ id: "8", fighter1: "roger", fighter2: "anna", fightNumber: 8 },
{ id: "9", fighter1: "lee", fighter2: "jack", fightNumber: 9 },
];
const usedFightNumbers = new Set();
const dataGroupedByName = data.reduce((groups, item) => {
const groupName = item.fighter1;
if (!groups[groupName]) {
groups[groupName] = [];
}
groups[groupName].push(item);
return groups;
}, {});
for (const groupName in dataGroupedByName) {
dataGroupedByName[groupName].sort(
(a, b) => parseInt(a.fightNumber) - parseInt(b.fightNumber)
);
}
let result = [];
let i = 0;
while (true) {
let done = true;
for (const groupName in dataGroupedByName) {
const group = dataGroupedByName[groupName];
if (i < group.length) {
const newItem = { ...group[i], fightNumber: String(result.length + 1) };
while (usedFightNumbers.has(newItem.fightNumber)) {
newItem.fightNumber = String(parseInt(newItem.fightNumber) + 0.5);
}
result.push(newItem);
usedFightNumbers.add(newItem.fightNumber);
done = false;
}
}
if (done) {
break;
}
i++;
}
console.log(result);
<!-- end snippet -->
The problem with this code is that, the gap sometimes are little like 1-2 fight number gap only and sometimes the gap is too huge that it reaches 40 fight number gap.
Is there a way where i can reconstruct this code and achieve my goal?
Thank you
答案1
得分: 3
我成功地为分配的任务创建了算法。请注意,某个时候提供的数据不足,下一场比赛将没有可用的自由斗士,所以在某个时候比赛会变得空无一人,只提供数字。
它按照分配的任务完美运行,希望它能满足您的需求。如果需要的话,请随时问我关于我的代码的问题。
尝试代码段:
const data = [
{ id: "1", fighter1: "paul", fighter2: "anna", fightNumber: null },
{ id: "2", fighter1: "jack", fighter2: "paul", fightNumber: null },
{ id: "3", fighter1: "roger", fighter2: "law", fightNumber: null },
{ id: "4", fighter1: "lee", fighter2: "law", fightNumber: null },
{ id: "5", fighter1: "law", fighter2: "paul", fightNumber: null },
{ id: "6", fighter1: "roger", fighter2: "anna", fightNumber: null },
{ id: "7", fighter1: "lee", fighter2: "jack", fightNumber: null },
{ id: "8", fighter1: "roger", fighter2: "anna", fightNumber: null },
{ id: "9", fighter1: "lee", fighter2: "jack", fightNumber: null },
];
function calculatreFight() {
const gapNumber = parseInt(document.getElementById("gapNumberInput").value);
const tiredFightersList = [];
const compiledIndexes = [];
const fights = data.map((element, index) => {
const tiredFighters = tiredFightersList.slice(-gapNumber).reduce((prev, curr) => {
curr.map(fighter => !prev.includes(fighter) ? prev.push(fighter) : null)
return prev;
}, []);
let searchIndex = 0;
while (tiredFighters.includes(data[searchIndex]?.fighter1) ||
tiredFighters.includes(data[searchIndex]?.fighter2) ||
compiledIndexes.includes(searchIndex)) {
searchIndex += 1;
if (searchIndex >= data.length) break;
}
tiredFightersList[index] = [data[searchIndex]?.fighter1, data[searchIndex]?.fighter2];
compiledIndexes.push(searchIndex);
return {
...data[searchIndex],
fightNumber: index
};
}, []);
console.log(fights);
}
<label>Select how many gap fights should a fighter have: </label>
<select name="gap" id="gapNumberInput">
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
</select>
<br>
<button onclick="calculatreFight()">Calculate</button>
<br><br><br>
<p>Remember that as bigger the gap is, the fewer possible solutions are there and so there are going to be fights that are with no figthers</p>
英文:
I managed to create the algorithm for the assigned task. Keep in mind that at some point the provided data is not enough and there are going to be no free fighters to be used in the next fight so this is why at some point the fights are getting empty and only number is provided.
it works exactly as assigned so hopefully it is going to fit your need. Feel free to ask questions about my code in case of need.
Try the code snippet:
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-js -->
const data = [
{ id: "1", fighter1: "paul", fighter2: "anna", fightNumber: null },
{ id: "2", fighter1: "jack", fighter2: "paul", fightNumber: null },
{ id: "3", fighter1: "roger", fighter2: "law", fightNumber: null },
{ id: "4", fighter1: "lee", fighter2: "law", fightNumber: null },
{ id: "5", fighter1: "law", fighter2: "paul", fightNumber: null },
{ id: "6", fighter1: "roger", fighter2: "anna", fightNumber: null },
{ id: "7", fighter1: "lee", fighter2: "jack", fightNumber: null },
{ id: "8", fighter1: "roger", fighter2: "anna", fightNumber: null },
{ id: "9", fighter1: "lee", fighter2: "jack", fightNumber: null },
];
function calculatreFight() {
const gapNumber = parseInt(document.getElementById("gapNumberInput").value);
const tiredFightersList = [];
const compiledIndexes = [];
const fights = data.map((element, index) => {
const tiredFighters = tiredFightersList.slice(-gapNumber).reduce((prev, curr) => {
curr.map(fighter => !prev.includes(fighter) ? prev.push(fighter) : null)
return prev;
}, []);
let searchIndex = 0;
while (tiredFighters.includes(data[searchIndex]?.fighter1) ||
tiredFighters.includes(data[searchIndex]?.fighter2) ||
compiledIndexes.includes(searchIndex)) {
searchIndex += 1;
if (searchIndex >= data.length) break;
}
tiredFightersList[index] = [data[searchIndex]?.fighter1, data[searchIndex]?.fighter2];
compiledIndexes.push(searchIndex);
return {
...data[searchIndex],
fightNumber: index
};
}, []);
console.log(fights);
}
<!-- language: lang-html -->
<label>Select how many gap fights should a fighter have: </label>
<select name="gap" id="gapNumberInput">
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
</select>
<br>
<button onclick="calculatreFight()">Calculate</button>
<br><br><br>
<p>Remember that as bigger the gap is, the fewer possible solutions are there and so there are going to be fights that are with no figthers</p>
<!-- end snippet -->
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论