From 4b7a8a08d248a6439bec59ce55603a7f72d7e6d9 Mon Sep 17 00:00:00 2001 From: Casey Rodarmor Date: Mon, 10 Jan 2022 13:29:22 -0800 Subject: [PATCH 1/7] Add lucky trait --- src/traits.rs | 8 ++++++-- tests/traits.rs | 9 +++++++++ 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/src/traits.rs b/src/traits.rs index 71e9ba20c2..cda8af6d00 100644 --- a/src/traits.rs +++ b/src/traits.rs @@ -21,14 +21,18 @@ pub(crate) fn run(n: u64) -> Result { println!("pi"); } - if s.replace("69", "") == "" { + if s.replace("69", "").is_empty() { println!("nice"); } - if s.replace("7", "") == "" { + if s.replace("7", "").is_empty() { println!("angelic"); } + if s.replace("8", "").is_empty() { + println!("lucky"); + } + println!("name:{}", name(n)); let mut block = 0; diff --git a/tests/traits.rs b/tests/traits.rs index 56bd5ffecb..23b34e1179 100644 --- a/tests/traits.rs +++ b/tests/traits.rs @@ -91,3 +91,12 @@ fn block() -> Result { assert!(traits(50 * 100_000_000 + 1)?.contains("block:1")); Ok(()) } + +#[test] +fn lucky() -> Result { + assert!(!traits(0)?.contains("lucky")); + assert!(traits(8)?.contains("lucky")); + assert!(traits(88)?.contains("lucky")); + assert!(!traits(89)?.contains("lucky")); + Ok(()) +} From 50045c89d5d5a9944e6d6da67593cbc83da5f419 Mon Sep 17 00:00:00 2001 From: Casey Rodarmor Date: Mon, 10 Jan 2022 14:02:57 -0800 Subject: [PATCH 2/7] Add more traits --- src/traits.rs | 31 ++++++++++++++++++++++--------- tests/traits.rs | 47 ++++++++++++++++++++++++++++++++++++----------- 2 files changed, 58 insertions(+), 20 deletions(-) diff --git a/src/traits.rs b/src/traits.rs index 2c36e3631b..dfca5c2afa 100644 --- a/src/traits.rs +++ b/src/traits.rs @@ -1,10 +1,6 @@ use super::*; pub(crate) fn run(n: u64) -> Result { - if n == 0 { - println!("zero"); - } - if n < subsidy(0) { println!("genesis"); } @@ -15,23 +11,40 @@ pub(crate) fn run(n: u64) -> Result { println!("odd"); } + if (n as f64).sqrt().fract() == 0.0 { + println!("square"); + } + + if (n as f64).cbrt().fract() == 0.0 { + println!("cube"); + } + + let digits = n.to_string().chars().collect::>(); + let pi = std::f64::consts::PI.to_string().replace('.', ""); let s = n.to_string(); if s == pi[..s.len()] { println!("pi"); } - if s.replace("69", "").is_empty() { + if digits.chunks(2).all(|chunk| chunk == &['6', '9']) { println!("nice"); } - if s.replace("7", "").is_empty() { + if digits.iter().all(|c| *c == '7') { println!("angelic"); } - if s.replace("8", "").is_empty() { - println!("lucky"); - } + println!( + "luck:{}/{}", + digits.iter().filter(|c| **c == '8').count(), + digits.iter().count() + ); + + println!( + "population:{}", + (n * 0x0002000400080010 & 0x1111111111111111) * 0x1111111111111111 >> 60 + ); println!("name:{}", name(n)); diff --git a/tests/traits.rs b/tests/traits.rs index b475c9e832..d358324d17 100644 --- a/tests/traits.rs +++ b/tests/traits.rs @@ -12,13 +12,6 @@ fn traits(n: u64) -> Result> { ) } -#[test] -fn zero() -> Result { - assert!(traits(0)?.contains("zero")); - assert!(!traits(1)?.contains("zero")); - Ok(()) -} - #[test] fn genesis() -> Result { assert!(traits(0)?.contains("genesis")); @@ -94,10 +87,10 @@ fn block() -> Result { #[test] fn lucky() -> Result { - assert!(!traits(0)?.contains("lucky")); - assert!(traits(8)?.contains("lucky")); - assert!(traits(88)?.contains("lucky")); - assert!(!traits(89)?.contains("lucky")); + assert!(traits(0)?.contains("luck:0/1")); + assert!(traits(8)?.contains("luck:1/1")); + assert!(traits(88)?.contains("luck:2/2")); + assert!(traits(89)?.contains("luck:1/2")); Ok(()) } @@ -110,3 +103,35 @@ fn shiny() -> Result { assert!(!traits(50 * 100_000_000 + 1)?.contains("shiny")); Ok(()) } + +#[test] +fn population() -> Result { + assert!(traits(0)?.contains("population:0")); + assert!(traits(1)?.contains("population:1")); + assert!(traits(2)?.contains("population:1")); + assert!(traits(3)?.contains("population:2")); + assert!(traits(4)?.contains("population:1")); + Ok(()) +} + +#[test] +fn square() -> Result { + assert!(traits(0)?.contains("square")); + assert!(traits(1)?.contains("square")); + assert!(!traits(2)?.contains("square")); + assert!(traits(4)?.contains("square")); + assert!(!traits(5)?.contains("square")); + assert!(traits(9)?.contains("square")); + Ok(()) +} + +#[test] +fn cube() -> Result { + assert!(traits(0)?.contains("cube")); + assert!(traits(1)?.contains("cube")); + assert!(!traits(2)?.contains("cube")); + assert!(traits(8)?.contains("cube")); + assert!(!traits(9)?.contains("cube")); + assert!(traits(27)?.contains("cube")); + Ok(()) +} From 5e9a745c17c88623b2fd4b5c3b20cab0012f64b3 Mon Sep 17 00:00:00 2001 From: Casey Rodarmor Date: Mon, 10 Jan 2022 14:05:33 -0800 Subject: [PATCH 3/7] Placate clippy --- justfile | 4 ++-- src/traits.rs | 6 +++--- tests/traits.rs | 1 + 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/justfile b/justfile index 82e65a6824..74a6343d6e 100644 --- a/justfile +++ b/justfile @@ -2,8 +2,8 @@ log := '0' export RUST_LOG := log -catalog: - cargo run catalog +clippy: + cargo clippy watch +args='ltest --release': cargo watch --clear --exec '{{args}}' diff --git a/src/traits.rs b/src/traits.rs index dfca5c2afa..7d96a0ef16 100644 --- a/src/traits.rs +++ b/src/traits.rs @@ -27,7 +27,7 @@ pub(crate) fn run(n: u64) -> Result { println!("pi"); } - if digits.chunks(2).all(|chunk| chunk == &['6', '9']) { + if digits.chunks(2).all(|chunk| chunk == ['6', '9']) { println!("nice"); } @@ -38,12 +38,12 @@ pub(crate) fn run(n: u64) -> Result { println!( "luck:{}/{}", digits.iter().filter(|c| **c == '8').count(), - digits.iter().count() + digits.len() ); println!( "population:{}", - (n * 0x0002000400080010 & 0x1111111111111111) * 0x1111111111111111 >> 60 + (((n * 0x0002000400080010) & 0x1111111111111111) * 0x1111111111111111) >> 60 ); println!("name:{}", name(n)); diff --git a/tests/traits.rs b/tests/traits.rs index d358324d17..601ad81ac5 100644 --- a/tests/traits.rs +++ b/tests/traits.rs @@ -53,6 +53,7 @@ fn nice() -> Result { assert!(traits(6969)?.contains("nice")); assert!(traits(696969)?.contains("nice")); assert!(!traits(696968)?.contains("nice")); + assert!(!traits(6969698)?.contains("nice")); Ok(()) } From f44e9bbf363d4ffd1ee5588ee48442935bc78109 Mon Sep 17 00:00:00 2001 From: Casey Rodarmor Date: Mon, 10 Jan 2022 14:11:31 -0800 Subject: [PATCH 4/7] Fix in non-release mode --- justfile | 2 +- src/traits.rs | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/justfile b/justfile index 74a6343d6e..3b2aa967a9 100644 --- a/justfile +++ b/justfile @@ -5,5 +5,5 @@ export RUST_LOG := log clippy: cargo clippy -watch +args='ltest --release': +watch +args='ltest': cargo watch --clear --exec '{{args}}' diff --git a/src/traits.rs b/src/traits.rs index 7d96a0ef16..88ddf9ea72 100644 --- a/src/traits.rs +++ b/src/traits.rs @@ -43,7 +43,8 @@ pub(crate) fn run(n: u64) -> Result { println!( "population:{}", - (((n * 0x0002000400080010) & 0x1111111111111111) * 0x1111111111111111) >> 60 + (n.wrapping_mul(0x0002000400080010) & 0x1111111111111111).wrapping_mul(0x1111111111111111) + >> 60 ); println!("name:{}", name(n)); From 9875f1d206bd1f420abb9eb67e6c1172490d0370 Mon Sep 17 00:00:00 2001 From: Casey Rodarmor Date: Mon, 10 Jan 2022 14:13:37 -0800 Subject: [PATCH 5/7] Just kidding release mode is much faster --- justfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/justfile b/justfile index 3b2aa967a9..74a6343d6e 100644 --- a/justfile +++ b/justfile @@ -5,5 +5,5 @@ export RUST_LOG := log clippy: cargo clippy -watch +args='ltest': +watch +args='ltest --release': cargo watch --clear --exec '{{args}}' From e60cf73e495c9675895740c777c0b07f05572267 Mon Sep 17 00:00:00 2001 From: Casey Rodarmor Date: Mon, 10 Jan 2022 14:27:26 -0800 Subject: [PATCH 6/7] Use integer square and cube root algorithms --- src/traits.rs | 37 +++++++++++++++++++++++++++++++++++-- 1 file changed, 35 insertions(+), 2 deletions(-) diff --git a/src/traits.rs b/src/traits.rs index 88ddf9ea72..4d288a1534 100644 --- a/src/traits.rs +++ b/src/traits.rs @@ -1,5 +1,38 @@ use super::*; +fn isqrt(x: u64) -> u64 { + let mut a = 1; + let mut b = ((x >> 5) + 8).min(65536); + loop { + let m = (a + b) >> 1; + if m * m > x { + b = m - 1; + } else { + a = m + 1; + } + + if b < a { + break; + } + } + a - 1 +} + +fn icbrt(mut x: u64) -> u64 { + let mut y = 0; + let mut s = 30; + while s >= 0 { + y = 2 * y; + let b = (3 * y * (y + 1) + 1) << s; + if x >= b { + x = x - b; + y = y + 1 + } + s -= 3; + } + y +} + pub(crate) fn run(n: u64) -> Result { if n < subsidy(0) { println!("genesis"); @@ -11,11 +44,11 @@ pub(crate) fn run(n: u64) -> Result { println!("odd"); } - if (n as f64).sqrt().fract() == 0.0 { + if isqrt(n) * isqrt(n) == n { println!("square"); } - if (n as f64).cbrt().fract() == 0.0 { + if icbrt(n) * icbrt(n) * icbrt(n) == n { println!("cube"); } From b0ae93727e14352198d803b567d01f1f269f555a Mon Sep 17 00:00:00 2001 From: Casey Rodarmor Date: Mon, 10 Jan 2022 14:32:15 -0800 Subject: [PATCH 7/7] Placate clippy --- justfile | 4 ++++ src/traits.rs | 11 ++++++----- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/justfile b/justfile index 74a6343d6e..0a96a7e838 100644 --- a/justfile +++ b/justfile @@ -2,6 +2,10 @@ log := '0' export RUST_LOG := log +all: clippy + cargo test --release + cargo test + clippy: cargo clippy diff --git a/src/traits.rs b/src/traits.rs index 4d288a1534..4c62c42839 100644 --- a/src/traits.rs +++ b/src/traits.rs @@ -22,11 +22,12 @@ fn icbrt(mut x: u64) -> u64 { let mut y = 0; let mut s = 30; while s >= 0 { - y = 2 * y; - let b = (3 * y * (y + 1) + 1) << s; - if x >= b { - x = x - b; - y = y + 1 + y *= 2; + let b = 3 * y * (y + 1) + 1; + let bs = b << s; + if x >= bs && b == (bs >> s) { + x -= b; + y += 1 } s -= 3; }