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
use crate::Polynomial;

use num::{One, Zero};
use std::fmt::{Display, Error, Formatter};

pub struct DisplayPolynomial<'a, 'b, T: Display + One + Zero + PartialEq> {
	variable: &'a str,
	polynomial: &'b Polynomial<T>,
}

impl<T: Display + One + Zero + PartialEq> Polynomial<T> {
	pub fn to_display<'a, 'b>(&'b self, variable: &'a str) -> DisplayPolynomial<'a, 'b, T> {
		DisplayPolynomial {
			variable,
			polynomial: self,
		}
	}
}

fn to_superscript(k: &str) -> Result<String, Error> {
	k.chars()
		.map(|x| match x {
			'0' => Ok('⁰'),
			'1' => Ok('¹'),
			'2' => Ok('²'),
			'3' => Ok('³'),
			'4' => Ok('⁴'),
			'5' => Ok('⁵'),
			'6' => Ok('⁶'),
			'7' => Ok('⁷'),
			'8' => Ok('⁸'),
			'9' => Ok('⁹'),
			_ => Err(Error),
		})
		.collect()
}

impl<'a, 'b, T: Display + One + Zero + PartialEq> Display for DisplayPolynomial<'a, 'b, T> {
	fn fmt(&self, f: &mut Formatter) -> std::fmt::Result {
		let mut first = true;
		for (k, v) in self.polynomial.rev_coeffs.iter().enumerate().rev() {
			if v.is_zero() {
				continue;
			}
			if !first {
				write!(f, " + ")?;
			}
			first = false;
			if k == 0 || !v.is_one() {
				write!(f, "{}", v)?;
			}
			if k > 0 {
				write!(f, "{}", self.variable)?;
			}
			if k > 1 {
				let k = to_superscript(&k.to_string())?;
				write!(f, "{}", k)?;
			}
		}
		Ok(())
	}
}

#[cfg(test)]
mod tests {
	use crate::*;
	use smallvec::SmallVec;

	#[test]
	fn test_display() {
		let poly = Polynomial::new(coefficients![1, 3, 2, 0, 1, 0]);
		let poly_string = poly.to_display("x").to_string();
		assert_eq!(poly_string, "x⁵ + 3x⁴ + 2x³ + x");

		let mut coeffs = SmallVec::new();
		coeffs.resize(11, 0);
		*coeffs.first_mut().unwrap() = 1;
		*coeffs.last_mut().unwrap() = 1;
		let poly = Polynomial::new(coeffs);
		let poly_string = poly.to_display("ω").to_string();
		assert_eq!(poly_string, "ω¹⁰ + 1");
	}
}