Skip to content

Commit

Permalink
Merge pull request #92 from qryxip/verify-with-oj
Browse files Browse the repository at this point in the history
Verify with problems from Library Checker
  • Loading branch information
qryxip authored Mar 25, 2022
2 parents 4ed6203 + 8f62704 commit 330306f
Show file tree
Hide file tree
Showing 8 changed files with 243 additions and 0 deletions.
44 changes: 44 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -129,3 +129,47 @@ jobs:

- name: expand.py tests
run: bash ./.github/workflows/test-expand.sh

verify:
name: Verify
runs-on: ubuntu-20.04

steps:
- name: Checkout
uses: actions/checkout@v2

- name: Setup `1.47.0-x86_64-unknown-linux-gnu`
uses: actions-rs/toolchain@v1
with:
toolchain: 1.47.0-x86_64-unknown-linux-gnu
override: true
profile: minimal

- name: Setup Python 3.9
uses: actions/setup-python@v2
with:
python-version: '3.9'

- name: Install `oj`
run: pip install online-judge-tools

- name: cargo-build
uses: actions-rs/cargo@v1
with:
command: build
args: --release --examples

- name: Verify
run: |
NAMES=(
convolution_mod
static_range_sum
sum_of_floor_of_linear
unionfind
)
for name in "${NAMES[@]}"; do
oj d "https://judge.yosupo.jp/problem/$name" -ad "/tmp/$name"
done
for name in "${NAMES[@]}"; do
oj t -d "/tmp/$name" -t 10 -c "./target/release/examples/library-checker-${name//_/-}" --judge-command ~/.cache/online-judge-tools/library-checker-problems/*/"$name"/checker
done
2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,7 @@ publish = false
[dependencies]

[dev-dependencies]
input = { path = "./crates/input" }
proconio = "=0.3.6"
proconio-derive = "0.2.1"
rand = "0.7.3"
10 changes: 10 additions & 0 deletions crates/input/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
[package]
name = "input"
version = "0.1.0"
authors = ["rust-lang-ja Developers"]
edition = "2018"
description = "Provides an `input!` macro for the `examples`."
license = "CC0-1.0"
publish = false

[dependencies]
96 changes: 96 additions & 0 deletions crates/input/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
//! A simple `input!` macro with minimal functionality.
//!
//! ```no_run
//! #[macro_use]
//! extern crate input as _;
//!
//! fn main() {
//! input! {
//! a: [u64],
//! }
//! }
//! ```
use std::{
fmt,
io::{self, Read},
str::{FromStr, SplitAsciiWhitespace},
};

#[macro_export]
macro_rules! input {
($($tt:tt)*) => {
let mut __scanner = $crate::Scanner::new().unwrap();
$crate::input_inner!(@scanner(__scanner), @tts($($tt)*));
::std::mem::drop(__scanner);
};
}

#[doc(hidden)]
#[macro_export]
macro_rules! input_inner {
(@scanner($scanner:ident), @tts()) => {};
(@scanner($scanner:ident), @tts(mut $single_tt_pat:tt : $readable:tt)) => {
let mut $single_tt_pat = $crate::read!(from $scanner { $readable });
};
(@scanner($scanner:ident), @tts($single_tt_pat:tt : $readable:tt)) => {
let $single_tt_pat = $crate::read!(from $scanner { $readable });
};
(@scanner($scanner:ident), @tts(mut $single_tt_pat:tt : $readable:tt, $($rest:tt)*)) => {
$crate::input_inner!(@scanner($scanner), @tts(mut $single_tt_pat: $readable));
$crate::input_inner!(@scanner($scanner), @tts($($rest)*));
};
(@scanner($scanner:ident), @tts($single_tt_pat:tt : $readable:tt, $($rest:tt)*)) => {
$crate::input_inner!(@scanner($scanner), @tts($single_tt_pat: $readable));
$crate::input_inner!(@scanner($scanner), @tts($($rest)*));
};
}

#[doc(hidden)]
#[macro_export]
macro_rules! read {
(from $scanner:ident { [$tt:tt] }) => {
$crate::read!(from $scanner { [$tt; $crate::read!(from $scanner { usize })] })
};
(from $scanner:ident { [$tt:tt; $n:expr] }) => {
(0..$n).map(|_| $crate::read!(from $scanner { $tt })).collect::<Vec<_>>()
};
(from $scanner:ident { ($($tt:tt),+) }) => {
($($crate::read!(from $scanner { $tt })),*)
};
(from $scanner:ident { $ty:ty }) => {
$scanner.parse::<$ty>()
};
}

#[doc(hidden)]
pub struct Scanner {
words: SplitAsciiWhitespace<'static>,
}

impl Scanner {
pub fn new() -> io::Result<Self> {
let mut buf = String::with_capacity(1024);
io::stdin().read_to_string(&mut buf)?;
let words = Box::leak(buf.into_boxed_str()).split_ascii_whitespace();
Ok(Self { words })
}

/// Parses the next word.
///
/// # Panics
///
/// Panics if:
///
/// - reached the end of input.
/// - the word is not successfully parsed.
pub fn parse<T>(&mut self) -> T
where
T: FromStr,
T::Err: fmt::Display,
{
let word = self.words.next().expect("reached the end of input");
word.parse()
.unwrap_or_else(|e| panic!("could not parse {:?}: {}", word, e))
}
}
27 changes: 27 additions & 0 deletions examples/library-checker-convolution-mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#[macro_use]
extern crate input as _;

use ac_library_rs::{convolution, modint::ModInt998244353 as Mint};
use std::fmt;

fn main() {
input! {
n: usize,
m: usize,
a: [Mint; n],
b: [Mint; m],
}

print_oneline(convolution::convolution(&a, &b));
}

fn print_oneline<I: IntoIterator<Item = T>, T: fmt::Display>(values: I) {
println!(
"{}",
values
.into_iter()
.map(|v| v.to_string())
.collect::<Vec<_>>()
.join(" "),
)
}
25 changes: 25 additions & 0 deletions examples/library-checker-static-range-sum.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#[macro_use]
extern crate input as _;
#[macro_use]
extern crate proconio_derive as _;

use ac_library_rs::fenwicktree::FenwickTree;

#[allow(clippy::needless_collect)]
#[fastout]
fn main() {
input! {
n: usize,
q: usize,
r#as: [u64; n],
lrs: [(usize, usize); q],
}

let mut fenwick = FenwickTree::new(n, 0);
for (i, a) in r#as.into_iter().enumerate() {
fenwick.add(i, a);
}
for (l, r) in lrs {
println!("{}", fenwick.sum(l, r));
}
}
17 changes: 17 additions & 0 deletions examples/library-checker-sum-of-floor-of-linear.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#[macro_use]
extern crate input as _;
#[macro_use]
extern crate proconio_derive as _;

use ac_library_rs::math;

#[fastout]
fn main() {
input! {
nmabs: [(i64, i64, i64, i64)],
}

for (n, m, a, b) in nmabs {
println!("{}", math::floor_sum(n, m, a, b));
}
}
22 changes: 22 additions & 0 deletions examples/library-checker-unionfind.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#[macro_use]
extern crate input as _;

use ac_library_rs::dsu::Dsu;

fn main() {
input! {
n: usize,
queries: [(u8, usize, usize)],
}

let mut dsu = Dsu::new(n);
for (kind, u, v) in queries {
match kind {
0 => {
dsu.merge(u, v);
}
1 => println!("{}", u8::from(dsu.same(u, v))),
_ => unreachable!(),
}
}
}

0 comments on commit 330306f

Please sign in to comment.