feat: finish p21. Implment mt19937.
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -1 +1,2 @@
|
|||||||
/target
|
/target
|
||||||
|
site
|
||||||
|
|||||||
6
problems/p21/Cargo.toml
Normal file
6
problems/p21/Cargo.toml
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
[package]
|
||||||
|
name = "p21"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2024"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
8
problems/p21/src/main.cpp
Normal file
8
problems/p21/src/main.cpp
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
#include <iostream>
|
||||||
|
#include <random>
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
std::mt19937 gen(12345);
|
||||||
|
std::cout << gen() << std::endl; // 第一个输出
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
93
problems/p21/src/main.rs
Normal file
93
problems/p21/src/main.rs
Normal file
@@ -0,0 +1,93 @@
|
|||||||
|
// //創建一個長度為624的數組來存儲發生器的狀態
|
||||||
|
// int[0..623] MT
|
||||||
|
// int index = 0
|
||||||
|
//
|
||||||
|
// //初始化產生器,種子作為首項內容
|
||||||
|
// function initialize_generator(int seed) {
|
||||||
|
// i := 0
|
||||||
|
// MT[0] := seed
|
||||||
|
// for i from 1 to 623 { // 走訪剩下的每個元素
|
||||||
|
// MT[i] := last 32 bits of(1812433253 * (MT[i-1] xor (right shift by 30 bits(MT[i-1]))) + i) // 1812433253 == 0x6c078965
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// // Extract a tempered pseudorandom number based on the index-th value,
|
||||||
|
// // calling generate_numbers() every 624 numbers
|
||||||
|
// function extract_number() {
|
||||||
|
// if index == 0 {
|
||||||
|
// generate_numbers()
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// int y := MT[index]
|
||||||
|
// y := y xor (right shift by 11 bits(y))
|
||||||
|
// y := y xor (left shift by 7 bits(y) and (2636928640)) // 2636928640 == 0x9d2c5680
|
||||||
|
// y := y xor (left shift by 15 bits(y) and (4022730752)) // 4022730752 == 0xefc60000
|
||||||
|
// y := y xor (right shift by 18 bits(y))
|
||||||
|
//
|
||||||
|
// index := (index + 1) mod 624
|
||||||
|
// return y
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// // Generate an array of 624 untempered numbers
|
||||||
|
// function generate_numbers() {
|
||||||
|
// for i from 0 to 623 {
|
||||||
|
// int y := (MT[i] & 0x80000000) // bit 31 (32nd bit) of MT[i]
|
||||||
|
// + (MT[(i+1) mod 624] & 0x7fffffff) // bits 0-30 (first 31 bits) of MT[...]
|
||||||
|
// MT[i] := MT[(i + 397) mod 624] xor (right shift by 1 bit(y))
|
||||||
|
// if (y mod 2) != 0 { // y is odd
|
||||||
|
// MT[i] := MT[i] xor (2567483615) // 2567483615 == 0x9908b0df
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
struct MT19937 {
|
||||||
|
mt: [u32; 624],
|
||||||
|
index: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl MT19937 {
|
||||||
|
fn new(seed: u32) -> Self {
|
||||||
|
let mut mt = [0; 624];
|
||||||
|
mt[0] = seed;
|
||||||
|
for i in 1..624 {
|
||||||
|
mt[i] = 0x6c078965u32
|
||||||
|
.wrapping_mul(mt[i - 1] ^ (mt[i - 1] >> 30))
|
||||||
|
.wrapping_add(i as u32)
|
||||||
|
}
|
||||||
|
let index = 0;
|
||||||
|
MT19937 { mt, index }
|
||||||
|
}
|
||||||
|
|
||||||
|
fn extract_number(&mut self) -> u32 {
|
||||||
|
if self.index == 0 {
|
||||||
|
self.generate_numbers();
|
||||||
|
}
|
||||||
|
let mut result = self.mt[self.index];
|
||||||
|
|
||||||
|
result ^= result >> 11;
|
||||||
|
result ^= (result << 7) & 0x9d2c5680;
|
||||||
|
result ^= (result << 15) & 0xefc60000;
|
||||||
|
result ^= result >> 18;
|
||||||
|
self.index = (self.index + 1) % 624;
|
||||||
|
|
||||||
|
result
|
||||||
|
}
|
||||||
|
|
||||||
|
fn generate_numbers(&mut self) {
|
||||||
|
for i in 0..624 {
|
||||||
|
let y: u32 = (self.mt[i] & 0x80000000) + (self.mt[(i + 1) % 624] & 0x7fffffff);
|
||||||
|
self.mt[i] = self.mt[(i + 397) % 624] ^ (y >> 1);
|
||||||
|
if y % 2 != 0 {
|
||||||
|
self.mt[i] ^= 0x9908b0df;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
// use C++ std::mt19937 to verify.
|
||||||
|
let mut mt19937 = MT19937::new(12345);
|
||||||
|
let result = mt19937.extract_number();
|
||||||
|
|
||||||
|
println!("{result}");
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user