Struct Ternary

Source
pub struct Ternary { /* private fields */ }
Expand description

Represents a balanced ternary number using a sequence of Digits.

Provides functions for creating, parsing, converting, and manipulating balanced ternary numbers.

Implementations§

Source§

impl Ternary

Source

pub fn new(digits: Vec<Digit>) -> Ternary

Creates a new balanced ternary number from a vector of Digits.

Source

pub fn log(&self) -> usize

Returns the number of digits (length) of the balanced ternary number.

Source

pub fn to_digit_slice(&self) -> &[Digit]

Retrieves a slice containing the digits of the Ternary.

§Returns

A slice referencing the digits vec of the Ternary.

This function allows access to the raw representation of the balanced ternary number as a slice of Digit values.

Source

pub fn get_digit(&self, index: usize) -> Option<&Digit>

Returns a reference to the Digit indexed by index if it exists.

Digits are indexed from the right:

use balanced_ternary::Ternary;

// Indexes :
//                              32
//                             4||1
//                            5||||0
//                            ||||||
//                            vvvvvv
let ternary = Ternary::parse("+++--+");
assert_eq!(ternary.get_digit(1).unwrap().to_char(), '-')
Source

pub fn parse(str: &str) -> Self

Parses a string representation of a balanced ternary number into a Ternary object.

Each character in the string must be one of +, 0, or -.

Source

pub fn to_dec(&self) -> i64

Converts the Ternary object to its integer (decimal) representation.

Calculates the sum of each digit’s value multiplied by the appropriate power of 3.

Source

pub fn from_dec(dec: i64) -> Self

Creates a balanced ternary number from a decimal integer.

The input number is converted into its balanced ternary representation, with digits represented as Digits.

Source

pub fn to_unbalanced(&self) -> String

Converts the balanced ternary number to its unbalanced representation as a string.

The unbalanced representation treats the digits as standard ternary (0, 1, 2), instead of balanced ternary (-1, 0, +1). Negative digits are handled by calculating the decimal value of the balanced ternary number and converting it back to an unbalanced ternary string.

Returns:

  • String - The unbalanced ternary representation of the number, where each digit is one of 0, 1, or 2.

Example:

use balanced_ternary::Ternary;

let repr = Ternary::parse("+--");
assert_eq!(repr.to_unbalanced(), "12");
assert_eq!(repr.to_dec(), 5);
let repr = Ternary::parse("-++");
assert_eq!(repr.to_unbalanced(), "-12");
assert_eq!(repr.to_dec(), -5);
Source

pub fn from_unbalanced(unbalanced: &str) -> Self

Parses a string representation of an unbalanced ternary number into a Ternary object.

The string must only contain characters valid in the unbalanced ternary numeral system (0, 1, or 2). Each character is directly converted into its decimal value and then interpreted as a balanced ternary number.

§Arguments
  • unbalanced - A string slice representing the unbalanced ternary number.
§Returns

A Ternary object representing the same value as the input string in balanced ternary form.

§Panics

This function will panic if the string is not a valid unbalanced ternary number. For instance, if it contains characters other than 0, 1, or 2.

§Examples
use balanced_ternary::Ternary;

let ternary = Ternary::from_unbalanced("-12");
assert_eq!(ternary.to_string(), "-++");
assert_eq!(ternary.to_dec(), -5);
Source

pub fn each(&self, f: impl Fn(Digit) -> Digit) -> Self

Applies a transformation function to each digit of the balanced ternary number, returning a new Ternary object with the transformed digits.

This method keeps the order of the digits unchanged while applying the provided transformation function f to each digit individually.

§Arguments
  • f - A closure or function that takes a Digit and returns a transformed Digit.
§Returns
  • Self - A new Ternary object containing the transformed digits.
§Digit transformations

These methods (unary operators) from the Digit type can be called directly.

§Examples
use balanced_ternary::{Ternary, Digit};

