見出し画像

【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
#はるまきチャンネル

この記事が気に入ったらサポートをしてみませんか?