1use crate::common::*;
2
3pub trait PermProduct<Rhs> {
5 type Output;
6
7 fn perm_product(&self, other: &Rhs) -> Self::Output;
8}
9
10mod without_std {
11 use super::*;
12 use crate::perm_type::PermS;
13
14 impl<const SIZE: usize> PermProduct<PermS<SIZE>> for PermS<SIZE> {
15 type Output = PermS<SIZE>;
16
17 fn perm_product(&self, other: &PermS<SIZE>) -> Self::Output {
18 let mut indices = [0; SIZE];
19 product(&self.indices, &other.indices, &mut indices);
20 Self { indices }
21 }
22 }
23
24 impl<const SIZE: usize> Mul<&PermS<SIZE>> for &PermS<SIZE> {
25 type Output = PermS<SIZE>;
26
27 fn mul(self, other: &PermS<SIZE>) -> Self::Output {
28 self.perm_product(other)
29 }
30 }
31
32 impl<'a, const SIZE: usize> Product<&'a PermS<SIZE>> for PermS<SIZE> {
33 fn product<I>(iter: I) -> Self
34 where
35 I: Iterator<Item = &'a PermS<SIZE>>,
36 {
37 iter.fold(Self::identity(), |product, item| product.mul(item))
38 }
39 }
40
41 impl<const SIZE: usize> Product<PermS<SIZE>> for PermS<SIZE> {
42 fn product<I>(iter: I) -> Self
43 where
44 I: Iterator<Item = PermS<SIZE>>,
45 {
46 iter.fold(Self::identity(), |product, item| product.mul(&item))
47 }
48 }
49}
50
51#[cfg(feature = "std")]
52mod with_std {
53 use super::*;
54 use crate::{
55 perm_trait::Permutation,
56 perm_type::{PermD, PermS},
57 };
58
59 impl<const SIZE: usize> PermProduct<PermD> for PermS<SIZE> {
60 type Output = Option<PermS<SIZE>>;
61
62 fn perm_product(&self, other: &PermD) -> Self::Output {
63 if other.len() != SIZE {
64 return None;
65 }
66 let mut indices = [0; SIZE];
67 product(&self.indices, &other.indices, &mut indices);
68 Some(Self { indices })
69 }
70 }
71
72 impl<const SIZE: usize> PermProduct<PermS<SIZE>> for PermD {
73 type Output = Option<PermS<SIZE>>;
74
75 fn perm_product(&self, other: &PermS<SIZE>) -> Self::Output {
76 if self.len() != SIZE {
77 return None;
78 }
79 let mut indices = [0; SIZE];
80 product(&self.indices, &other.indices, &mut indices);
81 Some(PermS { indices })
82 }
83 }
84
85 impl PermProduct<PermD> for PermD {
86 type Output = Option<PermD>;
87
88 fn perm_product(&self, other: &PermD) -> Self::Output {
89 if self.len() != other.len() {
90 return None;
91 }
92 let mut indices = vec![0; self.len()];
93 product(&self.indices, &other.indices, &mut indices);
94 Some(Self { indices })
95 }
96 }
97
98 impl<const SIZE: usize> Mul<&PermD> for &PermS<SIZE> {
99 type Output = PermS<SIZE>;
100
101 fn mul(self, other: &PermD) -> Self::Output {
102 self.perm_product(other).unwrap()
103 }
104 }
105
106 impl<const SIZE: usize> Mul<&PermS<SIZE>> for &PermD {
107 type Output = PermS<SIZE>;
108
109 fn mul(self, other: &PermS<SIZE>) -> Self::Output {
110 self.perm_product(other).unwrap()
111 }
112 }
113
114 impl Mul<&PermD> for &PermD {
115 type Output = PermD;
116
117 fn mul(self, other: &PermD) -> Self::Output {
118 self.perm_product(other).unwrap()
119 }
120 }
121
122 impl<'a, const SIZE: usize> Product<&'a PermD> for Option<PermS<SIZE>> {
123 fn product<I>(mut iter: I) -> Self
124 where
125 I: Iterator<Item = &'a PermD>,
126 {
127 iter.try_fold(PermS::<SIZE>::identity(), |product, item| -> Option<_> {
128 product.perm_product(item)
129 })
130 }
131 }
132
133 impl<const SIZE: usize> Product<PermD> for Option<PermS<SIZE>> {
134 fn product<I>(mut iter: I) -> Self
135 where
136 I: Iterator<Item = PermD>,
137 {
138 iter.try_fold(PermS::<SIZE>::identity(), |product, item| -> Option<_> {
139 product.perm_product(&item)
140 })
141 }
142 }
143
144 impl<'a, const SIZE: usize> Product<&'a PermS<SIZE>> for PermD {
145 fn product<I>(iter: I) -> Self
146 where
147 I: Iterator<Item = &'a PermS<SIZE>>,
148 {
149 iter.fold(PermS::<SIZE>::identity(), |product, item| product.mul(item))
150 .into_dynamic()
151 }
152 }
153
154 impl<const SIZE: usize> Product<PermS<SIZE>> for PermD {
155 fn product<I>(iter: I) -> Self
156 where
157 I: Iterator<Item = PermS<SIZE>>,
158 {
159 iter.fold(PermS::<SIZE>::identity(), |product, item| {
160 product.mul(&item)
161 })
162 .into_dynamic()
163 }
164 }
165
166 impl<'a> Product<&'a PermD> for Option<PermD> {
167 fn product<I>(mut iter: I) -> Self
168 where
169 I: Iterator<Item = &'a PermD>,
170 {
171 let first = iter.next()?.to_owned();
172 iter.try_fold(first, |product, item| -> Option<_> {
173 product.perm_product(item)
174 })
175 }
176 }
177
178 impl Product<PermD> for Option<PermD> {
179 fn product<I>(mut iter: I) -> Self
180 where
181 I: Iterator<Item = PermD>,
182 {
183 let first = iter.next()?;
184 iter.try_fold(first, |product, item| -> Option<_> {
185 product.perm_product(&item)
186 })
187 }
188 }
189}
190
191fn product(lhs: &[usize], rhs: &[usize], output: &mut [usize]) {
192 let len = output.len();
193 (0..len).for_each(|src| {
194 let dst = lhs[rhs[src]];
195 output[src] = dst;
196 });
197}