let orig_ternary = Ternary::parse("+0-");
let transformed = orig_ternary.each(Digit::necessary);
assert_eq!(transformed.to_string(), "+--");
let transformed = orig_ternary.each(Digit::positive);
assert_eq!(transformed.to_string(), "+00");
let transformed = orig_ternary.each(Digit::not_negative);
assert_eq!(transformed.to_string(), "++0");
let transformed = orig_ternary.each(Digit::absolute_negative);
assert_eq!(transformed.to_string(), "-0-");
Source

pub fn each_with(&self, f: impl Fn(Digit, Digit) -> Digit, other: Digit) -> Self

Applies a transformation function to each digit of the balanced ternary number, using an additional parameter for the transformation process, returning a new Ternary object with the transformed digits.

This method keeps the order of the digits unchanged while applying the provided transformation function f to each digit individually, along with the provided extra other digit.

§Arguments
  • f - A closure or function that takes a Digit and an additional Digit, and returns a transformed Digit.
  • other - An additional Digit to be passed to the transformation function f.
§Returns
  • Self - A new Ternary object containing the transformed digits.
§Digit transformations

These methods (binary operators) from the Digit type can be called directly.

§Examples
use std::ops::Mul;
use balanced_ternary::{Ternary, Digit};

let original = Ternary::parse("+-0");
let transformed = original.each_with(Digit::mul, Digit::Neg);
assert_eq!(transformed.to_string(), "-+0");
Source

pub fn each_zip(&self, f: impl Fn(Digit, Digit) -> Digit, other: Self) -> Self

Applies a transformation function to each digit of the balanced ternary number, along with a corresponding digit from another Ternary number.

This method ensures that the digits of both Ternary objects are aligned from the least significant to the most significant digit. If the other Ternary has fewer digits than the current one, the process is reversed to handle the shorter Ternary consistently. The result is a new Ternary object where each digit was transformed using the provided function f.

§Arguments
  • f - A closure or function that takes two arguments:
    • a Digit from the current Ternary,
    • a Digit from the corresponding position in the other Ternary.
    • The function must return a transformed Digit.
  • other - A Ternary object with digits to process alongside the digits of the current object.
§Returns
  • Self - A new Ternary object containing the transformed digits.
§Examples
use std::ops::Mul;
use balanced_ternary::{Ternary, Digit};

let ternary1 = Ternary::parse("-+0-+0-+0");
let ternary2 = Ternary::parse("---000+++");

let result = ternary1.each_zip(Digit::mul, ternary2.clone());
assert_eq!(result.to_string(), "+-0000-+0");

let result = ternary1.each_zip(Digit::k3_imply, ternary2.clone());
assert_eq!(result.to_string(), "+-0+00+++");
let result = ternary1.each_zip(Digit::bi3_imply, ternary2.clone());
assert_eq!(result.to_string(), "+-0000++0");
let result = ternary1.each_zip(Digit::ht_imply, ternary2.clone());
assert_eq!(result.to_string(), "+--+0++++");
Source

pub fn each_zip_carry( &self, f: impl Fn(Digit, Digit, Digit) -> (Digit, Digit), other: Self, ) -> Self

Applies a transformation function to each digit of the balanced ternary number, along with a corresponding digit from another Ternary number, and a carry digit.

This method processes the digits in reverse order (from the least significant to the most significant), keeping their transformed order correct by reversing the result afterward. Each digit from the current Ternary object is processed with the corresponding digit from another Ternary object and a carry digit using the provided closure or function f.

§Arguments
  • f - A closure or function that takes three arguments:
    • a Digit from the current Ternary,
    • a Digit from the corresponding position in the other Ternary,
    • and the current carry Digit.
    • The function must return a tuple containing (carry: Digit, transformed: Digit).
  • other - A Ternary object with digits to process alongside the digits of the current object.
§Returns
  • Self - A new Ternary object containing the transformed digits.
§Notes

The carry digit is initially Zero and is passed between each step of the transformation process. If the other Ternary has fewer digits than the current one, the missing digits in other are treated as Zero.

