1#![allow(dead_code)]
10use std::io::{self, Read, Stdin};
11use std::fs::File;
12
13pub struct InputReader<R: Read> {
14 reader: R,
15 buf: Vec<u8>,
16 bytes_read: usize,
17 current_index: usize,
18}
19
20impl InputReader<Stdin> {
21 pub fn new() -> Self {
22 Self::from_reader(io::stdin())
23 }
24}
25
26impl InputReader<File> {
27 pub fn from_file(path: &str) -> Self {
28 Self::from_reader(File::open(path).unwrap())
29 }
30}
31
32impl<R: Read> InputReader<R> {
33 pub fn from_reader(reader: R) -> Self {
34 Self {
35 reader,
36 buf: vec![0; 1 << 16],
37 bytes_read: 0,
38 current_index: 0,
39 }
40 }
41
42 pub fn next<T: InputReadable>(&mut self) -> T {
43 T::from_input(self)
44 }
45
46 pub fn next_line(&mut self) -> String {
47 self.assert_has_more();
48 let mut line = String::new();
49 while self.peek() != '\n' {
50 line.push(self.peek());
51 self.consume();
52 if !self.has_more() { break; }
53 }
54 self.consume(); line
56 }
57
58 pub fn has_more(&mut self) -> bool {
59 if self.current_index >= self.bytes_read {
60 self.bytes_read = self.reader.read(&mut self.buf[..]).unwrap();
61 self.current_index = 0
62 }
63 self.bytes_read > 0
64 }
65
66 pub fn set_buf_size(&mut self, buf_size: usize) {
67 self.buf.resize(buf_size, 0);
68 }
69}
70
71impl<R: Read> InputReader<R> {
73 fn peek(&self) -> char { self.buf[self.current_index] as char }
74
75 fn consume(&mut self) { self.current_index += 1; }
76
77 fn assert_has_more(&mut self) {
78 assert!(self.has_more(), "InputReader: Reached end of input!");
79 }
80
81 fn pop_digit(&mut self) -> u64 {
82 let c = self.peek();
83 self.consume();
84 c as u64 - '0' as u64
85 }
86
87 fn consume_until<F: Fn(char) -> bool>(&mut self, test: F) {
88 loop {
89 self.assert_has_more();
90 if test(self.peek()) { return; }
91 self.consume();
92 }
93 }
94
95 fn consume_until_sign(&mut self) -> i64 {
96 loop {
97 self.consume_until(|c| c.is_ascii_digit() || c == '-');
98 if self.peek() != '-' { return 1; }
99
100 self.consume();
101 self.assert_has_more();
102 if self.peek().is_ascii_digit() { return -1; }
103 }
104 }
105}
106
107pub trait InputReadable {
108 fn from_input<R: Read>(input: &mut InputReader<R>) -> Self;
109}
110
111impl InputReadable for u64 {
112 fn from_input<R: Read>(input: &mut InputReader<R>) -> Self {
113 input.consume_until(|c| c.is_ascii_digit());
114 let mut num = 0;
115 while input.peek().is_ascii_digit() {
116 num = num * 10 + input.pop_digit();
117 if !input.has_more() { break; }
118 }
119 num
120 }
121}
122
123impl InputReadable for i64 {
124 fn from_input<R: Read>(input: &mut InputReader<R>) -> Self {
125 let sign = input.consume_until_sign();
126 u64::from_input(input) as i64 * sign
127 }
128}
129
130impl InputReadable for f64 {
131 fn from_input<R: Read>(input: &mut InputReader<R>) -> Self {
132 let sign = input.consume_until_sign() as f64;
133 let mut num = 0.0;
134 while input.peek().is_ascii_digit() {
135 num = num * 10.0 + input.pop_digit() as f64;
136 if !input.has_more() { break; }
137 }
138
139 let mut factor = 1.0;
140 if input.peek() == '.' {
141 input.consume();
142 while input.has_more() && input.peek().is_ascii_digit() {
143 num = num * 10.0 + input.pop_digit() as f64;
144 factor *= 10.0;
145 }
146 }
147 sign * num / factor
148 }
149}
150
151impl InputReadable for String {
152 fn from_input<R: Read>(input: &mut InputReader<R>) -> Self {
153 input.consume_until(|c| c.is_ascii_graphic());
154 let mut word = String::new();
155 while input.peek().is_ascii_graphic() {
156 word.push(input.peek());
157 input.consume();
158 if !input.has_more() { break; }
159 }
160 word
161 }
162}
163
164impl InputReadable for char {
165 fn from_input<R: Read>(input: &mut InputReader<R>) -> Self {
166 input.consume_until(|c| c.is_ascii_graphic());
167 let c = input.peek();
168 input.consume();
169 c
170 }
171}
172
173macro_rules! impl_readable_from {
174 ($A:ty, [$T:ty]) => {
175 impl InputReadable for $T {
176 fn from_input<R: Read>(input: &mut InputReader<R>) -> Self {
177 <$A>::from_input(input) as $T
178 }
179 }
180 };
181 ($A:ty, [$T:ty, $($Ts:ty),+]) => {
182 impl_readable_from!{$A, [$T]}
183 impl_readable_from!{$A, [$($Ts),*]}
184 };
185}
186impl_readable_from!{ u64, [u32, u16, u8, usize] }
187impl_readable_from!{ i64, [i32, i16, i8, isize] }
188impl_readable_from!{ f64, [f32] }