[][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:

This example deliberately fails to compile
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...

This example deliberately fails to compile
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.