summaryrefslogtreecommitdiff
path: root/labs/src/lab1.rs
diff options
context:
space:
mode:
Diffstat (limited to 'labs/src/lab1.rs')
-rw-r--r--labs/src/lab1.rs134
1 files changed, 134 insertions, 0 deletions
diff --git a/labs/src/lab1.rs b/labs/src/lab1.rs
new file mode 100644
index 0000000..b442199
--- /dev/null
+++ b/labs/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;
+}
+