-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Ricardo Fernández Serrata
committed
May 6, 2024
0 parents
commit 065b5ce
Showing
7 changed files
with
253 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
single-char-binding-names-threshold = 3 | ||
too-large-for-stack = 256 | ||
cognitive-complexity-threshold = 12 | ||
array-size-threshold = 262144 #2^18 | ||
enum-variant-size-threshold = 128 | ||
too-many-arguments-threshold = 4 | ||
literal-representation-threshold = 16 | ||
too-many-lines-threshold = 64 | ||
trivial-copy-size-limit = 2 | ||
max-include-file-size = 262144 | ||
type-complexity-threshold = 32 | ||
max-trait-bounds = 1 | ||
vec-box-size-threshold = 1024 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
/target |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
hard_tabs = true | ||
max_width = 96 #mean 0x40 0x80 | ||
short_array_element_width_threshold = 8 |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
[package] | ||
name = "n82k" | ||
version = "0.1.0" | ||
edition = "2021" | ||
|
||
[dependencies] | ||
num-bigint = "0.4.4" | ||
num-integer = "0.1.46" | ||
|
||
[lints.clippy] | ||
pedantic = "warn" | ||
nursery = "warn" | ||
unwrap_used = "warn" | ||
float_arithmetic = "forbid" | ||
float_cmp = "forbid" | ||
large_include_file = "forbid" | ||
|
||
[lints.rust] | ||
unsafe_code = "deny" | ||
|
||
[profile.release] | ||
strip = true | ||
lto = true | ||
codegen-units = 1 | ||
panic = "abort" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
mod util; | ||
#[allow(clippy::wildcard_imports)] | ||
use util::*; | ||
|
||
/// lowest unknown, as of year 2024 | ||
const BASE: Non0U8 = match Non0U8::new(6) { | ||
Some(n) => n, | ||
_ => unreachable!(), | ||
}; | ||
|
||
/// According to [Numberphile](https://youtu.be/LNS1fabDkeA) | ||
/// thousand-digit numerals have already been checked. | ||
const START: u128 = u128::MAX; | ||
|
||
fn main() { | ||
let start = START; | ||
// prevent us from using a trivial value | ||
assert!(start > 1); | ||
|
||
// each bit represents a digit in radix `BASE` | ||
let mut packed_numeral = UN::from(start); | ||
loop { | ||
/* | ||
We must pay the price of conversion, | ||
regardless of representation. | ||
Maybe someone can come up with a clever algorithm | ||
that exploits previously-unpacked values to infer the next? | ||
*/ | ||
let n = unpack_as_radix(&packed_numeral, BASE); | ||
// by definition, `BASE` is already checked, | ||
// so no need to include it in the range | ||
if is_0_1_all(&n, BASE) { | ||
println!("{packed_numeral:#x}"); | ||
break; | ||
} | ||
// skip all `n` that match `!is_0_1(n, BASE)` | ||
packed_numeral.inc(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,126 @@ | ||
pub use core::num::NonZeroU8 as Non0U8; | ||
pub use num_bigint::BigUint as UN; | ||
pub use num_integer::Integer; | ||
|
||
const MIN_NON_TRIVIAL_BASE: Non0U8 = match Non0U8::new(3) { | ||
Some(n) => n, | ||
_ => unreachable!(), | ||
}; | ||
|
||
/// Interpret the bits of `digits` as digits in base `radix`, | ||
/// and return the numeric value represented by that numeral. | ||
pub fn unpack_as_radix(digits: &UN, radix: Non0U8) -> UN { | ||
let mut out = UN::default(); | ||
let mut pow = UN::from(1u8); | ||
|
||
// LSb | ||
debug_assert_eq!(digits.bit(0), digits.is_odd()); | ||
for i in 0..digits.bits() { | ||
if digits.bit(i) { | ||
out += pow.clone(); | ||
} | ||
pow *= radix.get(); | ||
} | ||
out | ||
} | ||
|
||
/// Checks if `n` can be written in base `radix`, | ||
/// using only zeros and ones. | ||
pub fn is_0_1(mut n: UN, radix: Non0U8) -> bool { | ||
let radix = UN::from(radix.get()); | ||
let n1 = UN::from(1u8); | ||
|
||
// 1 is just "1" in any radix | ||
while n > n1 { | ||
let digit; | ||
(n, digit) = n.div_rem(&radix); | ||
if digit.bits() > 8 { | ||
unreachable!() | ||
} | ||
if digit > n1 { | ||
return false; | ||
} | ||
} | ||
true | ||
} | ||
|
||
/// Checks if `n` can be written using only zeros and ones, | ||
/// in all bases | ||
/// from the minimun non-trivial base (inclusive) | ||
/// to `max_radix` (exclusive). | ||
pub fn is_0_1_all(n: &UN, max_radix: Non0U8) -> bool { | ||
// would `rev` be more optimal? | ||
for radix in MIN_NON_TRIVIAL_BASE.get()..max_radix.get() { | ||
if !is_0_1( | ||
n.clone(), | ||
Non0U8::new(radix).unwrap_or_else(|| unreachable!()), | ||
) { | ||
return false; | ||
} | ||
} | ||
true | ||
} | ||
|
||
#[cfg(test)] | ||
mod tests { | ||
use super::*; | ||
|
||
#[test] | ||
fn unpacker_works() { | ||
assert_eq!( | ||
unpack_as_radix( | ||
&UN::from(0b1010u8), | ||
Non0U8::new(3).unwrap_or_else(|| unreachable!("3 == 0 ???")) | ||
), | ||
UN::from(27u8 + 3u8) | ||
); | ||
} | ||
|
||
#[test] | ||
fn checker_happy() { | ||
assert!(is_0_1( | ||
UN::from(3u8), | ||
Non0U8::new(3).unwrap_or_else(|| unreachable!()) | ||
)); | ||
assert!(is_0_1( | ||
UN::from(4u8), | ||
Non0U8::new(3).unwrap_or_else(|| unreachable!()) | ||
)); | ||
assert!(is_0_1_all( | ||
&UN::from(4u8), | ||
Non0U8::new(5).unwrap_or_else(|| unreachable!()) | ||
)); | ||
assert!(is_0_1_all( | ||
&UN::from(82000u32), | ||
Non0U8::new(6).unwrap_or_else(|| unreachable!()) | ||
)); | ||
assert!(is_0_1_all( | ||
&UN::from(82000u32), | ||
Non0U8::new(6).unwrap_or_else(|| unreachable!()) | ||
)); | ||
} | ||
|
||
#[test] | ||
fn checker_sad() { | ||
assert!(!is_0_1( | ||
UN::from(2u8), | ||
Non0U8::new(3).unwrap_or_else(|| unreachable!()) | ||
)); | ||
assert!(!is_0_1( | ||
UN::from(3u8), | ||
Non0U8::new(4).unwrap_or_else(|| unreachable!()) | ||
)); | ||
assert!(!is_0_1_all( | ||
&UN::from(3u8), | ||
Non0U8::new(5).unwrap_or_else(|| unreachable!()) | ||
)); | ||
assert!(!is_0_1_all( | ||
&UN::from(5u8), | ||
Non0U8::new(5).unwrap_or_else(|| unreachable!()) | ||
)); | ||
assert!(!is_0_1_all( | ||
&UN::from(4u8), | ||
Non0U8::new(6).unwrap_or_else(|| unreachable!()) | ||
)); | ||
} | ||
} |