use super::misc::isint;

pub struct Polys { n: u64, step: u8 }

pub fn polys(s: u8) -> Polys {
	Polys { n: 1, step: s - 2 }
}

impl Iterator for Polys {
	type Item = u64;
	fn next(&mut self) -> Option<u64> {
		let ans = Some(self.n);
		self.n += self.step as u64;
		ans
	}
}

pub fn tris()   -> Polys { polys(3) }
pub fn sqrs()   -> Polys { polys(4) }
pub fn pentas() -> Polys { polys(5) }
pub fn hexas()  -> Polys { polys(6) }

pub fn ispoly(s: u8, x: u64) -> bool {
	polys(s).take_while(|&y| y <= x).any(|y| y == x)
}

pub fn istri(x: u64) -> bool   { isint((((x * 8  + 1) as f64).sqrt() - 1.0) / 2.0) }
pub fn issqr(x: u64) -> bool   { isint( ( x           as f64).sqrt()) }
pub fn ispenta(x: u64) -> bool { isint((((x * 24 + 1) as f64).sqrt() + 1.0) / 6.0) }
pub fn ishexa(x: u64) -> bool  { isint((((x * 8  + 1) as f64).sqrt() + 1.0) / 4.0) }

pub fn poly(s: u8, x: u64) -> u64 {
	let s = s as u64;
	((s - 2) * x * x - (s - 4) * x) / 2
}

pub fn tri(x: u64) -> u64   { x * (x + 1) / 2 }
pub fn sqr(x: u64) -> u64   

pub fn penta(x: u64) -> u64 { x * (3 * x - 1) / 2 }
pub fn hexa(x: u64) -> u64  { x * (2 * x - 1) }

{ x * x }