use std::{
    cmp::min,
    convert::{TryFrom, TryInto},
    fmt,
    ops::{Add, Mul, Neg},
    str::FromStr,
};

fn main() -> Result<(), &'static str> {
    let a = BalancedTernary::from_str("+-0++0+")?;
    let b = BalancedTernary::from(-436);
    let c = BalancedTernary::from_str("+-++-")?;
    println!("a = {} = {}", a, i128::try_from(a.clone())?);
    println!("b = {} = {}", b, i128::try_from(b.clone())?);
    println!("c = {} = {}", c, i128::try_from(c.clone())?);

    let d = a * (b + -c);
    println!("a * (b - c) = {} = {}", d, i128::try_from(d.clone())?);

    let e = BalancedTernary::from_str(
        "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++",
    )?;
    assert_eq!(i128::try_from(e).is_err(), true);

    Ok(())
}

#[derive(Clone, Copy, PartialEq)]
enum Trit {
    Zero,
    Pos,
    Neg,
}

impl TryFrom<char> for Trit {
    type Error = &'static str;

    fn try_from(value: char) -> Result<Self, Self::Error> {
        match value {
            '0' => Ok(Self::Zero),
            '+' => Ok(Self::Pos),
            '-' => Ok(Self::Neg),
            _ => Err("Invalid character for balanced ternary"),
        }
    }
}

impl From<Trit> for char {
    fn from(x: Trit) -> Self {
        match x {
            Trit::Zero => '0',
            Trit::Pos => '+',
            Trit::Neg => '-',
        }
    }
}

impl Add for Trit {