diff options
Diffstat (limited to 'labs/src/lab6.rs')
| -rw-r--r-- | labs/src/lab6.rs | 114 |
1 files changed, 114 insertions, 0 deletions
diff --git a/labs/src/lab6.rs b/labs/src/lab6.rs new file mode 100644 index 0000000..9061da7 --- /dev/null +++ b/labs/src/lab6.rs @@ -0,0 +1,114 @@ +use crate::lab_trait::Lab; +use eframe::egui; +use std::collections::HashSet; +use std::collections::HashMap; + +enum State<'a> { + Clean, + Done1, + Done2, + Error(&'a str), +} + +pub struct Window<'a> { + n: u32, + q: u32, + subgroup: Vec<u32>, + subgroups: HashMap<u32, Vec<u32>>, + state: State<'a>, +} + +impl<'a> Default for Window<'a> { + fn default() -> Self { + Self { + n: 6, + q: 3, + subgroup: Vec::new(), + subgroups: HashMap::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("Порядок группы Z_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() { + self.subgroups.clear(); + if self.n % self.q != 0 { + self.state = State::Error("q не является делителем n"); + } + else { + self.subgroups = calculate_subgroups(self.n); + for (_, sg) in &self.subgroups { + if sg.len() == self.q as usize { + self.subgroup = sg.clone(); + break; + } + } + self.state = State::Done1; + } + } + if ui.button("Вычислить все подгруппы").clicked() { + self.subgroups.clear(); + if self.n % self.q != 0 { + self.state = State::Error("q не является делителем n"); + } + else { + self.subgroups = calculate_subgroups(self.n); + self.state = State::Done2; + } + } + match self.state { + State::Clean => {}, + State::Done1 => { + ui.label(format!("Вычисленная подгруппа: {:?}", self.subgroup)); + }, + State::Done2 => { + for (gen, set) in self.subgroups.iter() { + ui.label(format!("Подгруппа {:?} с генератором {}", set, gen)); + } + }, + 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_subgroups(n: u32) -> HashMap<u32, Vec<u32>> { + let mut subgroups = HashMap::new(); + 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); + } + let mut vec = group.drain().collect::<Vec<u32>>(); + vec.sort(); + subgroups.insert(i as u32, vec); + } + return subgroups; +} |