Skip to content

Instantly share code, notes, and snippets.

@RedL0tus
Created October 29, 2019 07:53
Show Gist options
  • Save RedL0tus/83314727f5268e25c3f1706e4aa8efdf to your computer and use it in GitHub Desktop.
Save RedL0tus/83314727f5268e25c3f1706e4aa8efdf to your computer and use it in GitHub Desktop.
USAMTS - 3/2/31: Brute force
#!/usr/bin/env run-cargo-script
//! USAMTS - 3/2/31
//!
//! ```cargo
//! [dependencies]
//! num = "~0.2"
//! ```
const LIMIT: u128 = 100;
const NUM_THREADS: usize = 8;
extern crate num;
use num::abs;
use num::Integer;
use std::fmt;
use std::thread;
use std::collections::HashMap;
#[derive(Clone, Copy, Debug)]
struct Source {
a: u128,
b: u128,
c: u128,
d: u128,
m: u128,
}
impl Source {
fn new(a: u128, b: u128, c: u128, d:u128, m: u128) -> Self {
Self {
a,
b,
c,
d,
m,
}
}
}
impl fmt::Display for Source {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "a: {}, b: {}, c: {}, d: {}, m: {}", self.a, self.b, self.c, self.d, self.m)
}
}
#[derive(Default, Debug)]
struct ResultSet {
start: u128,
stop: u128,
count: usize,
set: HashMap<i128, Vec<Source>>,
}
impl ResultSet {
fn new(start: u128, stop: u128, count: usize) -> Self {
Self {
start,
stop,
count,
..Default::default()
}
}
fn is_empty(&self) -> bool {
return self.set.is_empty();
}
fn add_result(&mut self, result: i128, source: Source) {
let mut source_set: Vec<Source> = if let Some(temp) = self.set.get(&result) {
temp.clone()
} else {
println!("New result: {}", result);
Vec::new()
};
source_set.push(source);
self.set.insert(result, source_set);
}
}
impl fmt::Display for ResultSet {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
if self.is_empty() {
write!(f, "No result from thread {} ({} to {})\n", self.count, self.start, self.stop)
} else {
let output: String = self.set.iter().map(|(key, value)| {
let mut count: u128 = 0;
let sources: String = value.iter().map(|source| {
count += 1;
format!(" [ Count: {}, Source: ({}) ]\n", count, source)
}).collect();
format!(" Result: {}, Sources ({} total):\n{}", key, value.len(), sources)
}).collect::<String>();
write!(f, "Result from thread {} ({} to {}):\n{}", self.count, self.start, self.stop, output)
}
}
}
fn run(start: u128, stop: u128, count: usize) -> ResultSet {
let mut result_set = ResultSet::new(start, stop, count);
for m in start..stop {
for a in 1..m {
for b in 1..a {
for c in 1..b {
for d in 1..c {
if ((a * m + b) as i128).gcd(&((c * m + d) as i128)) == 2019 {
let result: i128 = abs((a * d - b * c) as i128);
let source = Source::new(a, b, c, d, m);
result_set.add_result(result, source);
}
}
}
}
}
}
result_set
}
fn main(){
let limit_per_thread: u128 = LIMIT / ((NUM_THREADS - 1) as u128);
let handles: Vec<thread::JoinHandle<ResultSet>> = (1..NUM_THREADS).map(|count| {
println!("Initializing thread {}", count);
thread::spawn(move || {
run(limit_per_thread * ((count as u128)- 1), limit_per_thread * (count as u128), count)
})
}).collect();
let mut results: Vec<ResultSet> = handles.into_iter().map(|handle| {
handle.join().expect("WTF???")
}).collect();
results.push(run(limit_per_thread * ((NUM_THREADS - 1) as u128), LIMIT, NUM_THREADS));
println!("\n === Calculation finished === \n");
for result in results {
println!("{}", result);
}
println!("All done!");
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment