Skip to content

Commit

Permalink
extract bitwise stuff into mod
Browse files Browse the repository at this point in the history
  • Loading branch information
rudxain committed May 6, 2024
1 parent fc867c5 commit 6aac0b8
Show file tree
Hide file tree
Showing 5 changed files with 81 additions and 67 deletions.
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "n82k"
version = "0.1.2"
version = "0.1.3"
edition = "2021"

[dependencies]
Expand Down
69 changes: 69 additions & 0 deletions src/bits.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
pub use core::{
iter::successors,
num::NonZeroU8 as Non0U8,
ops::{Deref, DerefMut},
};

pub use num_bigint::BigUint as UN;
pub use num_integer::Integer;
pub use num_traits::{One, Zero};

#[derive(Debug, Clone)]
pub struct BitIter {
i: u64,
n: UN,
}
impl BitIter {
#[must_use]
pub const fn new(n: UN) -> Self {
Self { i: 0, n }
}
}
impl Iterator for BitIter {
type Item = bool;
fn next(&mut self) -> Option<Self::Item> {
// bounds-check
if self.i >= self.n.bits() {
return None;
}
let out = self.n.bit(self.i);
self.i = self
.i
.checked_add(1)
.unwrap_or_else(|| unreachable!("bounds-check failed"));
Some(out)
}
}

#[derive(Debug, Clone)]
/// `Vec`tor of packed `bool`s,
/// built on `BigUint`.
pub struct BitVec(UN);
impl BitVec {
#[must_use]
pub const fn new(n: UN) -> Self {
Self(n)
}
#[must_use]
pub fn clone_inc(&self) -> Self {
Self(self.0.clone() + 1u8)
}
}
impl Deref for BitVec {
type Target = UN;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl DerefMut for BitVec {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
}
impl IntoIterator for BitVec {
type Item = bool;
type IntoIter = BitIter;
fn into_iter(self) -> Self::IntoIter {
BitIter::new(self.0)
}
}
8 changes: 6 additions & 2 deletions src/main.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
mod util;
pub mod bits;
#[allow(clippy::wildcard_imports)]
use bits::*;

pub mod util;
#[allow(clippy::wildcard_imports)]
use util::*;

Expand All @@ -17,7 +21,7 @@ fn main() {
"{:#x}",
// each bit represents a digit in radix `BASE`
successors(Some(BitVec::new(UN::one() << START_LEN)), |n| Some(
BitVec::new((**n).clone() + 1u8)
n.clone_inc()
))
/*
We must pay the price of conversion,
Expand Down
67 changes: 4 additions & 63 deletions src/util.rs
Original file line number Diff line number Diff line change
@@ -1,66 +1,5 @@
pub use core::{
iter::successors,
num::NonZeroU8 as Non0U8,
ops::{Deref, DerefMut},
};

pub use num_bigint::BigUint as UN;
pub use num_integer::Integer;
pub use num_traits::{One, Zero};

#[derive(Debug, Clone)]
pub struct BitIter {
i: u64,
n: UN,
}
impl BitIter {
pub const fn new(n: UN) -> Self {
Self { i: 0, n }
}
}
impl Iterator for BitIter {
type Item = bool;
fn next(&mut self) -> Option<Self::Item> {
// bounds-check
if self.i >= self.n.bits() {
return None;
}
let out = self.n.bit(self.i);
self.i = self
.i
.checked_add(1)
.unwrap_or_else(|| unreachable!("bounds-check failed"));
Some(out)
}
}

#[derive(Debug, Clone)]
/// `Vec`tor of packed `bool`s,
/// built on `BigUint`.
pub struct BitVec(UN);
impl BitVec {
pub const fn new(n: UN) -> Self {
Self(n)
}
}
impl Deref for BitVec {
type Target = UN;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl DerefMut for BitVec {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
}
impl IntoIterator for BitVec {
type Item = bool;
type IntoIter = BitIter;
fn into_iter(self) -> Self::IntoIter {
BitIter::new(self.0)
}
}
#[allow(clippy::wildcard_imports)]
use crate::bits::*;

const MIN_NON_TRIVIAL_BASE: Non0U8 = match Non0U8::new(3) {
Some(n) => n,
Expand All @@ -82,6 +21,7 @@ pub fn unpack_as_radix<T: IntoIterator<Item = bool>>(digits: T, radix: Non0U8) -

/// Checks if `n` can be written in base `radix`,
/// using only zeros and ones.
#[must_use]
pub fn is_0_1(n: UN, radix: Non0U8) -> bool {
let radix = UN::from(radix.get());
let n1 = UN::one();
Expand All @@ -104,6 +44,7 @@ pub fn is_0_1(n: UN, radix: Non0U8) -> bool {
/// in all bases
/// from the minimun non-trivial base (inclusive)
/// to `max_radix` (exclusive).
#[must_use]
pub fn is_0_1_all(n: &UN, max_radix: Non0U8) -> bool {
// would `rev` be more optimal?
(MIN_NON_TRIVIAL_BASE.get()..max_radix.get()).all(|radix| {
Expand Down

0 comments on commit 6aac0b8

Please sign in to comment.