summaryrefslogtreecommitdiff
path: root/labs/src/lab6.rs
diff options
context:
space:
mode:
authorAndrew Guschin <guschin.drew@gmail.com>2022-11-13 11:40:34 +0400
committerAndrew Guschin <guschin.drew@gmail.com>2022-11-13 11:40:34 +0400
commit9bbc7b8c31458fbf8c639794531e3d324004d8d5 (patch)
tree7d6128c58518c78da03652e9f4e974e6de5a927f /labs/src/lab6.rs
parent14fefa99fae1433de08812558c07a0f81c40ab04 (diff)
Реализации лабораторных перенесены во отдельную папку
Diffstat (limited to 'labs/src/lab6.rs')
-rw-r--r--labs/src/lab6.rs114
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;
+}