1use std::fmt::{Display, Formatter};
2use std::io::{stdin, stdout, Write};
3use std::num::ParseFloatError;
4use std::str::FromStr;
5
6use thiserror::Error;
7
8use expressions::eval;
9use expressions::eval::Eval;
10
11#[derive(Debug, Clone, Copy, PartialEq)]
13pub struct Complex {
14 pub real: f64,
15 pub imag: f64,
16}
17
18impl Complex {
19 pub fn new(real: f64, imag: f64) -> Self {
21 Self { real, imag }
22 }
23}
24
25impl Display for Complex {
26 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
27 match (self.real != 0., self.imag != 0.) {
28 (true, true) => f.write_str(&format!(
29 "{} {} {}i",
30 self.real,
31 if self.imag.is_sign_positive() {
32 '+'
33 } else {
34 '-'
35 },
36 self.imag.abs()
37 )),
38 (true, false) => f.write_str(&format!("{}", self.real)),
39 (false, true) => f.write_str(&format!("{}i", self.imag)),
40 (false, false) => f.write_str("0"),
41 }
42 }
43}
44
45#[derive(Error, Debug, PartialEq)]
47pub enum ComplexEvalErr {
48 #[error("use of unsupported operator")]
50 OperatorNotSupported,
51}
52
53impl Eval for Complex {
56 type ErrEval = ComplexEvalErr;
57
58 fn eq(self, other: Self) -> Result<Self, Self::ErrEval> {
59 match self == other {
60 true => Ok(Self::new(1., 0.)),
61 false => Ok(Self::new(0., 0.)),
62 }
63 }
64
65 fn neq(self, other: Self) -> Result<Self, Self::ErrEval> {
66 match self != other {
67 true => Ok(Self::new(1., 0.)),
68 false => Ok(Self::new(0., 0.)),
69 }
70 }
71
72 fn gte(self, _other: Self) -> Result<Self, Self::ErrEval> {
73 Err(ComplexEvalErr::OperatorNotSupported)
74 }
75
76 fn gt(self, _other: Self) -> Result<Self, Self::ErrEval> {
77 Err(ComplexEvalErr::OperatorNotSupported)
78 }
79
80 fn lte(self, _other: Self) -> Result<Self, Self::ErrEval> {
81 Err(ComplexEvalErr::OperatorNotSupported)
82 }
83
84 fn lt(self, _other: Self) -> Result<Self, Self::ErrEval> {
85 Err(ComplexEvalErr::OperatorNotSupported)
86 }
87
88 fn and(self, _other: Self) -> Result<Self, Self::ErrEval> {
89 Err(ComplexEvalErr::OperatorNotSupported)
90 }
91
92 fn or(self, _other: Self) -> Result<Self, Self::ErrEval> {
93 Err(ComplexEvalErr::OperatorNotSupported)
94 }
95
96 fn bit_and(self, _other: Self) -> Result<Self, Self::ErrEval> {
97 Err(ComplexEvalErr::OperatorNotSupported)
98 }
99
100 fn bit_or(self, _other: Self) -> Result<Self, Self::ErrEval> {
101 Err(ComplexEvalErr::OperatorNotSupported)
102 }
103
104 fn add(self, other: Self) -> Result<Self, Self::ErrEval> {
105 Ok(Self {
106 real: self.real + other.real,
107 imag: self.imag + other.imag,
108 })
109 }
110
111 fn sub(self, other: Self) -> Result<Self, Self::ErrEval> {
112 Ok(Self {
113 real: self.real - other.real,
114 imag: self.imag - other.imag,
115 })
116 }
117
118 fn mul(self, other: Self) -> Result<Self, Self::ErrEval> {
119 Ok(Self {
120 real: self.real * other.real - self.imag * other.imag,
121 imag: self.real * other.imag * 2.,
122 })
123 }
124
125 fn div(self, other: Self) -> Result<Self, Self::ErrEval> {
126 let divisor = other.real * other.real + other.imag * other.imag;
127 Ok(Self {
128 real: (self.real * other.real + self.imag * other.imag) / divisor,
129 imag: (self.imag * other.real - self.real * other.imag) / divisor,
130 })
131 }
132
133 fn rem(self, _: Self) -> Result<Self, Self::ErrEval> {
134 Err(ComplexEvalErr::OperatorNotSupported)
135 }
136
137 fn exp(self, _: Self) -> Result<Self, Self::ErrEval> {
138 Err(ComplexEvalErr::OperatorNotSupported)
139 }
140
141 fn plus(self) -> Result<Self, Self::ErrEval> {
142 Ok(self)
143 }
144
145 fn minus(self) -> Result<Self, Self::ErrEval> {
146 Ok(Self {
147 real: -self.real,
148 imag: -self.imag,
149 })
150 }
151
152 fn not(self) -> Result<Self, Self::ErrEval> {
153 Err(ComplexEvalErr::OperatorNotSupported)
154 }
155
156 fn bit_not(self) -> Result<Self, Self::ErrEval> {
157 Err(ComplexEvalErr::OperatorNotSupported)
158 }
159}
160
161#[derive(Error, Debug, PartialEq)]
163pub enum ComplexParseErr {
164 #[error("{0}")]
166 ParseFloatErr(#[from] ParseFloatError),
167}
168
169impl FromStr for Complex {
172 type Err = ComplexParseErr;
173
174 fn from_str(s: &str) -> Result<Self, Self::Err> {
177 let (substr, is_imag) = if s.chars().last().map_or(false, |v| v == 'i') {
179 (&s[0..(s.len() - 1)], true)
180 } else {
181 (s, false)
182 };
183
184 let magnitude = substr.parse()?;
185 Ok(Self {
186 real: if !is_imag { magnitude } else { 0. },
187 imag: if is_imag { magnitude } else { 0. },
188 })
189 }
190}
191
192#[test]
193fn test_complex() {
194 assert_eq!(
195 eval::<Complex>("-1i + 23 - 394"),
196 Ok(Complex::new(-371., -1.))
197 );
198 assert_eq!(
199 eval::<Complex>("-1i + 23 + (2i - --1i)"),
200 Ok(Complex::new(23., 0.))
201 );
202 assert_eq!(
203 eval::<Complex>("(-1i + 23 + 2i - --1i) * (1 - 3i) * (5i)"),
204 Ok(Complex::new(690., 230.))
205 );
206 assert_eq!(eval::<Complex>("10 * 10"), Ok(Complex::new(100., 0.)),);
207 assert_eq!(eval::<Complex>("10i * 10i"), Ok(Complex::new(-100., 0.)),);
208 assert_eq!(
209 eval::<Complex>("-1i + 23 - 390 / 39"),
210 Ok(Complex::new(13., -1.))
211 );
212 assert_eq!(eval::<Complex>("-1i / 1i"), Ok(Complex::new(-1., 0.)));
213
214 assert!(eval::<Complex>("-1ii").is_err());
215 assert!(eval::<Complex>("i").is_err());
216 assert!(eval::<Complex>("").is_err());
217}
218
219fn main() {
220 let mut buf = String::new();
221 loop {
222 print!("Input: ");
223 stdout().flush().expect("could not flush stdout");
224 stdin()
225 .read_line(&mut buf)
226 .expect("could not read from stdin: ");
227
228 match eval::<Complex>(&buf) {
229 Ok(val) => println!("Result: {}", val),
230 Err(err) => eprintln!("Error: {}", err),
231 };
232 buf.clear();
233 }
234}