From f1d154d3e083e6cc0241345e28cc863ea0df2324 Mon Sep 17 00:00:00 2001 From: statiolake Date: Tue, 6 Aug 2019 21:20:56 +0900 Subject: [PATCH 1/6] Remove sfmt --- Cargo.toml | 5 ----- src/main.rs | 18 ------------------ 2 files changed, 23 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 76bb1ee..8ef4ecf 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -66,11 +66,6 @@ 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" - # 正規表現 regex = "=1.1.7" diff --git a/src/main.rs b/src/main.rs index 5d22cc1..b17f302 100644 --- a/src/main.rs +++ b/src/main.rs @@ -19,7 +19,6 @@ fn main() -> UnitResult { // run_im_rc(); // run_num(); run_rand_family()?; - run_sfmt()?; run_regex()?; Ok(()) } @@ -405,23 +404,6 @@ 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 { const ITERATIONS: usize = 10000; From 879e99efca09ce12f840bac1ab86e3a09df25d22 Mon Sep 17 00:00:00 2001 From: statiolake Date: Tue, 6 Aug 2019 21:22:15 +0900 Subject: [PATCH 2/6] Remove im --- Cargo.toml | 3 +-- src/main.rs | 2 -- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 8ef4ecf..13c9809 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -55,8 +55,7 @@ arrayvec = "=0.4.10" # 標準ライブラリのVecやHashMapに対応する永続データ構造 # 永続データ構造は関数型言語によく見られるデータ構造で、要素を更新しても、そのデータ構造の # 以前のバージョンにアクセスできる。(更新の度に差分が記録されていくイメージ) -im = "=13.0.0" # スレッドセーフ -im-rc = "=13.0.0" # スレッドセーフでないが高速 +im-rc = "=13.0.0" # 多バイト長整数、分数、複素数など num = "=0.2.0" diff --git a/src/main.rs b/src/main.rs index b17f302..88cee8a 100644 --- a/src/main.rs +++ b/src/main.rs @@ -15,7 +15,6 @@ fn main() -> UnitResult { run_hashbrown(); // run_smallvec(); // run_arrayvec(); - // run_im(); // run_im_rc(); // run_num(); run_rand_family()?; @@ -370,7 +369,6 @@ fn test_hashbrown() { // smallvec // arrayvec -// im // im-rc // num From b245c2e5a19eb75e9802e3b7b92417651a9c3690 Mon Sep 17 00:00:00 2001 From: statiolake Date: Tue, 6 Aug 2019 21:27:48 +0900 Subject: [PATCH 3/6] Remove once-cell --- Cargo.toml | 1 - 1 file changed, 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 13c9809..7ca9f83 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -70,7 +70,6 @@ regex = "=1.1.7" # staticアイテムの遅延初期化 lazy_static = "=1.3.0" -once_cell = "=0.2.1" # 代替ヒープアロケータ。条件によってはシステムアロケータより速いことも jemallocator = "=0.3.2" From ceafaa656804f2f1c7aa9d03949e71a21b8d906e Mon Sep 17 00:00:00 2001 From: statiolake Date: Tue, 6 Aug 2019 21:35:10 +0900 Subject: [PATCH 4/6] Update ascii, hashbrown, arrayvec, regex --- Cargo.toml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 7ca9f83..dfc43d0 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,11 +46,11 @@ 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に対応する永続データ構造 # 永続データ構造は関数型言語によく見られるデータ構造で、要素を更新しても、そのデータ構造の @@ -66,7 +66,7 @@ rand_chacha = "=0.1.1" rand_pcg = "=0.1.2" # 正規表現 -regex = "=1.1.7" +regex = "=1.2.1" # staticアイテムの遅延初期化 lazy_static = "=1.3.0" From 180417d2dbd86b78a0fd7c8c33761c67e838fe1c Mon Sep 17 00:00:00 2001 From: statiolake Date: Tue, 6 Aug 2019 21:47:38 +0900 Subject: [PATCH 5/6] Update rand to 0.7 Fix some test code accordingly. Note, this includes fix for the test code of bitset-fixed. The test expected the number sequences generated from the same seed is always the same. It seems the rand 0.7 produces different sequence for the seed, so change the result value to fit for rand 0.7. --- Cargo.toml | 6 +++--- src/main.rs | 6 ++++-- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index dfc43d0..e54e3f5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -61,9 +61,9 @@ 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" +rand = { version = "=0.7.0", features = ["small_rng"] } +rand_chacha = "=0.2.1" +rand_pcg = "=0.2.0" # 正規表現 regex = "=1.2.1" diff --git a/src/main.rs b/src/main.rs index 88cee8a..bdedf3e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -246,7 +246,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 @@ -265,7 +265,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] @@ -403,6 +403,8 @@ fn test_rand_family() -> UnitResult { } 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) From 83a60873e1bfb63c9d5500058708078add97175c Mon Sep 17 00:00:00 2001 From: statiolake Date: Thu, 4 Jul 2019 15:38:25 +0900 Subject: [PATCH 6/6] Test both OnceSource and LineSource instead of AutoSource --- src/main.rs | 47 ++++++++++++++++++++++++++++------------------- 1 file changed, 28 insertions(+), 19 deletions(-) diff --git a/src/main.rs b/src/main.rs index bdedf3e..398a26e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -28,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]