§Examples
use balanced_ternary::{Digit, Ternary};

let ternary1 = Ternary::parse("+-0");
let ternary2 = Ternary::parse("-+0");

// Transformation function that adds digits with a carry digit
let combine = |d1: Digit, d2: Digit, carry: Digit| -> (Digit, Digit) {
    // Simple example operation: this just illustrates transforming with carry.
    // Replace with meaningful logic as needed for your application.
    let sum = d1.to_i8() + d2.to_i8() + carry.to_i8();
    (Digit::from_i8(sum / 3), Digit::from_i8(sum % 3))
};

let result = ternary1.each_zip_carry(combine, ternary2.clone()).trim();
assert_eq!(result.to_string(), (&ternary1 + &ternary2).to_string());
Source

pub fn trim(&self) -> Self

Removes leading Zero digits from the Ternary number, effectively trimming it down to its simplest representation. The resulting Ternary number will still represent the same value.

§Returns
  • Self - A new Ternary object, trimmed of leading zeros.
§Examples
use balanced_ternary::{ Neg, Pos, Ternary, Zero};

let ternary = Ternary::new(vec![Zero, Zero, Pos, Neg]);
let trimmed = ternary.trim();
assert_eq!(trimmed.to_string(), "+-");
§Notes

This method does not mutate the original Ternary object but returns a new representation.

Source

pub fn with_length(&self, length: usize) -> Self

Adjusts the representation of the Ternary number to have a fixed number of digits.

If the current Ternary has fewer digits than the specified length, leading zero digits will be added to the Ternary to match the desired length. If the current Ternary has more digits than the specified length, it will be returned unmodified.

§Arguments
  • length - The desired length of the Ternary number.
§Returns
  • Self - A new Ternary object with the specified fixed length.
§Notes

If length is smaller than the existing number of digits, the function does not truncate the number but instead returns the original Ternary unchanged.

§Examples
use balanced_ternary::{Ternary, Zero, Pos};

let ternary = Ternary::new(vec![Pos]);
let fixed = ternary.with_length(5);
assert_eq!(fixed.to_string(), "0000+");

let fixed = ternary.with_length(1);
assert_eq!(fixed.to_string(), "+");
Source

pub fn to_string_repr<F: Fn(&Digit) -> char>(&self, transform: F) -> String

Converts the Ternary number into a string representation by applying a given transformation function to each digit of the ternary number.

§Arguments
  • transform - A function or closure that takes a Digit and returns a char, representing the digit.
§Returns

A String-based representation of the Ternary number resulting from applying the transformation to its digits.

§Examples
use balanced_ternary::{Digit, Pos, Neg, Zero, Ternary};

let ternary = Ternary::new(vec![Pos, Zero, Neg]);

let custom_repr = ternary.to_string_repr(Digit::to_char_t);
assert_eq!(custom_repr, "10T");
let custom_repr = ternary.to_string_repr(Digit::to_char_theta);
assert_eq!(custom_repr, "10Θ");
let custom_repr = ternary.to_string_repr(Digit::to_char);
assert_eq!(custom_repr, "+0-");
§Notes
  • The function provides flexibility to define custom string representations for the ternary number digits.
  • Call to Ternary::to_string() is equivalent to Ternary::to_string_repr(Digit::to_char).
Source

pub fn concat(&self, other: &Ternary) -> Ternary

Concatenates the current Ternary number with another Ternary number.

This function appends the digits of the provided Ternary object to the digits of the current Ternary object, creating a new Ternary number as the result.

§Arguments
  • other - A reference to the Ternary number to be concatenated to the current one.
§Returns
  • Ternary - A new Ternary object formed by concatenating the digits.
§Examples
use balanced_ternary::{Ternary, Pos, Zero, Neg};

let ternary1 = Ternary::new(vec![Pos, Zero]);
let ternary2 = Ternary::new(vec![Neg, Pos]);

