diff --git a/Cargo.toml b/Cargo.toml index 76bb1ee..e54e3f5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -25,7 +25,7 @@ modtype = "=0.7.0" # 英数字などのASCII文字専用の文字列。文字にインデックスでアクセスしたり # substringを簡単に作ったりできる -ascii = "=0.9.1" +ascii = "=0.9.2" # BitSet。C++のbitsetに相当 bitset-fixed = "=0.1.0" @@ -46,37 +46,30 @@ rustc-hash = "=1.0.1" # Rust 1.36.0からは標準ライブラリのHashMapがこれに置き換わる。(AtCoder 2019年言語 # アップデートではそれより古い1.35.0を採用) ハッシュ関数として従来のSipHashが用いられる # ことに注意。(SipHashは暗号強度を持つため計算量が多く低速) -hashbrown = "=0.4.0" +hashbrown = "=0.5.0" # 固定配列上のベクタ。ヒープ領域でなくスタック領域にアロケートされるので高速かもしれない smallvec = "=0.6.10" -arrayvec = "=0.4.10" +arrayvec = "=0.4.11" # 標準ライブラリのVecやHashMapに対応する永続データ構造 # 永続データ構造は関数型言語によく見られるデータ構造で、要素を更新しても、そのデータ構造の # 以前のバージョンにアクセスできる。(更新の度に差分が記録されていくイメージ) -im = "=13.0.0" # スレッドセーフ -im-rc = "=13.0.0" # スレッドセーフでないが高速 +im-rc = "=13.0.0" # 多バイト長整数、分数、複素数など num = "=0.2.0" # RNG 疑似乱数生成器 (randファミリー) -rand = "=0.6.5" -rand_chacha = "=0.1.1" -rand_pcg = "=0.1.2" - -# RNG 疑似乱数生成器 (SFMT) -# SIMD-oriented Fast Mersenne Twister (SFMT)のpure Rust実装 -# 高速で高品質な疑似乱数を生成。モンテカルロ・シミュレーションに適している -sfmt = "=0.5.0" +rand = { version = "=0.7.0", features = ["small_rng"] } +rand_chacha = "=0.2.1" +rand_pcg = "=0.2.0" # 正規表現 -regex = "=1.1.7" +regex = "=1.2.1" # staticアイテムの遅延初期化 lazy_static = "=1.3.0" -once_cell = "=0.2.1" # 代替ヒープアロケータ。条件によってはシステムアロケータより速いことも jemallocator = "=0.3.2" diff --git a/src/main.rs b/src/main.rs index 5d22cc1..398a26e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -15,11 +15,9 @@ fn main() -> UnitResult { run_hashbrown(); // run_smallvec(); // run_arrayvec(); - // run_im(); // run_im_rc(); // run_num(); run_rand_family()?; - run_sfmt()?; run_regex()?; Ok(()) } @@ -30,31 +28,40 @@ fn main() -> UnitResult { // proconio #[proconio_derive::fastout] fn run_proconio() { - use proconio::input; - use proconio::source::auto::AutoSource; + use proconio::source::{line::LineSource, once::OnceSource, Source}; + use std::io::BufReader; - let source = AutoSource::from( - r#"2 + run_proconio_for::>>(); + run_proconio_for::>>(); + + #[proconio_derive::fastout] + fn run_proconio_for<'a, T: Source> + From<&'a str>>() { + use proconio::input; + + let source = T::from( + r#"2 3 1 2 6 1 1 "#, - ); + ); - input! { - from source, - n: usize, - mut plan: [(i32, i32, i32); n], // Vec<(i32, i32, i32)> + input! { + from source, + n: usize, + mut plan: [(i32, i32, i32); n], // Vec<(i32, i32, i32)> + } + + plan.insert(0, (0, 0, 0)); + let yes = plan.windows(2).all(|w| { + let (t0, x0, y0) = w[0]; + let (t1, x1, y1) = w[1]; + let time = t1 - t0; + let dist = (x1 - x0).abs() + (y1 - y0).abs(); + dist <= time && time % 2 == dist % 2 + }); + println!("{}", if yes { "Yes" } else { "No" }); + assert!(yes); } - plan.insert(0, (0, 0, 0)); - let yes = plan.windows(2).all(|w| { - let (t0, x0, y0) = w[0]; - let (t1, x1, y1) = w[1]; - let time = t1 - t0; - let dist = (x1 - x0).abs() + (y1 - y0).abs(); - dist <= time && time % 2 == dist % 2 - }); - println!("{}", if yes { "Yes" } else { "No" }); - assert!(yes); } #[test] @@ -248,7 +255,7 @@ fn run_bitset_fixed() { use rand::distributions::Uniform; use rand::prelude::*; - let mut rng = StdRng::seed_from_u64(114514); + let rng = StdRng::seed_from_u64(114514); let dist = Uniform::from(0..2000); let n = rng @@ -267,7 +274,7 @@ fn run_bitset_fixed() { let ans = ((sum + 1) / 2..).find(|&i| bitset[i]).unwrap(); println!("N = {:?}\nAnswer = {}", n, ans); - assert_eq!(ans, 14675); + assert_eq!(ans, 13465); } #[test] @@ -371,7 +378,6 @@ fn test_hashbrown() { // smallvec // arrayvec -// im // im-rc // num @@ -405,24 +411,9 @@ fn test_rand_family() -> UnitResult { run_rand_family() } -// sfmt -fn run_sfmt() -> UnitResult { - use rand::prelude::*; - use sfmt::SFMT; - - let mut rng = SFMT::from_rng(thread_rng())?; - let mean = calc_mean(&mut rng); - println!("SFMT: mean = {:.4}", mean); - assert_eq!((mean * 10.0).round() as u32, 5); - Ok(()) -} - -#[test] -fn test_sfmt() -> UnitResult { - run_sfmt() -} - fn calc_mean(rng: &mut impl rand::Rng) -> f64 { + // to see `impl Rng for &mut R where R: Rng`, which prevent moving in `rng.sample_iter()` + use rand::Rng as _; const ITERATIONS: usize = 10000; // the stardard distribution for f64 generates a random rumber in interval [0, 1)