Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #![feature(core_intrinsics)]
- use std::fmt;
- use std::io::{self, Write};
- use std::intrinsics::likely;
- const WINDOW_SIZE: usize = 10;
- const UPPER_BOUND: usize = 10;
- struct FloatingWindow {
- data: [usize; WINDOW_SIZE],
- start_index: usize,
- current_size: usize,
- curr_sum: usize,
- counter: [usize; UPPER_BOUND]
- }
- impl FloatingWindow {
- pub fn new() -> Self {
- Self {
- start_index: 0,
- current_size: 0,
- data: [0; WINDOW_SIZE],
- curr_sum: 0,
- counter: [0; UPPER_BOUND],
- }
- }
- pub fn at(&self, idx: usize) -> usize {
- self.data[(self.start_index + idx) % WINDOW_SIZE]
- }
- pub fn push(&mut self, value: usize) {
- let old_value = self.at(self.current_size);
- self.curr_sum -= old_value;
- self.curr_sum += value;
- unsafe {
- if likely(self.counter[old_value] != 0) {
- self.counter[old_value] -= 1;
- }
- }
- self.counter[value] += 1;
- self.data[(self.start_index + self.current_size) % WINDOW_SIZE] = value;
- if self.current_size < WINDOW_SIZE {
- self.current_size += 1;
- } else {
- self.start_index += 1;
- }
- }
- pub fn sum(&self) -> usize {
- return self.curr_sum;
- }
- pub fn avg(&self) -> Option<usize> {
- if self.current_size != 0 {
- Some(self.curr_sum / (self.current_size))
- } else {
- None
- }
- }
- pub fn most_common(&self) -> usize {
- let mut num = 0;
- for (idx, &value) in self.counter.iter().enumerate() {
- if value > self.counter[num] {
- num = idx;
- }
- }
- num
- }
- }
- impl fmt::Debug for FloatingWindow {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- write!(
- f,
- "FloatingWindow {{ {:?}, sum: {:?}, avg: {:?}, most_common: {:?} }}",
- self.into_iter().collect::<Vec<usize>>(),
- self.sum(),
- self.avg(),
- self.most_common()
- )
- }
- }
- struct FloatingWindowIterator<'a> {
- window: &'a FloatingWindow,
- curr_index: usize,
- }
- impl<'a> IntoIterator for &'a FloatingWindow {
- type Item = usize;
- type IntoIter = FloatingWindowIterator<'a>;
- fn into_iter(self) -> Self::IntoIter {
- FloatingWindowIterator::new(self)
- }
- }
- impl<'a> FloatingWindowIterator<'a> {
- pub fn new(window: &'a FloatingWindow) -> Self {
- Self {
- window,
- curr_index: 0,
- }
- }
- }
- impl<'a> Iterator for FloatingWindowIterator<'a> {
- type Item = usize;
- fn next(&mut self) -> Option<Self::Item> {
- if self.curr_index < self.window.current_size {
- self.curr_index += 1;
- Some(self.window.at(self.curr_index - 1))
- } else {
- None
- }
- }
- }
- fn main() {
- let stdin = io::stdin();
- let mut stdout = io::stdout();
- let mut user_input = String::new();
- let mut window = FloatingWindow::new();
- loop {
- print!("> ");
- stdout.flush().expect("I/O error");
- user_input.truncate(0);
- stdin.read_line(&mut user_input).expect("I/O error");
- if user_input == "" || user_input == "q\n" {
- break;
- }
- user_input = user_input.trim().to_string();
- if user_input == "" {
- continue;
- }
- if user_input == "p" {
- println!("{:?}", window);
- } else {
- match user_input.parse() {
- Ok(num) => {
- if num >= UPPER_BOUND {
- eprintln!("num must be less than {}", UPPER_BOUND);
- } else {
- window.push(num);
- }
- }
- Err(err) => eprintln!("Error parsing number: {}", err),
- }
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement