use std::io::{self, BufRead, BufReader};
pub struct Scanner<R> {
reader: R,
buffer: Vec<String>,
}
impl<R: BufRead> Scanner<R> {
pub fn new(reader: R) -> Self {
Self {
reader,
buffer: Vec::new(),
}
}
pub fn token<T: std::str::FromStr>(&mut self) -> T {
loop {
if let Some(token) = self.buffer.pop() {
return token.parse().ok().expect("Failed to parse token");
}
let mut line = String::new();
self.reader
.read_line(&mut line)
.expect("Failed to read line");
self.buffer = line
.split_whitespace()
.rev()
.map(String::from)
.collect();
}
}
pub fn vec<T: std::str::FromStr>(&mut self, n: usize) -> Vec<T> {
(0..n).map(|_| self.token()).collect()
}
pub fn matrix<T: std::str::FromStr>(&mut self, rows: usize, cols: usize) -> Vec<Vec<T>> {
(0..rows).map(|_| self.vec(cols)).collect()
}
pub fn chars(&mut self) -> Vec<char> {
self.token::<String>().chars().collect()
}
pub fn string(&mut self) -> String {
self.token::<String>()
}
pub fn read_line(&mut self) -> String {
self.buffer.clear();
let mut line = String::new();
self.reader.read_line(&mut line).expect("Failed to read line");
line.trim_end().to_string()
}
pub fn read_lines(&mut self, n: usize) -> Vec<String> {
(0..n).map(|_| self.read_line()).collect()
}
pub fn graph(&mut self, n: usize, m: usize, directed: bool) -> Vec<Vec<usize>> {
let mut adj = vec![vec![]; n + 1];
for _ in 0..m {
let u: usize = self.token();
let v: usize = self.token();
adj[u].push(v);
if !directed {
adj[v].push(u);
}
}
adj
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_token_parsing() {
let input = "42 3.14 hello";
let mut scanner = Scanner::new(input.as_bytes());
let number: i32 = scanner.token();
let float: f64 = scanner.token();
let text: String = scanner.token();
assert_eq!(number, 42);
assert_eq!(float, 3.14);
assert_eq!(text, "hello");
}
#[test]
fn test_vec() {
let input = "1 2 3 4 5";
let mut scanner = Scanner::new(input.as_bytes());
let numbers: Vec<i32> = scanner.vec(5);
assert_eq!(numbers, vec![1, 2, 3, 4, 5]);
}
#[test]
fn test_matrix() {
let input = "1 2 3\n4 5 6";
let mut scanner = Scanner::new(input.as_bytes());
let matrix: Vec<Vec<i32>> = scanner.matrix(2, 3);
assert_eq!(matrix, vec![vec![1, 2, 3], vec![4, 5, 6]]);
}
#[test]
fn test_chars() {
let input = "hello";
let mut scanner = Scanner::new(input.as_bytes());
let chars: Vec<char> = scanner.chars();
assert_eq!(chars, vec!['h', 'e', 'l', 'l', 'o']);
}
#[test]
fn test_string() {
let input = "hello world";
let mut scanner = Scanner::new(input.as_bytes());
let word1: String = scanner.string();
let word2: String = scanner.string();
assert_eq!(word1, "hello");
assert_eq!(word2, "world");
}
#[test]
fn test_undirected_graph() {
let input = "1 2\n2 3\n1 3";
let mut scanner = Scanner::new(input.as_bytes());
let graph = scanner.graph(3, 3, false);
assert_eq!(graph[1], vec![2, 3]);
assert_eq!(graph[2], vec![1, 3]);
assert_eq!(graph[3], vec![2, 1]);
}
#[test]
fn test_directed_graph() {
let input = "1 2\n2 3";
let mut scanner = Scanner::new(input.as_bytes());
let graph = scanner.graph(3, 2, true);
assert_eq!(graph[1], vec![2]);
assert_eq!(graph[2], vec![3]);
assert_eq!(graph[3], vec![]);
}
#[test]
fn test_read_line() {
let input = "first line\nsecond line\n";
let mut scanner = Scanner::new(input.as_bytes());
assert_eq!(scanner.read_line(), "first line");
assert_eq!(scanner.read_line(), "second line");
}
#[test]
fn test_read_lines() {
let input = "one\ntwo\nthree\n";
let mut scanner = Scanner::new(input.as_bytes());
let lines = scanner.read_lines(3);
assert_eq!(lines, vec!["one", "two", "three"]);
}
}