let concatenated = ternary1.concat(&ternary2);
assert_eq!(concatenated.to_string(), "+0-+");

Trait Implementations§

Source§

impl Add<&Ternary> for &Ternary

Source§

type Output = Ternary

The resulting type after applying the + operator.
Source§

fn add(self, rhs: &Ternary) -> Self::Output

Performs the + operation. Read more
Source§

impl BitAnd<&Ternary> for &Ternary

Source§

type Output = Ternary

The resulting type after applying the & operator.
Source§

fn bitand(self, rhs: &Ternary) -> Self::Output

Performs the & operation. Read more
Source§

impl BitOr<&Ternary> for &Ternary

Source§

type Output = Ternary

The resulting type after applying the | operator.
Source§

fn bitor(self, rhs: &Ternary) -> Self::Output

Performs the | operation. Read more
Source§

impl BitXor<&Ternary> for &Ternary

Source§

type Output = Ternary

The resulting type after applying the ^ operator.
Source§

fn bitxor(self, rhs: &Ternary) -> Self::Output

Performs the ^ operation. Read more
Source§

impl Clone for Ternary

Source§

fn clone(&self) -> Ternary

Returns a copy of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for Ternary

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Display for Ternary

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Div<&Ternary> for &Ternary

Source§

type Output = Ternary

The resulting type after applying the / operator.
Source§

fn div(self, rhs: &Ternary) -> Self::Output

Performs the / operation. Read more
Source§

impl From<&str> for Ternary

Source§

fn from(value: &str) -> Self

Converts to this type from the input type.
Source§

impl From<String> for Ternary

Source§

fn from(value: String) -> Self

Converts to this type from the input type.
Source§

impl From<Ternary> for String

Source§

fn from(value: Ternary) -> Self

Converts to this type from the input type.
Source§

impl<const SIZE: usize> From<Ternary> for Tryte<SIZE>

Source§

fn from(value: Ternary) -> Self

Converts to this type from the input type.
Source§

impl From<Ternary> for i64

Source§

fn from(value: Ternary) -> Self

Converts to this type from the input type.
Source§

impl<const SIZE: usize> From<Tryte<SIZE>> for Ternary

Source§

fn from(value: Tryte<SIZE>) -> Self

Converts to this type from the input type.
Source§

impl From<i64> for Ternary

Source§

fn from(value: i64) -> Self

Converts to this type from the input type.
Source§

impl Hash for Ternary

Source§

fn hash<__H: Hasher>(&self, state: &mut __H)

Feeds this value into the given Hasher. Read more
1.3.0 · Source§

fn hash_slice<H>(data: &[Self], state: &mut H)
where H: Hasher, Self: Sized,

Feeds a slice of this type into the given Hasher. Read more
Source§

impl Mul<&Ternary> for &Ternary

Source§

type Output = Ternary

The resulting type after applying the * operator.
Source§

fn mul(self, rhs: &Ternary) -> Self::Output

Performs the * operation. Read more
Source§

impl Neg for &Ternary

Source§

fn neg(self) -> Self::Output

Returns the negation of the current Ternary object.

Negates each digit in the number.

Source§

type Output = Ternary

The resulting type after applying the - operator.
Source§

impl Not for &Ternary

Source§

type Output = Ternary

The resulting type after applying the ! operator.
Source§

fn not(self) -> Self::Output

Performs the unary ! operation. Read more
Source§

impl PartialEq for Ternary

Source§

fn eq(&self, other: &Ternary) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
Source§

impl Sub<&Ternary> for &Ternary

Source§

type Output = Ternary

The resulting type after applying the - operator.
Source§

fn sub(self, rhs: &Ternary) -> Self::Output

Performs the - operation. Read more
Source§

impl Eq for Ternary

Source§

impl StructuralPartialEq for Ternary

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dst: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dst. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T> ToString for T
where T: Display + ?Sized,

Source§

fn to_string(&self) -> String

Converts the given value to a String. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.