1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
pub mod term;
use self::term::Term;
use self::term::degree::Degree;
use ::fmt;
use ::str;
use ::vec;
use ::ops::{Not, Neg, Add, Rem};
use ::num;
use ::array;
use ::iter;
use itertools::Itertools;
use num2::Zero;
#[derive(Debug, Clone, PartialEq)]
pub struct Order(pub Vec<Term>);
impl Order {
fn new(it: Vec<Term>) -> Self {
Order(it.into_iter()
.sorted()
.into_iter()
.group_by(|elt: &Term| match elt {
&Term::Determinate(_) => false,
&Term::Indeterminate(_, Degree(power)) => power.rem(2).eq(&1),
})
.into_iter()
.map(|(_, group): (bool, ::itertools::Group<bool, vec::IntoIter<Term>, _>)| group.fold(Term::default(), |acc, term| term.add(acc)))
.filter(|term| term.is_zero().not())
.collect::<Vec<Term>>())
}
}
impl str::FromStr for Order {
type Err = num::ParseIntError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
let line = s.replace(" ", "").replace("*", "").replace("-", "+-");
if let Some(position) = line.find('=') {
let (left, rright): (&str, &str) = line.split_at(position);
let (_, right): (&str, &str) = rright.split_at(1);
Ok(Order::new(left.split("+")
.filter_map(|term| Term::from_str(term).ok())
.chain(right.split("+")
.filter_map(|term| Term::from_str(term).ok())
.map(|term| term.neg()))
.collect::<Vec<Term>>()))
} else {
Ok(Order::new(line.split("+")
.filter_map(|term| Term::from_str(term).ok())
.collect::<Vec<Term>>()))
}
}
}
impl Default for Order {
fn default() -> Self {
Order(Vec::new())
}
}
impl Iterator for Order {
type Item = Term;
fn next(&mut self) -> Option<Term> {
None
}
}
impl iter::ExactSizeIterator for Order {
fn len(&self) -> usize {
self.0.len()
}
fn is_empty(&self) -> bool {
self.0.is_empty()
}
}
unsafe impl array::FixedSizeArray<Term> for Order {
fn as_slice(&self) -> &[Term] {
self.0.as_slice()
}
fn as_mut_slice(&mut self) -> &mut [Term] {
self.0.as_mut_slice()
}
}
impl fmt::Display for Order {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
if self.0.is_empty() {
write!(f, "0 = 0")
} else if self.0.len().eq(&1) {
write!(f, "{} != 0", self.0.first().unwrap_or(&Term::default()))
} else {
write!(f, "{} = 0", self.0.iter()
.map(|term| format!("{}", term))
.collect::<Vec<String>>()
.join(" + ")
.replace("+ -", "- "))
}
}
}