【RUST】記念日判定⑦【はるまき@エンジニアカップル】
0.はじめに
記念日には何か意味を持たせたいですよね.
そこで理系的に意味のある素数の日にしたいと思いました.
★★★★★ 過去の投稿一覧 ★★★★★
1.素数探索プログラム
本日の日付から365日分の日付に対して
素数かどうかの判定を行っていきます.
use rand::Rng; // 乱数発生モジュール
use mod_exp::mod_exp; // べき乗余モジュール
use chrono::{Date, Local, Duration}; // 日付モジュール
use std::time::{Instant, };
use std::io::{Write, };
use std::fs;
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
// main 関数
//
fn main() {
println!("===================================");
println!("Prime number detect!");
// **********************************
// main init param
//
let log_name = "log.txt";
let log_cols = String::from(format!("ID, date, elapsed_time, flag\n"));
let day_max:i64 = 365;
// **********************************
// log file 作成
//
let mut file = fs::File::create(log_name).unwrap();
file.write_all(log_cols.as_bytes()).unwrap();
// 全体の時間計測開始
let total_start = Instant::now();
// **********************************
// day_max 日分先の日付に対して フェルマーテストを行う
//
for iday in 1..day_max{
// 1日の時間計測開始
let start = Instant::now();
// 日付情報取得 & 日付計算
let target_dt: Date<Local> = Local::today() + Duration::days(iday);
// int に変換
let target_number:u64 = target_dt.format("%Y%m%d").to_string().parse().unwrap();
// println!("target_number: {}", target_number);
// 素数の判定
let prime_flag = is_prime(target_number);
// 判定結果により表示を変える
if prime_flag{
println!("[OK] {} is `prime number`", target_number); // 別の関数
}else{
// println!("[NG] {} is not `prime number`......", target_number); // 別の関数
}
// 1日の時間計測終了
let end = start.elapsed();
// println!("elapsed time : {:5}ms, {:5}us", end.subsec_nanos() / 1_000_000, end.subsec_nanos() / 1_000);
// log に書き込む
let write_line = String::from(format!("{}, {}, {}, {}\n", iday, target_number, end.subsec_nanos() / 1_000, prime_flag));
file.write_all(write_line.as_bytes()).unwrap();
}
println!("===============================");
// 全体の時間計測終了
let total_end = total_start.elapsed();
println!("total_elapsed time : {:5}ms", total_end.subsec_nanos() / 1_000_000);
// println!("total_elapsed time : {:5}s", total_end.as_secs(), );
}
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
// 素数判定 関数
//
fn is_prime(number:u64) -> bool {
// **********************************
// init param
//
// フェルマーテストの試行回数
let i_max:u8 = 100;
// **********************************
// 例外処理
//
// 下記の数字は素数判定しない
if number == 1 {
println!("number is 1");
return false;
}
if number == 2 {
println!("number is 2");
return true;
}
// **********************************
// i_max回 フェルマーテストを行う
//
for _ in 1..i_max{
// ________________________
// a をランダムに選定 : aを, 2からn−1までの数からランダムに選ぶ
let a = rand::thread_rng().gen_range(2, number - 1);
// ________________________
// ユークリッドの互除法 : aがnと互いに素でなければ, nは合成数
let gcd_a:u64 = gcd(number, a);
if gcd_a != 1 {
// 合成数のためNG
return false;
}
// ________________________
// a^(p-1) is not (mod p)
let ap_1 = mod_exp(a, number-1, number);;
if ap_1 != 1 {
// 合成数のためNG
return false;
}
}
// **********************************
// ここまで来ればフェルマーテストクリア
// おそらく素数である
//
true
}
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
// ユークリッドの互除法 関数
//
fn gcd(number:u64, a0:u64) -> u64{
let (mut _a, mut _b) = (number, a0);
let (mut a, mut b) = (number, a0);
while b > 0{
_a = b;
_b = a % b;
a = _a;
b = _b;
}
return _a
}
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
// ref : 参考サイト
//
// https://docs.rs/modpow/latest/modpow/fn.modpow.html
//
// https://qiita.com/srtk86/items/609737d50c9ef5f5dc59
//
// https://docs.rs/mod_exp/latest/mod_exp/fn.mod_exp.html
3.実行方法と結果
root@b9e9353c2d11:/home/fermat_sample# cargo run
Compiling fermat_sample v0.1.1 (/home/fermat_sample)
Finished dev [unoptimized + debuginfo] target(s) in 11.39s
Running `target/debug/fermat_sample`
===================================
Prime number detect!
[OK] 20211221 is `prime number`
[OK] 20220103 is `prime number`
[OK] 20220119 is `prime number`
[OK] 20220121 is `prime number`
[OK] 20220127 is `prime number`
[OK] 20220217 is `prime number`
[OK] 20220307 is `prime number`
[OK] 20220311 is `prime number`
[OK] 20220323 is `prime number`
[OK] 20220331 is `prime number`
[OK] 20220407 is `prime number`
[OK] 20220517 is `prime number`
[OK] 20220601 is `prime number`
[OK] 20220619 is `prime number`
[OK] 20220713 is `prime number`
[OK] 20220817 is `prime number`
[OK] 20220821 is `prime number`
[OK] 20220901 is `prime number`
[OK] 20220923 is `prime number`
[OK] 20221009 is `prime number`
[OK] 20221027 is `prime number`
[OK] 20221127 is `prime number`
===============================
total_elapsed time : 165ms
root@b9e9353c2d11:/home/fermat_sample#
思ったよりも少ないですね.
4.おわりに
以上の結果をもとに,入籍日とか自由が利く日付の候補にできたら,理系的にはロマンティックかなと思います.
#プログラム
#プログラミング
#rustプログラミング入門
#rustプログラミング
#RUST
#素数判定
#素数
#数字
#記念日
#特別な日
#きねんび
#エンジニアカップル
#カップル
#harumakich
#はるまきチャンネル