diff options
| author | Andrew Guschin <guschin.drew@gmail.com> | 2022-09-26 03:50:55 +0400 |
|---|---|---|
| committer | Andrew Guschin <guschin.drew@gmail.com> | 2022-09-26 03:50:55 +0400 |
| commit | 62f1fb7b8c748a8d57ef073980911cb7a0252b68 (patch) | |
| tree | a16bc8b53973b83b8f82d85295617bde0fb93848 /src/main.rs | |
| parent | 4a8088e904fe46d842d37d75bacb3ed6092b6e12 (diff) | |
Рефакторинг приложения
Diffstat (limited to 'src/main.rs')
| -rw-r--r-- | src/main.rs | 209 |
1 files changed, 14 insertions, 195 deletions
diff --git a/src/main.rs b/src/main.rs index b8e6eb2..832805f 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,6 +1,9 @@ -use rug::{Complete, Integer}; +mod lab_trait; +mod lab1; +mod lab3; + +use lab_trait::Lab; use eframe::egui; -// use std::time::Instant; fn main() { let options = eframe::NativeOptions::default(); @@ -11,211 +14,27 @@ fn main() { ); } -enum State { - Idle, - Running(u32), - Done, - Error, -} - struct Application { - order: u32, - element: u32, - element_check: Option<bool>, - primitive_roots: Vec<u32>, - state: State, - - str_num: String, + labs: Vec<Box<dyn Lab>>, } impl Default for Application { fn default() -> Self { Self { - order: 29, - element: 2, - element_check: None, - primitive_roots: Vec::new(), - state: State::Idle, - - str_num: String::from("20"), - } - } -} - -fn min_order(x: u32, order: u32) -> u32 { - let mut min = 0; - let mut pow = x; - for power in 1..order { - if pow == 1 { - min = power; - break; + labs: vec![ + Box::new(lab1::Window::default()), + Box::new(lab3::Window::default()), + ], } - pow = (pow * x) % order; } - return min; -} - -fn is_prime(x: u32) -> bool { - if x <= 1 { - return false; - } - for i in 2..x / 2 + 1 { - if x % i == 0 { - return false; - } - } - return true; } impl eframe::App for Application { fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) { - let clear_state = |app: &mut Application| { - app.element_check = None; - app.state = State::Idle; - }; - egui::Window::new("Задача №1").show(ctx, |ui| { - ui.horizontal(|ui| { - ui.label("Порядок поля: "); - if ui - .add(egui::DragValue::new(&mut self.order).clamp_range(2..=u32::MAX)) - .changed() - { - clear_state(self); - } - }); - ui.horizontal(|ui| { - ui.label("Проверяемый элемент: "); - if ui - .add(egui::DragValue::new(&mut self.element).clamp_range(1..=self.order - 1)) - .changed() - { - clear_state(self); - } - }); - - if ui.button("Проверить элемент").clicked() { - let min = min_order(self.element, self.order); - self.element_check = Some(min == self.order - 1); - } - match self.element_check { - Some(true) => { - ui.label("Элемент является порождающим элементом"); - } - Some(false) => { - ui.label("Элемент не является порождающим элементом"); - } - None => {} - } - - if ui.button("Рассчитать порождающие элементы").clicked() { - self.primitive_roots.clear(); - self.state = if is_prime(self.order) { - State::Running(1) - } else { - State::Error - } - } - match self.state { - State::Running(current) => { - ui.label("Вычисление..."); - let min = min_order(current, self.order); - if min == self.order - 1 { - self.primitive_roots.push(current); - } - self.state = if current == self.order - 1 { - State::Done - } else { - State::Running(current + 1) - } - } - State::Done => { - ui.label(format!( - "Порождающие элементы поля F_{}: {:?}", - self.order, self.primitive_roots - )); - } - State::Idle => {} - State::Error => { - ui.label("Можно указать только простое число!"); - } - } - }); - egui::Window::new("Задача №2").show(ctx, |ui| { - ui.horizontal(|ui| { - ui.label("Число: "); - ui.add(egui::TextEdit::singleline(&mut self.str_num)); - }); - if ui.button("Разложить на множители").clicked() { - let number = Integer::parse(&self.str_num).unwrap().complete(); - let factors = factorize(&number); - println!("Множители: {:?}", factors); - } - }); - } -} - -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); + for window in &mut self.labs { + egui::Window::new(window.get_name()) + .show(ctx, |ui| window.update(ui)); } - 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; } + |