Skip to content

Commit 330306f

Browse files
authored
Merge pull request #92 from qryxip/verify-with-oj
Verify with problems from Library Checker
2 parents 4ed6203 + 8f62704 commit 330306f

File tree

8 files changed

+243
-0
lines changed

8 files changed

+243
-0
lines changed

.github/workflows/ci.yml

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,3 +129,47 @@ jobs:
129129

130130
- name: expand.py tests
131131
run: bash ./.github/workflows/test-expand.sh
132+
133+
verify:
134+
name: Verify
135+
runs-on: ubuntu-20.04
136+
137+
steps:
138+
- name: Checkout
139+
uses: actions/checkout@v2
140+
141+
- name: Setup `1.47.0-x86_64-unknown-linux-gnu`
142+
uses: actions-rs/toolchain@v1
143+
with:
144+
toolchain: 1.47.0-x86_64-unknown-linux-gnu
145+
override: true
146+
profile: minimal
147+
148+
- name: Setup Python 3.9
149+
uses: actions/setup-python@v2
150+
with:
151+
python-version: '3.9'
152+
153+
- name: Install `oj`
154+
run: pip install online-judge-tools
155+
156+
- name: cargo-build
157+
uses: actions-rs/cargo@v1
158+
with:
159+
command: build
160+
args: --release --examples
161+
162+
- name: Verify
163+
run: |
164+
NAMES=(
165+
convolution_mod
166+
static_range_sum
167+
sum_of_floor_of_linear
168+
unionfind
169+
)
170+
for name in "${NAMES[@]}"; do
171+
oj d "https://judge.yosupo.jp/problem/$name" -ad "/tmp/$name"
172+
done
173+
for name in "${NAMES[@]}"; do
174+
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
175+
done

Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,5 +15,7 @@ publish = false
1515
[dependencies]
1616

1717
[dev-dependencies]
18+
input = { path = "./crates/input" }
1819
proconio = "=0.3.6"
20+
proconio-derive = "0.2.1"
1921
rand = "0.7.3"

crates/input/Cargo.toml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
[package]
2+
name = "input"
3+
version = "0.1.0"
4+
authors = ["rust-lang-ja Developers"]
5+
edition = "2018"
6+
description = "Provides an `input!` macro for the `examples`."
7+
license = "CC0-1.0"
8+
publish = false
9+
10+
[dependencies]

