您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
コンテスト参加者の色(Rating)別の正解率を表示します.
// ==UserScript== // @name AtCoderColorStandings // @namespace http://tampermonkey.net/ // @version 1.51 // @description コンテスト参加者の色(Rating)別の正解率を表示します. // @author Shobonvip // @match https://atcoder.jp/*standings* // @exclude https://atcoder.jp/*standings/json // @grant none // @license MIT // ==/UserScript== $(function () { // RGBからカラーコードに変換する function rgb2hex ( rgb ) { return "#" + rgb.map( function ( value ) { return ( "0" + value.toString( 16 ) ).slice( -2 ) ; }).join( "" ) ; } // 詳細か否か let detailmode = 0; // Ratedのみを集めるか否か let ratedmode = 0; // 1回以上提出を集めるか否か let submitmode = 1; // 表を先頭に追加 $("#vue-standings").prepend(`<div><button class="btn btn-default" id="colorstanding-detail">詳細に切り替え</button><button class="btn btn-default" id="colorstanding-rated">Unratedも表示中</button><button class="btn btn-default" id="colorstanding-submit">1回以上提出を表示中</button><button class="btn btn-default" id="colorstanding-off">非表示</button><table id="accs-table" class="table table-bordered table-hover th-center td-middle"><thead></thead><tbody></tbody></table></div>`); // 表の更新 function update () { vueStandings.$watch("standings", function (new_val, old_val) { if (detailmode == 1) { $("#colorstanding-detail").empty(); $("#colorstanding-detail").append(`詳細表示中`); } else { $("#colorstanding-detail").empty(); $("#colorstanding-detail").append(`詳細に切り替え`); } if (ratedmode == 1) { $("#colorstanding-rated").empty(); $("#colorstanding-rated").append(`Ratedのみを表示中`); } else { $("#colorstanding-rated").empty(); $("#colorstanding-rated").append(`Unratedも表示中`); } if (submitmode == 1) { $("#colorstanding-submit").empty(); $("#colorstanding-submit").append(`1回以上提出を表示中`); } else { $("#colorstanding-submit").empty(); $("#colorstanding-submit").append(`提出なしも表示中`); } if (!new_val) { return; } let task = new_val.TaskInfo; let data = new_val.StandingsData; let ratecolor = ["#000000", "#666666", "#663300", "#006600", "#009999", "#0000cc", "#cc9900", "#ff9900", "#ff3333"]; let ratename = ["黒", "灰", "茶", "緑", "水", "青", "黄", "橙", "赤"] let ratelist = [1, 400, 800, 1200, 1600, 2000, 2400, 2800, 9999]; if (detailmode == 1){ ratelist = [1, 33, 100, 200, 300, 400, 500, 600, 700, 800, 900, 1000, 1100, 1200, 1300, 1400, 1500, 1600, 1700, 1800, 1900, 2000, 2100, 2200, 2300, 2400, 2500, 2600, 2700, 2800, 2900, 3000, 3100, 3200, 3300, 3400, 3500, 3600, 9999]; ratename = ["0", "1", "33", "100", "200", "300", "400", "500", "600", "700", "800", "900", "1000", "1100", "1200", "1300", "1400", "1500", "1600", "1700", "1800", "1900", "2000", "2100", "2200", "2300", "2400", "2500", "2600", "2700", "2800", "2900", "3000", "3100", "3200", "3300", "3400", "3500", "金"]; ratecolor = ["#000000", "#666666", "#666666", "#666666", "#666666", "#666666", "#663300", "#663300", "#663300", "#663300", "#006600", "#006600", "#006600", "#006600", "#009999", "#009999", "#009999", "#009999", "#0000cc", "#0000cc", "#0000cc", "#0000cc", "#cc9900", "#cc9900", "#cc9900", "#cc9900", "#ff9900", "#ff9900", "#ff9900", "#ff9900", "#ff3333", "#ff3333", "#ff3333", "#ff3333", "#990000", "#990000", "#990000", "#990000", "#461900"]; } // コンテスト前とコンテスト後ではjsonの挙動が違う let ratingmode = 0; for (let cnt = 0; cnt < data.length; cnt++) { if (data[cnt]["TotalResult"]["Count"] >= 1) { if (data[cnt]["OldRating"] > 0) { ratingmode = 1; break; } } } let nowrating = "Rating"; if (ratingmode == 1) { nowrating = "OldRating" } // 参加者一覧の表を作る let contestant = []; for (let i = 0; i < ratelist.length; i++) { contestant.push([]); } // 参加者カウント for (let cnt = 0; cnt < data.length; cnt++) { for (let color = 0; color < ratelist.length; color++){ if (data[cnt]["IsRated"] == true || ratedmode == 0) { if (data[cnt]["TotalResult"]["Count"] >= 1 || submitmode == 0) { if (data[cnt][nowrating] < ratelist[color]) { contestant[color].push(cnt); break; } } } } } // 配列の用意 var colordata = []; for (let i = 0; i < task.length; i++) { colordata.push([]); for (let j = 0; j < ratelist.length; j++) { colordata[i].push(0); } } var colornum = []; for (let i = 0; i < ratelist.length; i++) { colornum[i] = contestant[i].length; } // 色別の正解数を取得 for (let colors = 0; colors < contestant.length; colors++) { for (let cnt = 0; cnt < task.length; cnt++) { let probid = task[cnt].TaskScreenName; for (let player = 0; player < contestant[colors].length; player++) { try { if (data[contestant[colors][player]]["TaskResults"][probid]["Status"] === 1) { colordata[cnt][colors] += 1; } } catch { null; } } } } // 表の先頭 let t = `<tr style="font-weight: bold;"><td align="center">Rate</td><td align="center">参加者数</td>`; for (let i = 0; i < task.length; i++) { t += `<td align="center">` + task[i].Assignment + `</td>`; } t += `</tr>`; // 表の途中 for (let colors = 0; colors < ratecolor.length; colors++) { t += `<tr><td align="center" style="padding: 2px;"><font color="` + ratecolor[colors] + `"><b>` + ratename[colors] + `</b></td><td align="right">` + colornum[colors] + `</td>`; for (let i = 0; i < task.length; i++) { // 正解率を求める let dat = 0; if (colornum[colors] != 0) { dat = colordata[i][colors] / colornum[colors]; } // 正解率によって背景色を定める let targ = 0; let cr = 0; let cg = 0; let cb = 0; if (dat >= 0.9) { targ = (1-dat)*1000; cr = Math.floor(255-targ); cg = 255; cb = Math.floor(155+targ); } else if (dat >= 0.75) { targ = (0.9-dat)/1.5*1000; cr = 155; cg = 255; cb = Math.floor(255-targ); } else if (dat >= 0.5) { targ = (0.75-dat)/2.5*1000; cr = Math.floor(155+targ); cg = Math.floor(255-targ*0.5); cb = 155; } else if (dat >= 0.25) { targ = (0.5-dat)/2.5*1000; cr = Math.floor(255-targ*0.5); cg = 205; cb = Math.floor(155+targ*0.5); } else if (dat >= 0.05) { targ = (0.25-dat)/2*1000; cr = Math.floor(205-targ*0.5); cg = Math.floor(205-targ*0.5); cb = Math.floor(205-targ*0.5); } else { targ = (0.05-dat)/0.5*1000; cr = Math.floor(155-targ*0.2); cg = Math.floor(155-targ*0.2); cb = Math.floor(155-targ*0.2); } t += `<td align="right" bgcolor="` + rgb2hex( [cr, cg, cb] ) + `">` + (dat*100).toFixed(2) + `%</td>`; } t += `</tr>`; } $("#accs-table > tbody").empty(); $("#accs-table > tbody").append(t); }, { deep: true, immediate: true }); } update(); document.getElementById("colorstanding-detail").addEventListener("click", () => { detailmode = 1 - detailmode update(); }); document.getElementById("colorstanding-rated").addEventListener("click", () => { ratedmode = 1 - ratedmode update(); }); document.getElementById("colorstanding-submit").addEventListener("click", () => { submitmode = 1 - submitmode update(); }); document.getElementById("colorstanding-off").addEventListener("click", () => { $("#accs-table > tbody").empty(); }); });