1use std::cell::RefCell;
7use std::fmt::Display;
8use std::io::{self, BufRead, BufWriter, Write};
9
10#[doc(hidden)]
17pub struct Scanner<R: BufRead> {
18 reader: R,
19 buffer: String,
20 cursor: usize,
21}
22
23impl<R: BufRead> Scanner<R> {
24 pub fn new(reader: R) -> Self {
38 Self {
39 reader,
40 buffer: String::new(),
41 cursor: 0,
42 }
43 }
44
45 pub fn with_reader(reader: R) -> Self {
49 Self::new(reader)
50 }
51
52 pub fn token<T: std::str::FromStr>(&mut self) -> T {
57 loop {
58 let bytes = self.buffer.as_bytes();
59 while self.cursor < bytes.len() && bytes[self.cursor].is_ascii_whitespace() {
60 self.cursor += 1;
61 }
62 let start = self.cursor;
63 while self.cursor < bytes.len() && !bytes[self.cursor].is_ascii_whitespace() {
64 self.cursor += 1;
65 }
66 if start < self.cursor {
67 return self.buffer[start..self.cursor]
68 .parse()
69 .ok()
70 .expect("failed to parse token");
71 }
72 self.buffer.clear();
73 self.cursor = 0;
74 let read = self
75 .reader
76 .read_line(&mut self.buffer)
77 .expect("failed to read input");
78 assert!(read > 0, "input exhausted");
79 }
80 }
81}
82
83thread_local! {
84 #[doc(hidden)]
85 pub static SCANNER: RefCell<Scanner<io::BufReader<io::Stdin>>> =
86 RefCell::new(Scanner::new(io::BufReader::new(io::stdin())));
87
88 #[doc(hidden)]
89 pub static WRITER: RefCell<BufWriter<io::Stdout>> =
90 RefCell::new(BufWriter::new(io::stdout()));
91}
92
93#[doc(hidden)]
102#[macro_export]
103macro_rules! read_value {
104 ($scanner:expr, ($($ty:tt),*)) => {
105 ($( $crate::read_value!($scanner, $ty) ),*)
106 };
107 ($scanner:expr, [$ty:tt; $len:expr]) => {
108 (0..$len)
109 .map(|_| $crate::read_value!($scanner, $ty))
110 .collect::<Vec<_>>()
111 };
112 ($scanner:expr, chars) => {
113 $scanner.token::<String>().chars().collect::<Vec<char>>()
114 };
115 ($scanner:expr, usize1) => {
116 $scanner.token::<usize>() - 1
117 };
118 ($scanner:expr, isize1) => {
119 $scanner.token::<isize>() - 1
120 };
121 ($scanner:expr, $ty:ty) => {
122 $scanner.token::<$ty>()
123 };
124}
125
126#[macro_export]
140macro_rules! input {
141 ($(,)?) => {};
142 (mut $($var:ident),+ : $ty:tt $(, $($rest:tt)*)?) => {
143 $(
144 let mut $var = $crate::io::SCANNER.with(|scanner| {
145 let mut scanner = scanner.borrow_mut();
146 $crate::read_value!(&mut *scanner, $ty)
147 });
148 )+
149 $($crate::input!($($rest)*);)?
150 };
151 ($($var:ident),+ : $ty:tt $(, $($rest:tt)*)?) => {
152 $(
153 let $var = $crate::io::SCANNER.with(|scanner| {
154 let mut scanner = scanner.borrow_mut();
155 $crate::read_value!(&mut *scanner, $ty)
156 });
157 )+
158 $($crate::input!($($rest)*);)?
159 };
160}
161
162#[macro_export]
167macro_rules! wprint {
168 ($($argument:tt)*) => {
169 $crate::io::WRITER.with(|writer| {
170 std::io::Write::write_fmt(
171 &mut *writer.borrow_mut(),
172 format_args!($($argument)*),
173 )
174 .unwrap()
175 })
176 };
177}
178
179#[macro_export]
184macro_rules! wprintln {
185 () => {
186 $crate::wprint!("\n")
187 };
188 ($($argument:tt)*) => {
189 $crate::wprint!("{}\n", format_args!($($argument)*))
190 };
191}
192
193pub fn wflush() {
198 WRITER.with(|writer| writer.borrow_mut().flush().unwrap());
199}
200
201pub struct Writer<W: Write> {
206 writer: BufWriter<W>,
207}
208
209impl<W: Write> Writer<W> {
210 pub fn with_writer(writer: W) -> Self {
215 Self {
216 writer: BufWriter::new(writer),
217 }
218 }
219
220 pub fn print(&mut self, value: impl Display) {
224 write!(self.writer, "{value}").unwrap();
225 }
226
227 pub fn println(&mut self, value: impl Display) {
231 writeln!(self.writer, "{value}").unwrap();
232 }
233
234 pub fn print_yes_no(&mut self, condition: bool) {
236 self.println(if condition { "Yes" } else { "No" });
237 }
238
239 pub fn print_yes(&mut self) {
241 self.print_yes_no(true);
242 }
243
244 pub fn print_no(&mut self) {
246 self.print_yes_no(false);
247 }
248
249 pub fn join<T: Display>(&mut self, values: impl IntoIterator<Item = T>, separator: &str) {
254 let mut values = values.into_iter();
255 if let Some(first) = values.next() {
256 self.print(first);
257 for value in values {
258 self.print(separator);
259 self.print(value);
260 }
261 }
262 self.println("");
263 }
264
265 pub fn join_nospace<T: Display>(&mut self, values: impl IntoIterator<Item = T>) {
267 self.join(values, "");
268 }
269
270 pub fn join_whitespace<T: Display>(&mut self, values: impl IntoIterator<Item = T>) {
272 self.join(values, " ");
273 }
274
275 pub fn join_line<T: Display>(&mut self, values: impl IntoIterator<Item = T>) {
277 self.join(values, "\n");
278 }
279
280 pub fn flush(&mut self) {
284 self.writer.flush().unwrap();
285 }
286}
287
288impl Writer<io::StdoutLock<'static>> {
289 pub fn new() -> Self {
293 Self::with_writer(io::stdout().lock())
294 }
295}
296
297impl Default for Writer<io::StdoutLock<'static>> {
298 fn default() -> Self {
299 Self::new()
300 }
301}
302
303impl<W: Write> Drop for Writer<W> {
304 fn drop(&mut self) {
305 self.flush();
306 }
307}
308
309#[cfg(test)]
310mod tests {
311 use super::{Scanner, Writer};
312
313 #[test]
314 fn scans_supported_values() {
315 let mut scanner = Scanner::new("3 hello\n".as_bytes());
316 assert_eq!(scanner.token::<usize>(), 3);
317 assert_eq!(scanner.token::<String>(), "hello");
318 }
319
320 #[test]
321 fn writes_joined_values() {
322 let mut output = Vec::new();
323 {
324 let mut writer = Writer::with_writer(&mut output);
325 writer.join_whitespace([1, 2, 3]);
326 }
327 assert_eq!(output, b"1 2 3\n");
328 }
329}