Clean Rust Library for Competitive Programming

Revision en1, by AB22, 2025-06-26 18:46:42

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.

link

The Problem

Standard Rust CP code looks like this:

use std::io;

fn main() {
    let mut input = String::new();
    io::stdin().read_line(&mut input).unwrap();
    let n: usize = input.trim().parse().unwrap();
    
    input.clear();
    io::stdin().read_line(&mut input).unwrap();
    let arr: Vec<i32> = input.trim()
        .split_whitespace()
        .map(|x| x.parse().unwrap())
        .collect();
    
    // Actually solve the problem...
    println!("{}", solve(n, arr));
}

That's way too much boilerplate! (>_<#)

The Solution

With this library, the same code becomes:

sol! {
    fn solution(n: usize, arr: [i32]) -> i32 {
        // 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). file_link

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!

Tags rust, boilerplatecode, macros, io

History

 
 
 
 
Revisions
 
 
  Rev. Lang. By When Δ Comment
en8 English AB22 2025-06-30 16:30:56 71
en7 English AB22 2025-06-30 10:46:33 8 Tiny change: 'e, arr: [i32]) -> i32 {\n ' -> 'e, arr: [i64]) -> i64 {\n '
en6 English AB22 2025-06-30 10:45:35 505
en5 English AB22 2025-06-30 10:28:35 4
en4 English AB22 2025-06-30 10:28:08 85
en3 English AB22 2025-06-29 14:16:54 2 Tiny change: 'ix: [[i32]]; n, ' -> 'ix: [[i32]; n], '
en2 English AB22 2025-06-26 18:47:20 1 Tiny change: 'es! \(^_^)/\n\nI've b' -> 'es! \(^_^)\n\nI've b'
en1 English AB22 2025-06-26 18:46:42 4801 Initial revision (published)