use std::iter;
pub fn bct_trybble_to_i8(bct: u8) -> i8 {
match bct {
0b101010 => -13, 0b101000 => -12, 0b101001 => -11, 0b100010 => -10, 0b100000 => -9, 0b100001 => -8, 0b100110 => -7, 0b100100 => -6, 0b100101 => -5, 0b001010 => -4, 0b001000 => -3, 0b001001 => -2, 0b000010 => -1, 0b000000 => 0, 0b000001 => 1, 0b000110 => 2, 0b000100 => 3, 0b000101 => 4, 0b011010 => 5, 0b011000 => 6, 0b011001 => 7, 0b010010 => 8, 0b010000 => 9, 0b010001 => 10, 0b010110 => 11, 0b010100 => 12, 0b010101 => 13, _ => 0,
}
}
pub fn i8_trybble_to_bct(number: i8) -> u8 {
match number {
-13 => 0b101010, -12 => 0b101000, -11 => 0b101001, -10 => 0b100010, -9 => 0b100000, -8 => 0b100001, -7 => 0b100110, -6 => 0b100100, -5 => 0b100101, -4 => 0b001010, -3 => 0b001000, -2 => 0b001001, -1 => 0b000010, 0 => 0b000000, 1 => 0b000001, 2 => 0b000110, 3 => 0b000100, 4 => 0b000101, 5 => 0b011010, 6 => 0b011000, 7 => 0b011001, 8 => 0b010010, 9 => 0b010000, 10 => 0b010001, 11 => 0b010110, 12 => 0b010100, 13 => 0b010101, _ => 0,
}
}
pub fn bct_trybble_to_ternary_string(bct: u8) -> Option<String> {
let res = match bct {
0b101010 => Some("TTT"),
0b101000 => Some("TT0"),
0b101001 => Some("TT1"),
0b100010 => Some("T0T"),
0b100000 => Some("T00"),
0b100001 => Some("T01"),
0b100110 => Some("T1T"),
0b100100 => Some("T10"),
0b100101 => Some("T11"),
0b001010 => Some("0TT"),
0b001000 => Some("0T0"),
0b001001 => Some("0T1"),
0b000010 => Some("00T"),
0b000000 => Some("000"),
0b000001 => Some("001"),
0b000110 => Some("01T"),
0b000100 => Some("010"),
0b000101 => Some("011"),
0b011010 => Some("1TT"),
0b011000 => Some("1T0"),
0b011001 => Some("1T1"),
0b010010 => Some("10T"),
0b010000 => Some("100"),
0b010001 => Some("101"),
0b010110 => Some("11T"),
0b010100 => Some("110"),
0b010101 => Some("111"),
_ => None,
};
match res {
Some(s) => Some(s.to_string()),
None => None,
}
}
fn negate_nonary(ns: &str) -> String {
ns.chars().map(|c| {
match c {
'D' => '4',
'C' => '3',
'B' => '2',
'A' => '1',
'1' => 'A',
'2' => 'B',
'3' => 'C',
'4' => 'D',
_ => '0',
}
}).collect()
}
pub fn i16_tryte_to_nonary_string(number: i16) -> Option<String> {
if number > 364 { return None }
if number < -364 { return None }
let is_negative = number < 0;
let mut v = Vec::new();
let mut n = if is_negative { -number } else { number };
while n > 0 {
let rem = n % 9;
n = n / 9;
if rem > 4 {
n += 1;
}
let out = match rem {
1 => "1",
2 => "2",
3 => "3",
4 => "4",
5 => "D",
6 => "C",
7 => "B",
8 => "A",
_ => "0",
};
v.push(out);
}
if v.len() < 3 {
let diff = 3 - v.len();
v.extend(iter::repeat("0").take(diff));
}
v.reverse();
let result = v.join("");
let nonary = if is_negative { negate_nonary(&result) } else { result };
Some(nonary)
}