summaryrefslogtreecommitdiff
path: root/src/lab3.rs
diff options
context:
space:
mode:
authorAndrew Guschin <guschin.drew@gmail.com>2022-11-13 11:40:34 +0400
committerAndrew Guschin <guschin.drew@gmail.com>2022-11-13 11:40:34 +0400
commit9bbc7b8c31458fbf8c639794531e3d324004d8d5 (patch)
tree7d6128c58518c78da03652e9f4e974e6de5a927f /src/lab3.rs
parent14fefa99fae1433de08812558c07a0f81c40ab04 (diff)
Реализации лабораторных перенесены во отдельную папку
Diffstat (limited to 'src/lab3.rs')
-rw-r--r--src/lab3.rs128
1 files changed, 0 insertions, 128 deletions
diff --git a/src/lab3.rs b/src/lab3.rs
deleted file mode 100644
index 7f8edf5..0000000
--- a/src/lab3.rs
+++ /dev/null
@@ -1,128 +0,0 @@
-use crate::lab_trait::Lab;
-use eframe::egui;
-use rug::{Complete, Integer};
-
-enum State {
- Clean,
- Done,
- Error,
-}
-
-pub struct Window {
- str_num: String,
- factors: Vec<Integer>,
- state: State,
-}
-
-impl Default for Window {
- fn default() -> Self {
- Self {
- str_num: String::from("21894583143407671"),
- factors: Vec::new(),
- state: State::Clean,
- }
- }
-}
-
-impl Lab for Window {
- fn get_name(&self) -> &str { "Задача №3" }
-
- fn update(&mut self, ui: &mut egui::Ui) {
- ui.horizontal(|ui| {
- ui.label("Число: ");
- let field = ui.add(egui::TextEdit::singleline(&mut self.str_num));
- if field.changed() {
- self.state = State::Clean;
- self.factors.clear();
- }
- });
- if ui.button("Разложить на множители").clicked() {
- self.factors.clear();
- match Integer::parse(&self.str_num) {
- Ok(number) => {
- self.factors.append(&mut factorize(&number.complete()));
- self.state = State::Done;
- },
- Err(_) => self.state = State::Error,
- };
- }
- if let State::Done = self.state {
- if self.factors.len() == 1 {
- ui.label(format!("Число является простым"));
- }
- else {
- ui.label(format!("Множители: {:?}", self.factors));
- }
- }
- if let State::Error = self.state {
- ui.label("В числе имеются недопустимые символы");
- }
- }
-}
-
-fn factorize(n: &Integer) -> Vec<Integer> {
- let mut factors = Vec::new();
- let mut front = vec![n.clone()];
-
- while !front.is_empty() {
- let num = front.pop().unwrap();
- match lehman(&num) {
- Some(factor) => {
- let other = num.div_exact_ref(&factor).complete();
- front.push(factor);
- front.push(other);
- },
- None => factors.push(num)
- };
- }
-
- return factors;
-}
-
-fn lehman(n: &Integer) -> Option<Integer> {
- let one = &Integer::from(1u32);
- let mut a = Integer::from(2u32);
- let root3 = n.root_ref(3).complete();
-
- while a <= root3 {
- let (_, r) = n.div_rem_ref(&a).complete();
- if r == 0 {
- return Some(a);
- }
- a += one;
- }
-
- let root6 = n.root_ref(6).complete();
- let mut k = Integer::from(1u32);
- while k <= root3 {
- let mut d = Integer::ZERO;
- let sqrtk4 = k.sqrt_ref().complete() * 4;
- let (r6sk4, _) = root6.div_rem_ref(&sqrtk4).complete();
- while d <= (&r6sk4 + one).complete() {
- let kn4: Integer = k.clone() * n.clone() * 4;
- let sqrt_kn4 = kn4.sqrt_ref().complete();
-
- let number = (sqrt_kn4.clone() + d.clone()).square() - kn4.clone();
- if number.is_perfect_square() {
- let big_a = sqrt_kn4 + d.clone();
- let big_b = (big_a.square_ref() - kn4).sqrt();
-
- let gcd1 = (big_a.clone() + big_b.clone()).gcd_ref(n).complete();
- let gcd2 = (big_a.clone() - big_b.clone()).gcd_ref(n).complete();
-
- if &gcd1 > one && &gcd1 < n {
- return Some(gcd1);
- }
- else if &gcd2 > one && &gcd2 < n {
- return Some(gcd2);
- }
- }
-
- d += one;
- }
- k += one;
- }
-
- return None;
-}
-