Javaが遅いって お前それPetrの前でも同じ事言えんの?

うっかり「Javaは遅いので競技プログラミングには向いていない」みたいなことを言ってしまう人が稀にいますが、世界最強の一角であるところのPetrさんはJavaで問題を解きまくっているわけです。

       _,,;' '" '' ゛''" ゛' ';;,,
      (rヽ,;''"""''゛゛゛'';, ノr)   Javaが遅いって
      ,;'゛ i _  、_ iヽ゛';,    お前それPetrの前でも同じ事言えんの?
      ,;'" ''| ヽ・〉 〈・ノ |゙゛ `';,
      ,;'' "|   ▼   |゙゛ `';,
      ,;''  ヽ_人_ /  ,;'_
     /シ、  ヽ⌒⌒ /   リ \
    |   "r,, `"'''゙´  ,,ミ゛   |
    |      リ、    ,リ    |
    |   i   ゛r、ノ,,r" i   _|
    |   `ー――----┴ ⌒´ )
    (ヽ  ______ ,, _´)
     (_⌒ ______ ,, ィ
      丁           |
       |           |

ところで「自分の好きな言語は競技プログラミングには向いていないかもしれない…」という不安に駆られた時、誰を思い浮かべればよいのでしょうか?Javaの時はPetrを思い浮かべればいいとして、その他の言語の場合は?

あるユーザーがAtCoderで最も多くの問題をACしている言語を、そのユーザーのメイン言語とします。メイン言語ごとにユーザーをグループ分けして、グループ内でMax Ratingが最高のユーザーを抽出しました。

言語 ユーザー Max Rating
C sheyasutaka 2686
C# chokudai 3056
C++ tourist 4208
Crystal tomerun 2884
D hos_lyric 3135
Haskell tos 2544
Java Petr 3882
Nim chaemon 2231
Perl x20 2028
PyPy Tallfall 2107
Python maspy 2587
Ruby betrue12 2553
Rust ichyo 2528

いかがでしたか?C++が遅いと感じた時はtouristさんに相談すると良さそうですね!

コード

use scraper::{Html, Selector};
use serde::Deserialize;
use std::collections::BTreeMap;

#[derive(Deserialize)]
struct LanguageEntry {
    user_id: String,
    language: String,
    count: usize,
}

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let client = reqwest::ClientBuilder::new().gzip(true).build().unwrap();

    let lang: Vec<LanguageEntry> = client
        .get("https://kenkoooo.com/atcoder/resources/lang.json")
        .send()
        .await?
        .json()
        .await?;

    let mut map = BTreeMap::new();
    for e in lang.into_iter() {
        let cur = map.entry(e.user_id).or_insert_with(|| (String::new(), 0));
        if cur.1 < e.count {
            *cur = (e.language, e.count);
        }
    }

    let mut language2user = BTreeMap::new();

    let table_selector = Selector::parse("div.table-responsive").unwrap();
    let tbody_selector = Selector::parse("tbody").unwrap();
    let span_selector = Selector::parse("span").unwrap();
    let tr_selector = Selector::parse("tr").unwrap();

    for i in 0..10 {
        let html = client
            .get(&format!("https://atcoder.jp/ranking?page={}", i + 1))
            .send()
            .await?
            .text()
            .await?;
        let document = Html::parse_document(&html);
        let table = document.select(&table_selector).next().unwrap();
        let tbody = table.select(&tbody_selector).next().unwrap();

        for tr in tbody.select(&tr_selector) {
            let tds = tr
                .select(&Selector::parse("td").unwrap())
                .collect::<Vec<_>>();
            let user_id = tds[1]
                .select(&span_selector)
                .next()
                .unwrap()
                .text()
                .next()
                .unwrap();
            let max_rating: u32 = tds[4].text().next().unwrap().parse().unwrap();

            if let Some(e) = map.get(user_id) {
                if !language2user.contains_key(&e.0) {
                    language2user.insert(e.0.clone(), (user_id.to_string(), max_rating));
                }
            }
        }
    }

    for (language, (user_id, max_rating)) in language2user.into_iter() {
        println!("|{}|{}|{}|", language, user_id, max_rating);
    }

    Ok(())
}