Userscript to show the number of teams that have solved each problem on Universal Cup contests.
- Install Tamper Monkey as a browswer extension.
- Add the script universal_cup_enhanced.user.js to the extension.
Userscript to show the number of teams that have solved each problem on Universal Cup contests.
| // ==UserScript== | |
| // @name Universal Cup Enhanced | |
| // @namespace http://tampermonkey.net/ | |
| // @version 2024-06-18 | |
| // @description Provide extra information and tools for problems dashboard | |
| // @author Marcelo Fornet | |
| // @match https://contest.ucup.ac/contest/* | |
| // @icon https://www.google.com/s2/favicons?sz=64&domain=ucup.ac | |
| // @grant none | |
| // ==/UserScript== | |
| // https://stackoverflow.com/a/2091331/4950797 | |
| function getQueryVariable(key, defaultValue) { | |
| var query = window.location.search.substring(1); | |
| var vars = query.split('&'); | |
| for (var i = 0; i < vars.length; i++) { | |
| var pair = vars[i].split('='); | |
| if (decodeURIComponent(pair[0]) == key) { | |
| return decodeURIComponent(pair[1]); | |
| } | |
| } | |
| return defaultValue; | |
| } | |
| (function() { | |
| 'use strict'; | |
| let currentPage = window.location.href; | |
| let match = currentPage.match(/^https?:\/\/contest.ucup.ac\/contest\/\d+(\?.*)?$/); | |
| if (match === null) { | |
| return; | |
| } | |
| let sortBySolved = getQueryVariable('sortBySolved', 'True') === 'True'; | |
| let qMarkIndex = currentPage.indexOf('?'); | |
| if (qMarkIndex !== -1) { | |
| currentPage = currentPage.slice(0, qMarkIndex); | |
| } | |
| fetch(currentPage + '/standings') | |
| .then(data => data.text()) | |
| .then(htmlString => { | |
| const re = /\nscore=[^\n]*\n/ | |
| let matches = htmlString.match(re); | |
| let standingString = matches[0]; | |
| standingString = standingString.slice(7, -2); | |
| let standing = JSON.parse(standingString); | |
| let problems = {}; | |
| for (var team in standing) { | |
| let submissions = standing[team]; | |
| for (var problem in submissions) { | |
| let result = submissions[problem]; | |
| if (result[1] !== 0) { | |
| if (problem in problems) { | |
| problems[problem] = problems[problem] + 1; | |
| } else { | |
| problems[problem] = 1; | |
| } | |
| } | |
| } | |
| } | |
| let table = document.getElementsByTagName('table')[0]; | |
| let rows = table.getElementsByTagName('tr'); | |
| let header = rows[0]; | |
| let firstColumn = header.getElementsByTagName('th')[0]; | |
| let sortById = document.createElement('a'); | |
| sortById.href = currentPage + '?sortBySolved=False'; | |
| sortById.textContent = '▼'; | |
| firstColumn.textContent = '# '; | |
| firstColumn.appendChild(sortById); | |
| let th = document.createElement('th'); | |
| th.textContent = 'Solved by '; | |
| let sortBySolvedButton = document.createElement('a'); | |
| sortBySolvedButton.href = currentPage + '?sortBySolved=True'; | |
| sortBySolvedButton.textContent = '▼'; | |
| th.appendChild(sortBySolvedButton); | |
| header.appendChild(th); | |
| let allRows = []; | |
| let ix = 1; | |
| while (ix < rows.length) { | |
| let problemId = ix - 1; | |
| let solvedBy = 0; | |
| if (problemId in problems) { | |
| solvedBy = problems[problemId]; | |
| } | |
| let td = document.createElement('td'); | |
| td.textContent = solvedBy; | |
| rows[ix].appendChild(td); | |
| allRows.push({'row': rows[ix], solvedBy}); | |
| ix += 1; | |
| } | |
| if (sortBySolved) { | |
| while (ix > 1) { | |
| ix -= 1; | |
| table.deleteRow(ix); | |
| } | |
| let body = table.getElementsByTagName('tbody')[0]; | |
| allRows.sort((a, b) => b.solvedBy - a.solvedBy); | |
| for (let row of allRows) { | |
| body.appendChild(row.row); | |
| } | |
| } | |
| }); | |
| })(); |