clean up 32
This commit is contained in:
+42
-29
@@ -5,70 +5,83 @@ type Int = u32;
|
|||||||
const UPPER_BOUND: Int = 3_333; // because result must be a 4-digit number
|
const UPPER_BOUND: Int = 3_333; // because result must be a 4-digit number
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
// prevent reallocation of these sets on every call in `are_pandigital`
|
||||||
let mut buffer1 = HashSet::new();
|
let mut buffer1 = HashSet::new();
|
||||||
let mut buffer2 = HashSet::new();
|
let mut buffer2 = HashSet::new();
|
||||||
|
|
||||||
let f = (1..UPPER_BOUND)
|
let factors = get_suitable_factors(UPPER_BOUND);
|
||||||
.filter(|n| {
|
|
||||||
let s = n.to_string();
|
|
||||||
let hs = s.chars().collect::<HashSet<_>>();
|
|
||||||
hs.len() == s.len() && !hs.contains(&'0')
|
|
||||||
})
|
|
||||||
.collect::<Vec<_>>()
|
|
||||||
.leak();
|
|
||||||
|
|
||||||
let mut result = HashSet::new();
|
let mut products_of_pandigital_triples = HashSet::new();
|
||||||
for f1 in f.iter() {
|
for f1 in factors.iter() {
|
||||||
let lower_bound = UPPER_BOUND / f1;
|
let lower_bound = UPPER_BOUND / f1;
|
||||||
|
|
||||||
'inner: for f2 in f.iter().skip_while(|i| **i < lower_bound) {
|
'inner: for f2 in factors.iter().skip_while(|i| **i < lower_bound) {
|
||||||
let p = f1 * f2;
|
let product = f1 * f2;
|
||||||
if f1.len() + f2.len() + p.len() > 9 {
|
if f1.oom() + f2.oom() + product.oom() > 9 {
|
||||||
break 'inner;
|
break 'inner;
|
||||||
}
|
}
|
||||||
|
|
||||||
if are_pandigital([f1, f2, &p], &mut buffer1, &mut buffer2) {
|
if are_pandigital([f1, f2, &product], &mut buffer1, &mut buffer2) {
|
||||||
println!("{f1} {f2} {p}");
|
println!("{f1} {f2} {product}");
|
||||||
result.insert(p);
|
products_of_pandigital_triples.insert(product);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
println!("{}", result.iter().sum::<Int>());
|
println!("{}", products_of_pandigital_triples.iter().sum::<Int>());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn are_pandigital(input: [∬ 3], accum: &mut HashSet<char>, hs: &mut HashSet<char>) -> bool {
|
fn get_suitable_factors(upper_bound: Int) -> &'static [Int] {
|
||||||
accum.clear();
|
(1..upper_bound)
|
||||||
|
.filter(|number| {
|
||||||
|
let str = number.to_string();
|
||||||
|
let set = str.chars().collect::<HashSet<_>>();
|
||||||
|
// a suitable number must not contain `0`, and must have an unique digit at every
|
||||||
|
// position
|
||||||
|
set.len() == str.len() && !set.contains(&'0')
|
||||||
|
})
|
||||||
|
.collect::<Vec<_>>()
|
||||||
|
// leaking the vec is slightly faster than handling the vec
|
||||||
|
.leak()
|
||||||
|
}
|
||||||
|
|
||||||
let mut length = 0;
|
fn are_pandigital(
|
||||||
|
input: [∬ 3],
|
||||||
|
digits_in_numbers: &mut HashSet<char>,
|
||||||
|
set_of_char_buffer: &mut HashSet<char>,
|
||||||
|
) -> bool {
|
||||||
|
digits_in_numbers.clear();
|
||||||
|
|
||||||
|
let mut length_of_all_numbers = 0;
|
||||||
|
|
||||||
for n in input {
|
for n in input {
|
||||||
hs.clear();
|
set_of_char_buffer.clear();
|
||||||
|
|
||||||
let s = n.to_string();
|
let s = n.to_string();
|
||||||
length += s.len();
|
length_of_all_numbers += s.len();
|
||||||
|
|
||||||
s.chars().for_each(|c| {
|
s.chars().for_each(|c| {
|
||||||
hs.insert(c);
|
set_of_char_buffer.insert(c);
|
||||||
});
|
});
|
||||||
|
|
||||||
if s.len() != hs.len() {
|
if s.len() != set_of_char_buffer.len() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
for item in hs.iter() {
|
for item in set_of_char_buffer.iter() {
|
||||||
accum.insert(*item);
|
digits_in_numbers.insert(*item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
accum.len() == 9 && length == 9 && !accum.contains(&'0')
|
digits_in_numbers.len() == 9 && length_of_all_numbers == 9 && !digits_in_numbers.contains(&'0')
|
||||||
}
|
}
|
||||||
|
|
||||||
trait Length {
|
trait Length {
|
||||||
fn len(&self) -> usize;
|
fn oom(&self) -> usize;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Length for Int {
|
impl Length for Int {
|
||||||
fn len(&self) -> usize {
|
// order of magnitude
|
||||||
|
fn oom(&self) -> usize {
|
||||||
let mut tmp = 1;
|
let mut tmp = 1;
|
||||||
let mut oom = 1;
|
let mut oom = 1;
|
||||||
while tmp - 1 < *self {
|
while tmp - 1 < *self {
|
||||||
|
|||||||
Reference in New Issue
Block a user