// Toggle leaderboard visibility const toggleBtn = document.getElementById('toggleLeaderboard'); const leaderboardSection = document.getElementById('leaderboardSection'); const contentContainer = document.getElementById('contentContainer'); toggleBtn.addEventListener('click', () => { if (leaderboardSection.style.display === 'none') { leaderboardSection.style.display = ''; toggleBtn.textContent = 'Hide'; contentContainer.classList.remove('single-column'); } else { leaderboardSection.style.display = 'none'; toggleBtn.textContent = 'Show'; contentContainer.classList.add('single-column'); } }); // Problem search functionality const problemSearch = document.getElementById('problemSearch'); const problemsContainer = document.getElementById('problemsContainer'); const problemItems = problemsContainer.querySelectorAll('.problem-item'); problemSearch.addEventListener('input', () => { const searchTerm = problemSearch.value.toLowerCase(); problemItems.forEach(item => { const name = item.dataset.name.toLowerCase(); const desc = item.dataset.desc?.toLowerCase() || ''; if (name.includes(searchTerm) || desc.includes(searchTerm)) { item.style.display = ''; } else { item.style.display = 'none'; } }); }); // Leaderboard filtering and sorting const userSearch = document.getElementById('userSearch'); const problemFilter = document.getElementById('problemFilter'); const runtimeFilter = document.getElementById('runtimeFilter'); const leaderboardBody = document.getElementById('leaderboardBody'); const leaderboardRows = Array.from(leaderboardBody.querySelectorAll('tr')); const sortableHeaders = document.querySelectorAll('.sortable'); // Current sort state let currentSort = { column: null, direction: 'asc' }; // Filter leaderboard function filterLeaderboard() { const userTerm = userSearch.value.toLowerCase(); const problemTerm = problemFilter.value.toLowerCase(); const runtimeType = runtimeFilter.value; leaderboardRows.forEach(row => { const user = row.dataset.user.toLowerCase(); const problem = row.dataset.problem.toLowerCase(); const runtime = parseFloat(row.dataset.runtime); const showUser = user.includes(userTerm); const showProblem = problem.includes(problemTerm); let showRuntime = true; if (runtimeType === 'best') { // Find if this is the best runtime for this user+problem combo const userProblemRows = leaderboardRows.filter(r => r.dataset.user === row.dataset.user && r.dataset.problem === row.dataset.problem ); const bestRuntime = Math.min(...userProblemRows.map(r => parseFloat(r.dataset.runtime))); showRuntime = runtime === bestRuntime; } else if (runtimeType === 'worst') { // Find if this is the worst runtime for this user+problem combo const userProblemRows = leaderboardRows.filter(r => r.dataset.user === row.dataset.user && r.dataset.problem === row.dataset.problem ); const worstRuntime = Math.max(...userProblemRows.map(r => parseFloat(r.dataset.runtime))); showRuntime = runtime === worstRuntime; } if (showUser && showProblem && showRuntime) { row.style.display = ''; } else { row.style.display = 'none'; } }); } // Sort leaderboard function sortLeaderboard(column, direction) { const rows = Array.from(leaderboardBody.querySelectorAll('tr')); const index = Array.from(document.querySelectorAll('th')).findIndex(th => th.dataset.sort === column); rows.sort((a, b) => { let aValue = a.cells[index].textContent; let bValue = b.cells[index].textContent; // Special handling for numeric columns if (column === 'runtime' || column === 'memory' || column === 'rank') { aValue = parseFloat(aValue) || 0; bValue = parseFloat(bValue) || 0; return direction === 'asc' ? aValue - bValue : bValue - aValue; } // Special handling for timestamps if (column === 'timestamp') { aValue = new Date(aValue).getTime(); bValue = new Date(bValue).getTime(); return direction === 'asc' ? aValue - bValue : bValue - aValue; } // Default string comparison aValue = aValue.toLowerCase(); bValue = bValue.toLowerCase(); if (aValue < bValue) return direction === 'asc' ? -1 : 1; if (aValue > bValue) return direction === 'asc' ? 1 : -1; return 0; }); // Re-append rows in sorted order rows.forEach(row => leaderboardBody.appendChild(row)); } // Set up event listeners userSearch.addEventListener('input', filterLeaderboard); problemFilter.addEventListener('input', filterLeaderboard); runtimeFilter.addEventListener('change', filterLeaderboard); // Set up sorting sortableHeaders.forEach(header => { header.addEventListener('click', () => { const column = header.dataset.sort; // Reset all sort indicators sortableHeaders.forEach(h => { h.classList.remove('sort-asc', 'sort-desc'); }); // Determine new sort direction if (currentSort.column === column) { currentSort.direction = currentSort.direction === 'asc' ? 'desc' : 'asc'; } else { currentSort.column = column; currentSort.direction = 'asc'; } // Apply new sort header.classList.add(`sort-${currentSort.direction}`); sortLeaderboard(column, currentSort.direction); }); });