#![feature(unchecked_math)]
pub(crate) mod convert;
use num_bigint::BigUint;
use crate::convert::{FromReverseVecChar, ToVecChar};
use std::ops::{DivAssign, Rem};
pub trait ToBase1112031:
Clone + TryInto<u32> + TryFrom<u32> + for<'a> DivAssign<&'a Self> + PartialEq<Self>
where
for<'a> &'a Self: Rem<&'a Self, Output = Self>,
{
fn to_base1112031<T>(mut self) -> Option<T>
where
T: FromReverseVecChar,
{
let zero: Self = 0_u32.try_into().ok()?;
let base: Self = 1112031_u32.try_into().ok()?;
let mut result: Vec<char> = Vec::new(); loop {
let digit: u32 = (&self % &base).try_into().ok()?;
let convert: i32 = match digit {
0..=9 => 0x30, 10..=35 => 0x61 - 10, 36..=61 => 0x41 - 36, 62..=77 => 0x20 - 62, 78..=84 => 0x3A - 78, 85..=90 => 0x5B - 85, 91..=94 => 0x7B - 91, 95..=55262 => 0x80 - 95, 55263.. => 0xE000 - 55263, };
unsafe {
let convert: u32 = std::mem::transmute(convert);
result.push(char::from_u32_unchecked(digit.unchecked_add(convert)));
}
self /= &base;
if self == zero {
break;
}
}
Some(FromReverseVecChar::from(result))
}
}
impl<T> ToBase1112031 for T
where
T: Clone + TryInto<u32> + TryFrom<u32> + for<'a> DivAssign<&'a Self> + PartialEq<Self>,
for<'a> &'a Self: Rem<&'a Self, Output = Self>,
{
}
pub trait FromBase1112031: TryFrom<BigUint> {
fn from_base1112031<T: ToVecChar>(input: T) -> Option<Self> {
let input = input
.to_vec_char()
.into_iter()
.rev() .map(|i| i as u32);
let mut exp = BigUint::from(1_u8);
let mut result = BigUint::from(0_u8);
for mut i in input {
let convert: i32 = match i {
0x30..=0x39 => 0x30, 0x61..=0x7A => 0x61 - 10, 0x41..=0x5A => 0x41 - 36, 0x20..=0x2F => 0x20 - 62, 0x3A..=0x40 => 0x3A - 78, 0x5B..=0x60 => 0x5B - 85, 0x7B..=0x7E => 0x7B - 91, 0x80..=0xD7FF => 0x80 - 95, 0xE000..=0x10FFFF => 0xE000 - 55263, _ => return None,
};
unsafe {
let convert: u32 = std::mem::transmute(convert);
i = i.unchecked_sub(convert);
}
result += &exp * i;
exp *= 1112031_u32;
}
result.try_into().ok()
}
}
impl<T> FromBase1112031 for T where T: TryFrom<BigUint> {}