From 62f1fb7b8c748a8d57ef073980911cb7a0252b68 Mon Sep 17 00:00:00 2001 From: Andrew Guschin Date: Mon, 26 Sep 2022 03:50:55 +0400 Subject: =?UTF-8?q?=D0=A0=D0=B5=D1=84=D0=B0=D0=BA=D1=82=D0=BE=D1=80=D0=B8?= =?UTF-8?q?=D0=BD=D0=B3=20=D0=BF=D1=80=D0=B8=D0=BB=D0=BE=D0=B6=D0=B5=D0=BD?= =?UTF-8?q?=D0=B8=D1=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/lab1.rs | 134 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 134 insertions(+) create mode 100644 src/lab1.rs (limited to 'src/lab1.rs') diff --git a/src/lab1.rs b/src/lab1.rs new file mode 100644 index 0000000..b442199 --- /dev/null +++ b/src/lab1.rs @@ -0,0 +1,134 @@ +use crate::lab_trait::Lab; +use eframe::egui; + +pub struct Window { + order: u32, + element: u32, + element_check: Option, + primitive_roots: Vec, + state: State, +} + +impl Window { + fn clear_state(&mut self) { + self.element_check = None; + self.state = State::Idle; + } +} + +impl Default for Window { + fn default() -> Self { + Self { + order: 29, + element: 2, + element_check: None, + primitive_roots: Vec::new(), + state: State::Idle, + } + } +} + +impl Lab for Window { + fn get_name(&self) -> &str { "Задача №1" } + + fn update(&mut self, ui: &mut egui::Ui) { + ui.horizontal(|ui| { + ui.label("Порядок поля: "); + if ui + .add(egui::DragValue::new(&mut self.order).clamp_range(2..=u32::MAX)) + .changed() + { + self.clear_state(); + } + }); + ui.horizontal(|ui| { + ui.label("Проверяемый элемент: "); + if ui + .add(egui::DragValue::new(&mut self.element).clamp_range(1..=self.order - 1)) + .changed() + { + self.clear_state(); + } + }); + + 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("Можно указать только простое число!"); + } + } + } +} + +enum State { + Idle, + Running(u32), + Done, + Error, +} + +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; + } + 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; +} + -- cgit v1.2.3