[−][src]Crate proconio
Easy IO library for competitive programming.
proconio
provides an easy way to read values from stdin (or other source). The main is
input!
macro.
Examples
The macro's user interface is basically the same with tanakh's input macro.
use proconio::input; input! { n: u8, m: u32, l: i32, } // now you can use n, m and l as variable. println!("{} {} {}", n, m, l);
In above code, variables n, m and l are declared and stored values are read from stdin.
You can declare mutable variables like below:
use proconio::input; input! { n: u32, mut m: u32, } m += n; // OK: m is mutable
You can read an array or a matrix like this:
use proconio::input; input! { n: usize, m: usize, a: [[i32; n]; m] // `a` is Vec<Vec<i32>>, (n, m)-matrix. }
If the first input is the length of the array, you can omit the length. This is the only way
to read jagged array (an array of arrays of which the member arrays can be of different sizes)
at once. (Of course you can use input!
multiple times in for-loop to read such an array
since input!
can be used multiple times.)
use proconio::input; input! { n: usize, a: [[i32]; n], } // if you enter "3 3 1 2 3 0 2 1 2" to the stdin, the result is as follows. assert_eq!( a, vec![ vec![1, 2, 3], vec![], vec![1, 2], ] );
Strings can be read as various types:
use proconio::input; use proconio::types::{Bytes, Chars}; input! { string: String, // read as String chars: Chars, // read as Vec<char> bytes: Bytes, // read as Vec<u8> } // if you enter "string chars bytes" to the stdin, they are like this. assert_eq!(string, "string"); assert_eq!(chars, ['c', 'h', 'a', 'r', 's']); assert_eq!(bytes, b"bytes");
You can read tuples:
use proconio::input; input! { t: (i32, i32, i32, i32, i32), } // if you enter "1 2 3 4 5" to the stdin, `t` is like this. assert_eq!(t, (1, 2, 3, 4, 5));
And you can freely combine these types.
use proconio::input; input! { n: usize, m: usize, t: [([u32; m], i32); n], }
You can use input!
macro multiple times. For the second time, input!
macro reads rest of
input. It works even if the first input stops at the middle of a line. The subsequent reads
will be started at the rest of the line. This may be helpful for problems where multiple
datasets are given once.
use proconio::input; input! { n: usize, } for i in 0..n { input! { m: usize, a: [i32; m], } }
Some special types exists. Usize1
and Isize1
are. They are read as usize
and isize
respectively, but the read value is decremented. It enables us to automatically convert
1-indexed vertices numbers to 0-indexed array indices.
use proconio::input; use proconio::types::Usize1; input! { n: usize, edges: [(Usize1, Usize1); n], } // if you enter "4 1 3 3 4 6 1 5 3", the decremented value is stored. assert_eq!(edges[0], (0, 2)); assert_eq!(edges[1], (2, 3)); assert_eq!(edges[2], (5, 0)); assert_eq!(edges[3], (4, 2));
Usize1
and Isize1
is a simple unit struct. This type is only used to tell "how to read the
value". It can be defined by Readable
trait. This trait doesn't require the output type to
be the same with the implementor. Usize1
is implementing Readable
trait, and there it
defines the type of read value is usize
. You can implement Readable
for your own type to
read values in customized way.
Finally, you can make your own types Readable
using #[derive_readable]
attribute. Types
used in the struct are automatically translated to their output types, so a member declared as
Usize1
has type usize
as real struct.
use proconio::input; use proconio_derive::derive_readable; // Unit struct can derive readable. This generates a no-op for the reading. Not ignoring // the read value, but simply skip reading process. You cannot use it to discard the input. #[derive_readable] #[derive(PartialEq, Debug)] struct Weight; #[derive_readable] #[derive(PartialEq, Debug)] struct Cost(i32); #[derive_readable] #[derive(Debug)] struct Edge { from: usize, to: proconio::types::Usize1, // The real Edge::to has type usize. weight: Weight, cost: Cost, } fn main() { input! { edge: Edge, } // if you enter "12 32 35" to the stdin, the values are as follows. assert_eq!(edge.from, 12); assert_eq!(edge.to, 31); assert_eq!(edge.weight, Weight); assert_eq!(edge.cost, Cost(35)); }
#[fastout]
If you import proconio_derive::fastout
, you can use #[fastout]
attribute. Adding this
attribute to your main()
, your print!
and println!
become faster.
use proconio_derive::fastout; #[fastout] fn main() { print!("{}{}, ", 'h', "ello"); // "hello" (no newline) println!("{}!", "world"); // "world!\n" println!("{}", 123456789); // "123456789\n" }
Closures having print!
or println!
in #[fastout]
function
You cannot create a closure containing print!
or println!
in #[fastout]
function. This
is because the closure becomes thread-unsafe since the closure refers the unlocked stdout
introduced by #[fastout]
attribute. If this were not prohibited, an invalid usage of such a
closure would produce a very complex error messages. For example, std::thread::spawn()
,
which requires its argument closure to be thread-safe, causes a confusing error.
Yes, it is too conservative to make all of such closures compilation error because it is
actually no problem to use such a closure only inside a single thread. This is related to a
limitation in #[fastout]
implementation.
For more technical details, see documentation for #[fastout]
in proconio-derive
.
How to resolve this error
Consider you want to run this code:
use proconio_derive::fastout; #[fastout] fn main() { let thread = std::thread::spawn(|| { let x = 3; let y = x * x; println!("{}", y); }); thread.join().unwrap(); }
You will get an error like below.
error: Closures in a #[fastout] function cannot contain `print!` or `println!` macro
note: If you want to run your entire logic in a thread having extended size of stack, you can
define a new function instead. See documentation (https://.....) for more details.
note: This is because if you use this closure with `std::thread::spawn()` or any other
functions requiring `Send` for an argument closure, the compiler emits an error about thread
unsafety for our internal implementations. If you are using the closure just in a single
thread, it's actually no problem, but we cannot check the trait bounds at the macro-expansion
time. So for now, all closures having `print!` or `println!` is prohibited regardless of the
`Send` requirements.
--> src/test.rs:10:9
|
10 | println!("{}", y);
| ^^^^^^^
If your print!
is relying on the calculation in the thread, you can instead return the result
from the thread.
use proconio_derive::fastout; #[fastout] fn main() { let thread = std::thread::spawn(|| { let x = 3; x * x }); let y = thread.join().unwrap(); println!("{}", y); }
If you are doing so complex job that it's too difficult to returning the results from your closure...
use proconio_derive::fastout; #[fastout] fn main() { let context = "some context".to_string(); let thread = std::thread::spawn(move || { // Use many println! and the order is very important // It's possible to aggregate the result and print it later, but it's not easy to read // and seems ugly. println!("this is header."); for (i, item) in some_function(context).enumerate() { print!("Item #{}: ", i); print!("{}", some_proc(&item)); println!("({})", item); } }); thread.join().unwrap(); }
...you can use a function instead.
use proconio_derive::fastout; // You can add #[fastout] here #[fastout] fn process(context: String) { // It's completely OK since this #[fastout] is a thing inside `process()` println!("this is header."); for (i, item) in some_function(context).enumerate() { print!("Item #{}: ", i); print!("{}", some_proc(&item)); println!("({})", item); } } // You must not add #[fastout] here! It causes deadlock. // #[fastout] fn main() { let context = "some context".to_string(); let thread = std::thread::spawn(move || process(context)); thread.join().unwrap(); }
Important Note: If you call another function annotated with #[fastout]
, you must not add
#[fastout]
to the caller. If you add #[fastout]
in caller too, then the caller has the
lock for the stdout, and so callee cannot acquire the lock forever --- deadlock. We cannot
warn about this kind of deadlock since we don't know annotations attached to the function to be
called. (In the above example, we can't know whether the function process()
has #[fastout]
attribute or not.)
If your code is so complex that you cannot avoid deadlock, you should give up using
#[fastout]
and simply use println!
or manually handle your stdout in usual Rust way.
Issues of printing order
#[fastout]
enables buffering to stdout, so if you print something in other functions between
two prints in main, the order of printing may differ. In other words, the below example
fn foo() { println!("between"); } #[fastout] fn main() { println!("hello"); foo(); println!("world"); }
likely prints like
between
hello
world
If you don't like this behavior, you can remove #[fastout] from your main()
.
Modules
read | Implements readable to the primitives and other special types (such as Chars, Bytes, ...). |
source | Defines whitespace-splitted token stream wrapping actual stream like stdin. |
types | Declares special types and aliases. |
Macros
input | read input from stdin. |
Functions
is_stdin_empty | Checks if some of tokens are left on stdin. |