Calculate scores, make a table, print the board
This commit is contained in:
parent
e37add37df
commit
683d7ef7a3
|
@ -6,7 +6,7 @@ const INPUT_DATA: &str = include_str!("../680754.json");
|
||||||
const TEAMS: &str = include_str!("../teams.yaml");
|
const TEAMS: &str = include_str!("../teams.yaml");
|
||||||
|
|
||||||
#[derive(Clone, Debug, Deserialize)]
|
#[derive(Clone, Debug, Deserialize)]
|
||||||
struct Board {
|
struct Leaderboard {
|
||||||
members: HashMap<String, Member>,
|
members: HashMap<String, Member>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -23,7 +23,64 @@ struct Team {
|
||||||
members: Vec<String>,
|
members: Vec<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn request_board(session_token: &str, year: &str, board_id: &str) -> Board {
|
#[derive(Clone, Debug)]
|
||||||
|
struct Scoreboard(HashMap<String, Score>);
|
||||||
|
|
||||||
|
impl Scoreboard {
|
||||||
|
fn table(&self) -> Table {
|
||||||
|
let mut table = Vec::new();
|
||||||
|
|
||||||
|
let team_names = self.0.keys().cloned().collect::<Vec<String>>();
|
||||||
|
|
||||||
|
{
|
||||||
|
let row = vec!["".to_owned()];
|
||||||
|
let row = row
|
||||||
|
.into_iter()
|
||||||
|
.chain(team_names.clone())
|
||||||
|
.collect::<Vec<String>>();
|
||||||
|
table.push(row);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
let mut row = vec!["Score".to_owned()];
|
||||||
|
for name in team_names.clone() {
|
||||||
|
let score = self.0.get(&name).unwrap();
|
||||||
|
row.push(format!("{}", score.total_score));
|
||||||
|
}
|
||||||
|
table.push(row);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
let mut row = vec!["Stars".to_owned()];
|
||||||
|
for name in team_names.clone() {
|
||||||
|
let score = self.0.get(&name).unwrap();
|
||||||
|
row.push(format!("{}", score.total_stars));
|
||||||
|
}
|
||||||
|
table.push(row);
|
||||||
|
}
|
||||||
|
|
||||||
|
Table::from(table)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug)]
|
||||||
|
struct Score {
|
||||||
|
total_stars: u32,
|
||||||
|
total_score: u32,
|
||||||
|
members: Vec<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for Score {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
total_stars: 0,
|
||||||
|
total_score: 0,
|
||||||
|
members: vec![],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn request_board(session_token: &str, year: &str, board_id: &str) -> Leaderboard {
|
||||||
let jar = reqwest::cookie::Jar::default();
|
let jar = reqwest::cookie::Jar::default();
|
||||||
let url = "https://adventofcode.com/".parse::<reqwest::Url>().unwrap();
|
let url = "https://adventofcode.com/".parse::<reqwest::Url>().unwrap();
|
||||||
jar.add_cookie_str(&format!("session={}", session_token), &url);
|
jar.add_cookie_str(&format!("session={}", session_token), &url);
|
||||||
|
@ -47,8 +104,76 @@ async fn request_board(session_token: &str, year: &str, board_id: &str) -> Board
|
||||||
.unwrap()
|
.unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn score(teams: Vec<Team>, leaderboard: Leaderboard) -> Scoreboard {
|
||||||
|
let mut scores = HashMap::new();
|
||||||
|
|
||||||
|
for team in teams {
|
||||||
|
let score = leaderboard
|
||||||
|
.members
|
||||||
|
.values()
|
||||||
|
.fold(Score::default(), |score, member| {
|
||||||
|
if team.members.contains(&member.name) {
|
||||||
|
let mut members = score.members.clone();
|
||||||
|
members.push(member.name.clone());
|
||||||
|
Score {
|
||||||
|
total_stars: score.total_stars + member.stars,
|
||||||
|
total_score: score.total_score + member.local_score,
|
||||||
|
members,
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
score
|
||||||
|
}
|
||||||
|
});
|
||||||
|
scores.insert(team.name.clone(), score);
|
||||||
|
}
|
||||||
|
|
||||||
|
Scoreboard(scores)
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Table {
|
||||||
|
table: Vec<Vec<String>>,
|
||||||
|
column_sizes: Vec<usize>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<Vec<Vec<String>>> for Table {
|
||||||
|
fn from(lst: Vec<Vec<String>>) -> Table {
|
||||||
|
let column_sizes = (0..lst[0].len())
|
||||||
|
.map(|idx| {
|
||||||
|
lst.iter()
|
||||||
|
.fold(0, |cur, r| std::cmp::max(cur, r[idx].len()))
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
Table {
|
||||||
|
table: lst,
|
||||||
|
column_sizes,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Table {
|
||||||
|
fn print(&self) {
|
||||||
|
for row in self.table.iter() {
|
||||||
|
for (width, field) in self.column_sizes.iter().zip(row.iter()) {
|
||||||
|
let val = pad(field.clone(), *width);
|
||||||
|
print!("| {} ", val);
|
||||||
|
}
|
||||||
|
println!("|");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn pad(mut val: String, size: usize) -> String {
|
||||||
|
while val.len() < size {
|
||||||
|
val.push(' ');
|
||||||
|
}
|
||||||
|
val
|
||||||
|
}
|
||||||
|
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
async fn main() {
|
async fn main() {
|
||||||
|
let teams: Vec<Team> = serde_yaml::from_str(TEAMS).unwrap();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
let session_token = std::env::vars()
|
let session_token = std::env::vars()
|
||||||
.find_map(|(key, value)| {
|
.find_map(|(key, value)| {
|
||||||
|
@ -63,8 +188,7 @@ async fn main() {
|
||||||
let board = request_board(&session_token, "2022", "680754");
|
let board = request_board(&session_token, "2022", "680754");
|
||||||
*/
|
*/
|
||||||
|
|
||||||
let teams: Vec<Team> = serde_yaml::from_str(TEAMS).unwrap();
|
let board: Leaderboard = serde_json::from_str(INPUT_DATA).unwrap();
|
||||||
let board: Board = serde_json::from_str(INPUT_DATA).unwrap();
|
let scoreboard = score(teams, board);
|
||||||
println!("resulting text: {:?}", teams);
|
scoreboard.table().print();
|
||||||
println!("resulting text: {:?}", board);
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue