Hey Codeforces! (^_^)
I've been working on a Rust library that makes competitive programming in Rust much cleaner and less verbose. If you've ever tried Rust for CP, you know the pain of writing the same input parsing boilerplate over and over again.
The Problem
Standard Rust CP code looks like this:
use std::{
io::{stdin, stdout, BufRead, BufReader, BufWriter, Read, Write},
iter::repeat,
};
fn solve<R: Read, W: Write>(input: R, output: W) {
let mut reader = BufReader::new(input);
let mut writer = BufWriter::new(output);
let mut buf = String::new();
reader.read_line(&mut buf).unwrap();
let n: usize = buf.trim().parse().unwrap();
buf.clear();
reader.read_line(&mut buf).unwrap();
let a: Vec<i64> = buf.split_whitespace().map(|s| s.parse().unwrap()).collect();
// rest of the logic here
writeln!(writer, "{}", ans).unwrap();
}
fn main() {
let stdin = stdin();
let stdout = stdout();
solve(stdin.lock(), stdout.lock());
}
That's way too much boilerplate! (>_<#)
The Solution
With this library, the same code becomes:
sol! {
fn solution(n: usize, arr: [i64]) -> i64 {
// Your actual solution logic here
arr.iter().sum()
}
}
That's it! Clean, readable, and focuses on the algorithm rather than I/O.
Features
Simple Macros
- sol! for single test case problems
- sol_n! for multiple test case problems (reads N, then N test cases)
Smart Input Parsing
- The read_value! macro handles various input patterns:
sol! {
fn solution(
n: usize, // Single integer
arr: [i32], // Space-separated integers
matrix: [[i32]; n], // n lines of space-separated integers
s: [char], // String as char array
binary: [01], // Binary string as Vec<u8>
fixed: [i32; 5], // Exactly 5 integers
lines: [String]; n // n lines as strings
) -> String {
format!("Parsed {} elements", arr.len())
}
}
Flexible Output
// Automatic Yes/No for booleans
sol! {
fn solution(n: i32) -> bool {
n % 2 == 0 // Prints "Yes" or "No"
}
}
// Lists with custom separators
use cp_lib::{Words, Lines, words_of, lines_of};
sol! {
fn solution(arr: [i32]) -> Words<i32> {
words_of(arr) // Space-separated output
}
}
Debug Support
sol! {
fn solution(n: usize, arr: [i32]) -> i32 {
dbg_cp!("Processing array of size: {}", n); // Only prints in debug mode
arr.iter().max().unwrap_or(&0).clone()
}
}
Real Examples
Typical CF Problem
sol! {
fn solution(n: usize, a: [i32]) -> i32 {
let mut max_val = 0;
let mut current = 0;
for &x in &a {
current = (current + x).max(x);
max_val = max_val.max(current);
}
max_val
}
}
Multiple Test Cases
sol_n! {
fn solution(n: usize, s: [char]) -> bool {
let count_a = s.iter().filter(|&&c| c == 'a').count();
count_a > n - count_a
}
}
Grid Problems
sol! {
fn solution(n: usize, m: usize, grid: [[char]; n]) -> i32 {
let mut count = 0;
for i in 0..n {
for j in 0..m {
if grid[i][j] == '#' {
count += 1;
}
}
}
count
}
}
Performance
The library is designed for competitive programming:
- Buffered I/O for fast input/output
- Pre-allocated string buffers
- Zero-copy parsing where possible
- Minimal runtime overhead
How to Use
- Copy the library code to your solution file (or use as a dependency)
- Replace your main function with sol! or sol_n! macro
- Focus on solving the problem instead of parsing input!
Source Code
The complete library is available as a single file that you can copy-paste into your solutions. It's designed to be self-contained and dependency-free (except for std).
Why Rust for CP?
- Memory Safety: No segfaults or buffer overflows
- Performance: As fast as C++ when optimized
- Expressiveness: Powerful iterators and functional programming
- Type Safety: Catch bugs at compile time
- Great Tooling: Excellent error messages and debugging
The main barrier was always the verbose I/O, but this library solves that!
Feedback Welcome!
I'd love to hear your thoughts and suggestions! Have you tried Rust for competitive programming? What other features would make this library more useful? Let me know in the comments if you try it out!