crates/input/src/lib.rs

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
//! A simple `input!` macro with minimal functionality.
2+
//!
3+
//! ```no_run
4+
//! #[macro_use]
5+
//! extern crate input as _;
6+
//!
7+
//! fn main() {
8+
//! input! {
9+
//! a: [u64],
10+
//! }
11+
//! }
12+
//! ```
13+
14+
use std::{
15+
fmt,
16+
io::{self, Read},
17+
str::{FromStr, SplitAsciiWhitespace},
18+
};
19+
20+
#[macro_export]
21+
macro_rules! input {
22+
($($tt:tt)*) => {
23+
let mut __scanner = $crate::Scanner::new().unwrap();
24+
$crate::input_inner!(@scanner(__scanner), @tts($($tt)*));
25+
::std::mem::drop(__scanner);
26+
};
27+
}
28+
29+
#[doc(hidden)]
30+
#[macro_export]
31+
macro_rules! input_inner {
32+
(@scanner($scanner:ident), @tts()) => {};
33+
(@scanner($scanner:ident), @tts(mut $single_tt_pat:tt : $readable:tt)) => {
34+
let mut $single_tt_pat = $crate::read!(from $scanner { $readable });
35+
};
36+
(@scanner($scanner:ident), @tts($single_tt_pat:tt : $readable:tt)) => {
37+
let $single_tt_pat = $crate::read!(from $scanner { $readable });
38+
};
39+
(@scanner($scanner:ident), @tts(mut $single_tt_pat:tt : $readable:tt, $($rest:tt)*)) => {
40+
$crate::input_inner!(@scanner($scanner), @tts(mut $single_tt_pat: $readable));
41+
$crate::input_inner!(@scanner($scanner), @tts($($rest)*));
42+
};
43+
(@scanner($scanner:ident), @tts($single_tt_pat:tt : $readable:tt, $($rest:tt)*)) => {
44+
$crate::input_inner!(@scanner($scanner), @tts($single_tt_pat: $readable));
45+
$crate::input_inner!(@scanner($scanner), @tts($($rest)*));
46+
};
47+
}
48+
49+
#[doc(hidden)]
50+
#[macro_export]
51+
macro_rules! read {
52+
(from $scanner:ident { [$tt:tt] }) => {
53+
$crate::read!(from $scanner { [$tt; $crate::read!(from $scanner { usize })] })
54+
};
55+
(from $scanner:ident { [$tt:tt; $n:expr] }) => {
56+
(0..$n).map(|_| $crate::read!(from $scanner { $tt })).collect::<Vec<_>>()
57+
};
58+
(from $scanner:ident { ($($tt:tt),+) }) => {
59+
($($crate::read!(from $scanner { $tt })),*)
60+
};
61+
(from $scanner:ident { $ty:ty }) => {
62+
$scanner.parse::<$ty>()
63+
};
64+
}
65+
66+
#[doc(hidden)]
67+
pub struct Scanner {
68+
words: SplitAsciiWhitespace<'static>,
69+
}
70+
71+
impl Scanner {
72+
pub fn new() -> io::Result<Self> {
73+
let mut buf = String::with_capacity(1024);
74+
io::stdin().read_to_string(&mut buf)?;
75+
let words = Box::leak(buf.into_boxed_str()).split_ascii_whitespace();
76+
Ok(Self { words })
77+
}
78+
79+
/// Parses the next word.
80+
///
81+
/// # Panics
82+
///
83+
/// Panics if:
84+
///
85+
/// - reached the end of input.
86+
/// - the word is not successfully parsed.
87+
pub fn parse<T>(&mut self) -> T
88+
where
89+
T: FromStr,
90+
T::Err: fmt::Display,
91+
{
92+
let word = self.words.next().expect("reached the end of input");
93+
word.parse()
94+
.unwrap_or_else(|e| panic!("could not parse {:?}: {}", word, e))
95+
}
96+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
#[macro_use]
2+
extern crate input as _;
3+
4+
use ac_library_rs::{convolution, modint::ModInt998244353 as Mint};
5+
use std::fmt;
6+
7+
fn main() {
8+
input! {
9+
n: usize,
10+
m: usize,
11+
a: [Mint; n],
12+
b: [Mint; m],
13+
}
14+
15+
print_oneline(convolution::convolution(&a, &b));
16+
}
17+
18+
fn print_oneline<I: IntoIterator<Item = T>, T: fmt::Display>(values: I) {
19+
println!(
20+
"{}",
21+
values
22+
.into_iter()
23+
.map(|v| v.to_string())
24+
.collect::<Vec<_>>()
25+
.join(" "),
26+
)
27+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
#[macro_use]
2+
extern crate input as _;
3+
#[macro_use]
4+
extern crate proconio_derive as _;
5+
6+
use ac_library_rs::fenwicktree::FenwickTree;
7+
8+
#[allow(clippy::needless_collect)]
9+
#[fastout]
10+
fn main() {
11+
input! {
12+
n: usize,
13+
q: usize,
14+
r#as: [u64; n],
15+
lrs: [(usize, usize); q],
16+
}
17+
18+
let mut fenwick = FenwickTree::new(n, 0);
19+
for (i, a) in r#as.into_iter().enumerate() {
20+
fenwick.add(i, a);
21+
}
22+
for (l, r) in lrs {
23+
println!("{}", fenwick.sum(l, r));
24+
}
25+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
#[macro_use]
2+
extern crate input as _;
3+
#[macro_use]
4+
extern crate proconio_derive as _;
5+
6+
use ac_library_rs::math;
7+
8+
#[fastout]
9+
fn main() {
10+
input! {
11+
nmabs: [(i64, i64, i64, i64)],
12+
}
13+
14+
for (n, m, a, b) in nmabs {
15+
println!("{}", math::floor_sum(n, m, a, b));
16+
}
17+
}

examples/library-checker-unionfind.rs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
#[macro_use]
2+
extern crate input as _;
3+
4+
use ac_library_rs::dsu::Dsu;
5+
6+
fn main() {
7+
input! {
8+
n: usize,
9+
queries: [(u8, usize, usize)],
10+
}
11+
12+
let mut dsu = Dsu::new(n);
13+
for (kind, u, v) in queries {
14+
match kind {
15+
0 => {
16+
dsu.merge(u, v);
17+
}
18+
1 => println!("{}", u8::from(dsu.same(u, v))),
19+
_ => unreachable!(),
20+
}
21+
}
22+
}

0 commit comments

Comments
 (0)