From 4e299db3c02774620a2041a5a1c4a72dce39887e Mon Sep 17 00:00:00 2001 From: Jan-Peter von Hunnius Date: Thu, 29 May 2025 10:47:05 +0200 Subject: [PATCH] Corrected handling of tied times --- src/records.rs | 109 ++++++++++++++++++++++++++++++++----------------- 1 file changed, 72 insertions(+), 37 deletions(-) diff --git a/src/records.rs b/src/records.rs index 5f1ed90..6b8e4eb 100644 --- a/src/records.rs +++ b/src/records.rs @@ -1,14 +1,19 @@ -use futures::future::join_all; -use once_cell::sync::Lazy; -use reqwest::get; -use serde_json::Value; use std::collections::HashMap; use std::env; use std::fs; use std::sync::Mutex; + use tokio::sync::Semaphore; use tokio::task; +use futures::future::join_all; + +use once_cell::sync::Lazy; + +use reqwest::get; + +use serde_json::Value; + #[derive(Debug, Clone)] struct Car { rid: String, @@ -28,7 +33,7 @@ struct BestCarRecord { time: f64, } type TripletKey = (String, u8, String); // (Track ID, RQ, Surface) -static BEST_CARS: Lazy>> = +static BEST_CARS: Lazy>>> = Lazy::new(|| Mutex::new(HashMap::new())); #[tokio::main] @@ -81,19 +86,22 @@ fn print_best_times() { sorted_keys.sort_by(|a, b| a.1.cmp(&b.1).then(a.0.cmp(&b.0))); // Sort by RQ, then Track ID for key in sorted_keys { - let best_car = best_cars.get(key).unwrap(); - println!( - "{},{},{},{},{},{},{},{},{}", - key.1, - key.0, - key.2, - best_car.rq, - best_car.brand, - best_car.only_name, - best_car.year, - best_car.config, - best_car.time - ); + if let Some(records) = best_cars.get(key) { + for best_car in records { + println!( + "{},{},{},{},{},{},{},{},{}", + key.1, + key.0, + key.2, + best_car.rq, + best_car.brand, + best_car.only_name, + best_car.year, + best_car.config, + best_car.time + ); + } + } } } fn print_best_cars() { @@ -101,16 +109,18 @@ fn print_best_cars() { let mut car_count: HashMap = HashMap::new(); // Count occurrences and store RQ - for (_key, best_car) in best_cars.iter() { - let entry = car_count - .entry(best_car.car_rid.clone()) - .or_insert((best_car.clone(), 0)); - entry.1 += 1; + for (_key, best_list) in best_cars.iter() { + for best_car in best_list { + let entry = car_count + .entry(best_car.car_rid.clone()) + .or_insert((best_car.clone(), 0)); + entry.1 += 1; + } } // Convert to vector and sort by RQ first, then name let mut car_count_vec: Vec<_> = car_count.iter().collect(); - car_count_vec.sort_by(|a, b| a.1.0.rq.cmp(&b.1.0.rq).then(a.0.cmp(&b.0))); + car_count_vec.sort_by(|a, b| a.1 .0.rq.cmp(&b.1 .0.rq).then(a.0.cmp(&b.0))); for (_car_rid, (car_record, count)) in car_count_vec { println!( @@ -121,14 +131,25 @@ fn print_best_cars() { } fn print_best_car(track: &String, condition: &String, rq: &String) { let best_cars = BEST_CARS.lock().unwrap(); - let key = (track.clone(), rq.parse::().unwrap_or(115), condition.clone()); + let key = ( + track.clone(), + rq.parse::().unwrap_or(115), + condition.clone(), + ); - if let Some(best_car) = best_cars.get(&key) { - println!( - "Best car for Track: {}, Condition: {}, RQ: {} -> {} {} ({}) with time {:.2}", - track, condition, rq, - best_car.brand, best_car.only_name, best_car.year, best_car.time - ); + if let Some(best_list) = best_cars.get(&key) { + for best_car in best_list { + println!( + "Best car for Track: {}, Condition: {}, RQ: {} -> {} {} ({}) with time {:.2}", + track, + condition, + rq, + best_car.brand, + best_car.only_name, + best_car.year, + best_car.time + ); + } } else { println!( "No best car found for Track: {}, Condition: {}, RQ: {}", @@ -192,15 +213,29 @@ async fn parse_car_times(car: Car) { fn update_best_car(track_id: &str, car_rq: u8, surface: &str, new_record: BestCarRecord) { let mut best_cars = BEST_CARS.lock().unwrap(); - for rq in car_rq..116 { + for rq in car_rq..=115 { let key = (track_id.to_string(), rq, surface.to_string()); - if let Some(existing) = best_cars.get(&key) { - if new_record.time < existing.time { - best_cars.insert(key, new_record.clone()); + match best_cars.get_mut(&key) { + Some(existing_list) => { + let best_time = existing_list.first().map(|r| r.time).unwrap_or(f64::MAX); + + if new_record.time < best_time { + // Found better time → replace list + *existing_list = vec![new_record.clone()]; + } else if (new_record.time - best_time).abs() < f64::EPSILON { + // Tie → add only if not already in the list + if !existing_list + .iter() + .any(|r| r.car_rid == new_record.car_rid) + { + existing_list.push(new_record.clone()); + } + } + } + None => { + best_cars.insert(key, vec![new_record.clone()]); } - } else { - best_cars.insert(key, new_record.clone()); } } }