diff options
Diffstat (limited to 'src/lab1.rs')
| -rw-r--r-- | src/lab1.rs | 134 |
1 files changed, 134 insertions, 0 deletions
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<bool>, + primitive_roots: Vec<u32>, + 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; +} + |