basic version of 95, very slow
This commit is contained in:
@@ -5,4 +5,9 @@ edition = "2021"
|
|||||||
|
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
[dependencies]
|
[dev-dependencies]
|
||||||
|
rstest = "0.17"
|
||||||
|
|
||||||
|
[profile.release]
|
||||||
|
debug = true
|
||||||
|
lto = "fat"
|
||||||
|
|||||||
+70
-27
@@ -1,51 +1,94 @@
|
|||||||
const MAX: usize = 1_000;
|
use std::collections::HashSet;
|
||||||
|
|
||||||
|
const MAX: usize = 1_000_000;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let mut numbers: Vec<_> = (0_usize..MAX + 1).map(|_| true).collect();
|
|
||||||
|
|
||||||
let mut chains = vec![];
|
let mut chains = vec![];
|
||||||
|
|
||||||
let mut i = 0_usize;
|
let mut part_of_any_chain = HashSet::new();
|
||||||
loop {
|
|
||||||
if i > MAX {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
let mut num = if numbers[i] {
|
|
||||||
numbers[i] = false;
|
|
||||||
i
|
|
||||||
} else {
|
|
||||||
i += 1;
|
|
||||||
continue;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
for current in 1..MAX {
|
||||||
|
if part_of_any_chain.contains(¤t) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
try_build_chain_from_number(MAX, current, &mut chains, &mut part_of_any_chain);
|
||||||
|
}
|
||||||
|
|
||||||
|
chains.sort_by_key(|chain| chain.len());
|
||||||
|
|
||||||
|
let longest = chains.last().unwrap();
|
||||||
|
|
||||||
|
let smallest = longest.iter().min().unwrap().to_owned();
|
||||||
|
|
||||||
|
println!("{smallest}");
|
||||||
|
}
|
||||||
|
|
||||||
|
fn try_build_chain_from_number(
|
||||||
|
max: usize,
|
||||||
|
mut current: usize,
|
||||||
|
chains: &mut Vec<Vec<usize>>,
|
||||||
|
part_of_any_chain: &mut HashSet<usize>,
|
||||||
|
) {
|
||||||
let mut maybe_chain = vec![];
|
let mut maybe_chain = vec![];
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
let next: usize = get_proper_divisors(num).sum();
|
maybe_chain.push(current);
|
||||||
if next > MAX {
|
|
||||||
|
let next: usize = get_proper_divisors(current).sum();
|
||||||
|
|
||||||
|
if next > max || next == 0 {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if !numbers[next] {
|
|
||||||
if maybe_chain.contains(&next) {
|
if maybe_chain.contains(&next) {
|
||||||
|
if maybe_chain.len() > 1 && *maybe_chain.first().unwrap() == next {
|
||||||
|
for number in &maybe_chain {
|
||||||
|
part_of_any_chain.insert(*number);
|
||||||
|
}
|
||||||
|
println!("{}", maybe_chain.first().unwrap());
|
||||||
chains.push(maybe_chain);
|
chains.push(maybe_chain);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
numbers[next] = false;
|
current = next;
|
||||||
maybe_chain.push(num);
|
|
||||||
|
|
||||||
num = next;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
i += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
dbg!(chains);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_proper_divisors(x: usize) -> impl Iterator<Item = usize> {
|
fn get_proper_divisors(x: usize) -> impl Iterator<Item = usize> {
|
||||||
let limit = x / 2 + 1;
|
let limit = x / 2 + 1;
|
||||||
(1..limit).filter(move |i| x % *i == 0)
|
(1..limit).filter(move |i| x % *i == 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
|
||||||
|
use rstest::rstest;
|
||||||
|
|
||||||
|
#[rstest]
|
||||||
|
#[case(6, vec![1, 2, 3])]
|
||||||
|
#[case(28, vec![1, 2, 4, 7, 14])]
|
||||||
|
#[case(12_496, vec![1, 2, 4, 8, 11, 16, 22, 44, 71, 88, 142, 176, 284, 568, 781, 1136, 1562, 3124, 6248])]
|
||||||
|
fn proper_divisor(#[case] input: usize, #[case] expected: Vec<usize>) {
|
||||||
|
use crate::get_proper_divisors;
|
||||||
|
|
||||||
|
assert_eq!(get_proper_divisors(input).collect::<Vec<_>>(), expected);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[rstest]
|
||||||
|
#[case(220, vec![vec![220, 284]])]
|
||||||
|
#[case(12_496, vec![vec![12_496, 14_288, 15_472, 14_536, 14_264]])]
|
||||||
|
fn chain(#[case] input: usize, #[case] expected: Vec<Vec<usize>>) {
|
||||||
|
use std::collections::HashSet;
|
||||||
|
|
||||||
|
use crate::try_build_chain_from_number;
|
||||||
|
|
||||||
|
let max = expected.iter().flatten().max().unwrap().to_owned();
|
||||||
|
let mut part_of_any_chain = HashSet::new();
|
||||||
|
|
||||||
|
let mut chains = vec![];
|
||||||
|
try_build_chain_from_number(max, input, &mut chains, &mut part_of_any_chain);
|
||||||
|
|
||||||
|
assert_eq!(chains, expected);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user