use crate::lab_trait::Lab; use eframe::egui; use std::collections::HashSet; enum State<'a> { Clean, Done, Error(&'a str), } pub struct Window<'a> { n: u32, q: u32, subgroup: Vec, state: State<'a>, } impl<'a> Default for Window<'a> { fn default() -> Self { Self { n: 6, q: 3, subgroup: Vec::new(), state: State::Clean, } } } impl<'a> Lab for Window<'a> { fn get_name(&self) -> &str { "Задача №6" } fn update(&mut self, ui: &mut egui::Ui) { ui.horizontal(|ui| { ui.label("Число n: "); if ui.add(egui::DragValue::new(&mut self.n).clamp_range(2..=u32::MAX)).changed() { self.state = State::Clean; self.subgroup.clear(); } }); ui.horizontal(|ui| { ui.label("Число q: "); if ui.add(egui::DragValue::new(&mut self.q).clamp_range(1..=self.n)).changed() { self.state = State::Clean; self.subgroup.clear(); } }); if ui.button("Вычислить подгруппу").clicked() { if self.n % self.q != 0 { self.state = State::Error("q не является делителем n"); } else { self.subgroup = calculate_subgroup(self.n, self.q); self.state = State::Done; } } match self.state { State::Clean => {}, State::Done => { ui.label(format!("Вычисленная подгруппа: {:?}", self.subgroup)); }, State::Error(msg) => { ui.label(msg); }, } } } fn powmod(x: u32, n: u32, m: u32) -> u32 { let mut res = 0; for _ in 0..n { res = (res + x) % m; } return res; } fn calculate_subgroup(n: u32, q: u32) -> Vec { for i in 0..n { let mut group = HashSet::new(); group.insert(i); for p in 2..=n { let power = powmod(i, p, n); group.insert(power); } if group.len() == q as usize { let mut vec = group.drain().collect::>(); vec.sort(); return vec; } } return Vec::new(); }