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
impl Ternary
Sourcepub fn new(digits: Vec<Digit>) -> Ternary
pub fn new(digits: Vec<Digit>) -> Ternary
Creates a new balanced ternary number from a vector of Digits.
Sourcepub fn log(&self) -> usize
pub fn log(&self) -> usize
Returns the number of digits (length) of the balanced ternary number.
Sourcepub fn to_digit_slice(&self) -> &[Digit]
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.
Sourcepub fn get_digit(&self, index: usize) -> Option<&Digit>
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(), '-')Sourcepub fn parse(str: &str) -> Self
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 -.
Sourcepub fn to_dec(&self) -> i64
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.
Sourcepub fn from_dec(dec: i64) -> Self
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.
Sourcepub fn to_unbalanced(&self) -> String
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 of0,1, or2.
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);Sourcepub fn from_unbalanced(unbalanced: &str) -> Self
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);Sourcepub fn each(&self, f: impl Fn(Digit) -> Digit) -> Self
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 aDigitand returns a transformedDigit.
§Returns
Self- A newTernaryobject containing the transformed digits.
§Digit transformations
These methods (unary operators) from the Digit type can be called directly.
- Returns either
PosorNeg: - Returns either
ZeroorPosorNeg.
§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-");Sourcepub fn each_with(&self, f: impl Fn(Digit, Digit) -> Digit, other: Digit) -> Self
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 aDigitand an additionalDigit, and returns a transformedDigit.other- An additionalDigitto be passed to the transformation functionf.
§Returns
Self- A newTernaryobject containing the transformed digits.
§Digit transformations
These methods (binary operators) from the Digit type can be called directly.
Digit::mulDigit::divDigit::bitand(k3/l3 and)- Digit::bi3_and
Digit::bitor(k3/l3 or)- Digit::bi3_or
Digit::bitxor(k3/l3 xor)- Digit::k3_imply
- Digit::k3_equiv
- Digit::bi3_imply
- Digit::l3_imply
- Digit::rm3_imply
- Digit::ht_imply
§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");Sourcepub fn each_zip(&self, f: impl Fn(Digit, Digit) -> Digit, other: Self) -> Self
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
Digitfrom the currentTernary, - a
Digitfrom the corresponding position in theotherTernary. - The function must return a transformed
Digit.
- a
other- ATernaryobject with digits to process alongside the digits of the current object.
§Returns
Self- A newTernaryobject 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++++");Sourcepub fn each_zip_carry(
&self,
f: impl Fn(Digit, Digit, Digit) -> (Digit, Digit),
other: Self,
) -> Self
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
Digitfrom the currentTernary, - a
Digitfrom the corresponding position in theotherTernary, - and the current carry
Digit. - The function must return a tuple containing
(carry: Digit, transformed: Digit).
- a
other- ATernaryobject with digits to process alongside the digits of the current object.
§Returns
Self- A newTernaryobject 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());Sourcepub fn trim(&self) -> Self
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 newTernaryobject, 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.
Sourcepub fn with_length(&self, length: usize) -> Self
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 theTernarynumber.
§Returns
Self- A newTernaryobject 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(), "+");Sourcepub fn to_string_repr<F: Fn(&Digit) -> char>(&self, transform: F) -> String
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 aDigitand returns achar, 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 toTernary::to_string_repr(Digit::to_char).
Sourcepub fn concat(&self, other: &Ternary) -> Ternary
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 theTernarynumber to be concatenated to the current one.
§Returns
Ternary- A newTernaryobject 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-+");