Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save kenkoooo/38ede2613f4cb748b3453a1963ba617c to your computer and use it in GitHub Desktop.
Save kenkoooo/38ede2613f4cb748b3453a1963ba617c to your computer and use it in GitHub Desktop.
use anyhow::Result;
use reqwest::ClientBuilder;
use serde::Deserialize;
use std::collections::{HashMap, HashSet};
#[tokio::main]
async fn main() -> Result<()> {
let client = ClientBuilder::new().gzip(true).build()?;
let models: HashMap<String, ProblemModel> = client
.get("https://kenkoooo.com/atcoder/resources/problem-models.json")
.send()
.await?
.json()
.await?;
let problems: Vec<Problem> = client
.get("https://kenkoooo.com/atcoder/resources/problems.json")
.send()
.await?
.json()
.await?;
let mut submissions = vec![];
let mut from_second = 0;
loop {
let url = format!(
r"https://kenkoooo.com/atcoder/atcoder-api/v3/user/submissions?user=kenkoooo&from_second={}",
from_second
);
let response: Vec<Submission> = client.get(url).send().await?.json().await?;
if let Some(max) = response.iter().map(|s| s.epoch_second).max() {
from_second = max + 1;
submissions.extend(response);
} else {
break;
}
}
let solved_problem_ids = submissions
.iter()
.filter(|s| &s.result == "AC")
.map(|s| s.problem_id.clone())
.collect::<HashSet<_>>();
let mut unsolved_problems = problems
.into_iter()
.filter(|p| !solved_problem_ids.contains(&p.id))
.flat_map(|problem| {
let difficulty = models.get(&problem.id).and_then(|model| model.difficulty);
difficulty.map(|difficulty| (problem, difficulty))
})
.collect::<Vec<_>>();
unsolved_problems.sort_by_key(|t| t.1);
let yellow = unsolved_problems
.iter()
.filter(|t| 2400 <= t.1 && t.1 < 2800)
.collect::<Vec<_>>();
print_table(&yellow, 20);
Ok(())
}
fn print_table(problems: &[&(Problem, i64)], size: usize) {
for _ in 0..size {
print!("|");
}
println!("|");
for _ in 0..size {
print!("|:-----");
}
println!("|");
for chunk in problems.chunks(size) {
for problem in chunk {
print!(
"|[{} {}](https://atcoder.jp/contests/{}/tasks/{})",
problem.1, problem.0.title, problem.0.contest_id, problem.0.id
);
}
let last = size - chunk.len();
for _ in 0..last {
print!("|");
}
println!("|");
}
}
#[derive(Deserialize)]
struct ProblemModel {
difficulty: Option<i64>,
}
#[derive(Deserialize)]
struct Problem {
id: String,
contest_id: String,
title: String,
}
#[derive(Deserialize)]
struct Submission {
result: String,
problem_id: String,
epoch_second: i64,
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment