Skip to content

Instantly share code, notes, and snippets.

@tomerun
Last active March 16, 2017 03:36
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tomerun/6be64900c4d20952438dd86223950ea4 to your computer and use it in GitHub Desktop.
Save tomerun/6be64900c4d20952438dd86223950ea4 to your computer and use it in GitHub Desktop.

RCO Presents 日本橋ハーフマラソン順位表用ユーザースクリプト

  • これは 日本橋ハーフマラソン のAtCoder順位表をカスタマイズして表示するためのユーザースクリプトです。予選・オープンコンテストの順位表でも利用できます。
  • Google Chrome, Mozilla Firefox, Microsoft Edgeの各最新版で動作確認をしています。

インストール方法

  1. ブラウザに Tampermonkey もしくは Greasemonkey (Firefoxのみ) をインストールします。
  2. 下記のリンクをクリックし、ユーザースクリプトをインストールします。
    https://gist.github.com/tomerun/6be64900c4d20952438dd86223950ea4/raw/rcocon2017.user.js

使用方法

  1. 順位表ページを表示すると、順位表の文字の下に「RCO Presents 日本橋ハーフマラソンの順位にする」というチェックボックスが表示されます。
  2. チェックボックスをONにすると、日本橋ハーフマラソンの順位付けに従って付けられた順位が表示されるようになります。

更新履歴

  • v0.2 (2017.03.16)
    • 日本橋ハーフマラソンのページでのみユーザースクリプトが動作するよう修正
    • 名前欄に国旗とカラーを表示
  • v0.1 (2017.02.24)
    • 初公開
// ==UserScript==
// @name AtCoder Standings for RCO Contest 2017
// @namespace http://tampermonkey.net/
// @version 0.2
// @description Provide standings for Nihonbashi Half Marathon
// @author Recruit Communications Co., Ltd.
// @include *://rco-contest-2017-qual.contest.atcoder.jp/standings*
// @include *://rco-contest-2017-final.contest.atcoder.jp/standings*
// @include *://rco-contest-2017-final-open.contest.atcoder.jp/standings*
// @grant none
// ==/UserScript==
(function() {
'use strict';
// 各問題の順位からスコアを計算して表示
var rcoMode = function() {
// 元の順位表をクリア
$('tbody tr').remove();
$('div#pagination-standings').remove();
var data = ATCODER.standings.data;
var sorted = new Array(data[0].tasks.length);
for(var i = 0; i < sorted.length; i++) {
sorted[i] = data.map((d) => d.tasks[i].score || 0).sort((a, b) => b - a);
data.forEach((d) => d.tasks[i].rank = sorted[i].indexOf(d.tasks[i].score || 0) + 1);
}
data.forEach(function(d) {
d.score = d.tasks.map((e) => e.rank).reduce((a, b) => a + b, 0);
d.sub_score = Math.min.apply(null, d.tasks.map((e) => e.rank));
});
var sorted_overall_score = data.map((d) => [d.score, d.sub_score])
.sort((a, b) => a[0] - b[0] || a[1] - b[1]).map((d) => d.join());
data.forEach((d) => d.rank = sorted_overall_score.indexOf([d.score, d.sub_score].join()) + 1);
// 順位・総合得点順のときだけソート
var query = location.search.replace('order_by=total', '').replace('?', '').replace('&', '');
if (query === '') {
data.sort((a, b) => a.rank - b.rank);
} else if (query === 'rev=true') {
data.sort((a, b) => b.rank - a.rank);
}
data.forEach(addLine);
// 自分のところまでスクロール
if ($('tr.standings-me').offset()) {
$("html, body").animate({ scrollTop: $('tr.standings-me').offset().top - 200 }, 200);
}
$('.tooltip-label').tooltip({placement:'top'});
};
var scoreTime = function(d){
if (d.score) {
return d.score/100 + ' / ' + Math.floor(d.elapsed_time/60) + ':' + ('0'+d.elapsed_time%60).slice(-2);
} else {
return '-';
}
};
// 順位表に行を追加
var addLine = function(d){
var name = d.user_screen_name;
var line = '<td class="standings-rank">'+d.rank+'</td><td class="standings-username">';
line += '<img src="/img/flag/'+d.country+'.png" style="vertical-align: middle;"> ';
line += '<a class="username '+ getRatingClass(d.competitions, d.rating) +'" href="https://atcoder.jp/user/' + encodeURIComponent(name) + '">'+name+'</a>';
line += '<a href="/submissions/all?user_screen_name=' + encodeURIComponent(name) + '">';
line += ' <i class="icon-search tooltip-label" rel="tooltip" data-title="View ' + escapeAttrValue(name) + '\'s submissions' + '" data-original-title=""></i>';
line += '</a></td>';
line += d.tasks.map((t) => '<td class="center"><p><span class="standings-ac">'+ t.rank +'</span><br>'+ scoreTime(t) +'</p></td>').join('');
line += '<td class="center"><p><span class="standings-score">'+d.score+'</span></p></td>';
var myid = $.cookie('_user_id');
if (myid == d.user_id) {
$('tbody').append('<tr class="standings-me">'+line+'</tr>');
} else {
$('tbody').append('<tr>'+line+'</tr>');
}
};
var escapeAttrValue = function(str) {
return str
.replace(/&/g, '&amp;')
.replace(/</g, '&lt;')
.replace(/>/g, '&gt;')
.replace(/"/g, '&quot;')
.replace(/'/g, '&#39;');
};
var getRatingClass = function(competitions, rating){
if(typeof competitions === "undefined" || typeof rating === "undefined") { return ""; }
if(competitions === 0) { return "user-unrated"; }
var rating_table = [
{"rating": 400, "name": "user-gray"},
{"rating": 800, "name": "user-brown"},
{"rating": 1200, "name": "user-green"},
{"rating": 1600, "name": "user-cyan"},
{"rating": 2000, "name": "user-blue"},
{"rating": 2400, "name": "user-yellow"},
{"rating": 2800, "name": "user-orange"}
];
for(var i = 0 ; i < rating_table.length ; i++) {
if(rating < rating_table[i].rating) { return rating_table[i].name; }
}
return "user-red";
};
$('h2').after('<input type="checkbox" id="rcocon-mode"> RCO Presents 日本橋ハーフマラソンの順位にする');
$('#rcocon-mode').change(function(){
if ($('#rcocon-mode').is(':checked')) {
$.cookie("rcocon-mode", "true");
rcoMode();
} else {
// Cookieを消してリロード
$.cookie("rcocon-mode", null);
location.href = "/standings";
}
});
if ($.cookie("rcocon-mode")) {
$('#rcocon-mode').prop('checked', true);
rcoMode();
}
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment