Last active
April 9, 2025 21:03
-
-
Save kdkasad/78a3bcbf0022a6a830edc7575ad1789e to your computer and use it in GitHub Desktop.
Rust competitive programming template
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//! | |
//! # Rust competitive programming template | |
//! | |
//! Copyright (C) 2025 Kian Kasad (@kdkasad). | |
//! Testing via I/O dependency injection inspired by Eric Park (@ericswpark). | |
//! | |
//! You are free to use this template. If you redistribute it or a derivative work, the above | |
//! copyright notice and credits as well as this permission notice must be kept intact. | |
//! | |
//! Requires the following crates as dev-dependencies: | |
//! - `indoc` | |
//! - `pretty_assertions` | |
//! | |
/// Solves the problem. | |
fn solve<R, W>(input: &mut R, output: &mut W) | |
where | |
R: std::io::BufRead, | |
W: std::io::Write, | |
{ | |
todo!() | |
} | |
/// Reads a single line containing `N` integers separated by ASCII whitespace from the input | |
/// stream. | |
/// | |
/// # Panics | |
/// | |
/// Panics if | |
/// - reading from the stream fails, | |
/// - the line contains less than `N` whitespace-separated parts, or | |
/// - parsing any part into a `usize` fails. | |
/// | |
/// In debug mode, this function also panics if the line contains more than `N` parts. | |
#[allow(dead_code)] | |
fn read_parts<T, const N: usize, R>(input: &mut R) -> [T; N] | |
where | |
R: std::io::BufRead, | |
T: std::str::FromStr<Err: std::fmt::Debug> + Default + Copy, | |
{ | |
let mut arr = [T::default(); N]; | |
let mut line = String::new(); | |
input.read_line(&mut line).unwrap(); | |
let mut parts = line | |
.split_ascii_whitespace() | |
.map(|s| s.parse::<T>().unwrap()); | |
for (i, cell) in arr.iter_mut().enumerate() { | |
*cell = parts | |
.next() | |
.unwrap_or_else(|| panic!("Expected {N} numbers but got {i}")); | |
} | |
debug_assert!(parts.next().is_none(), "Line contains more than {N} parts"); | |
arr | |
} | |
/// Specialized form of [`read_parts()`] to allow for a nicer interface to read a line of a known | |
/// amount of space-separated `usize`s. | |
#[allow(dead_code)] | |
fn read_usizes<const N: usize, R>(input: &mut R) -> [usize; N] | |
where | |
R: std::io::BufRead, | |
{ | |
read_parts(input) | |
} | |
pub fn main() { | |
solve(&mut std::io::stdin().lock(), &mut std::io::stdout().lock()); | |
} | |
#[cfg(test)] | |
mod tests { | |
use indoc::indoc; | |
use pretty_assertions::assert_str_eq; | |
macro_rules! sample { | |
{ $testname:ident, $input:literal, $output:literal } => { | |
#[test] | |
fn $testname() { | |
let mut input = std::io::Cursor::new( | |
indoc! { $input } | |
); | |
let expected_output = indoc! { $output }; | |
let mut output = Vec::new(); | |
super::solve(&mut input, &mut output); | |
assert_str_eq!(expected_output, std::str::from_utf8(&output).unwrap()); | |
} | |
}; | |
} | |
sample! { | |
sample1, | |
"", | |
"" | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment