use rand::prelude::*;
fn main() {
let debug_mode = std::env::args().any(|x| x == "debug".to_string());
let auto = std::env::args().any(|x| x == "auto".to_string());
let mut n: String = "".into();
std::io::stdin().read_line(&mut n).expect("IO Ongelma :(");
let n: usize = n.trim().parse().expect("Eka rivi ei ollut numero");
let mut line: String = "".into();
if !auto {
// **..**..R..** juttu
std::io::stdin()
.read_line(&mut line)
.expect("IO Ongelma :(");
} else {
let mut rng = rand::thread_rng();
for _ in 0..n {
let num = rng.gen_range(0.0..=1.);
if num < 0.3 {
line.push('*');
} else {
line.push('.');
}
}
let half = n / 2;
line.replace_range(half..=half, "R");
}
let mut askeleet = 0;
let mut kolikot = 0;
let mut robotti_pos = pos_of_c(&line, 'R')
.first()
.expect("Ei R:ää (robottia)")
.clone();
let mut kolikko_positions = pos_of_c(&line, '*').clone();
let time = get_timer();
loop {
// Unwrap
let Some(close) = closest(&robotti_pos, &kolikko_positions) else {
break;
};
// Optimisaatio
let diff = close as i32 - robotti_pos as i32;
askeleet += diff.abs();
robotti_pos = (robotti_pos as i32 + diff) as usize;
kolikot += 1;
kolikko_positions.retain(|x| *x != close);
//DEBUG
/*if debug_mode {
for i in 0..n {
if i == robotti_pos {
print!("R");
} else if kolikko_positions.contains(&i) {
print!("*");
} else {
print!(".");
}
}
println!("");
}*/
}
println!("{} {}", askeleet, kolikot);
if debug_mode {
println!("Kesti {}", get_timer() - time);
}
}
// Pakko alkaa mittaamaan ku ei kelvannu mun 0.2 sekuntia
// Kestävä ratkasu
fn get_timer() -> f64 {
std::time::SystemTime::now()
.duration_since(std::time::UNIX_EPOCH)
.expect("Time went backwards")
.as_secs_f64()
}
#[inline(always)]
fn closest(a: &usize, b: &[usize]) -> Option<usize> {
let mut c = usize::MAX;
let mut c_index = 0;
let mut wurst: Option<usize> = None;
if b.is_empty() {
return None;
}
for (i, val) in b.iter().enumerate() {
let diff = dist((*a, *val));
if diff < c {
c = diff;
c_index = i;
wurst = None;
} else if diff == c {
wurst = Some(c);
}
}
// Tyhmä ropotti >:(
if let Some(_) = wurst {
return None;
}
Some(b[c_index])
}
#[inline(always)]
fn dist((a, b): (usize, usize)) -> usize {
a.abs_diff(b)
}
fn pos_of_c(s: &str, c: char) -> Vec<usize> {
// *
let mut pos = vec![];
for (i, char) in s.chars().enumerate() {
if char == c {
pos.push(i);
}
}
pos
}