use std::collections::HashSet;
use itertools::Itertools;
use std::iter;
use std::sync::Arc;
use std::time::{SystemTime, UNIX_EPOCH};
use std::thread;
fn permute(arr: &mut [i32; 5], start: usize, vettore: &mut Vec<[i32; 5]>) {
if start == arr.len() {
vettore.push(*arr);
return;
}
for i in start..arr.len() {
arr.swap(start, i);
permute(arr, start + 1, vettore);
arr.swap(start, i);
}
}
fn permute_operators<'a>(arr: &mut [&'a str; 4], start: usize, vettore: &mut Vec<[&'a str; 4]>) {
if start == arr.len() {
vettore.push(*arr);
return;
}
for i in start..arr.len() {
arr.swap(start, i);
permute_operators(arr, start + 1, vettore);
arr.swap(start, i);
}
}
fn permute_with_repetition<'a>(arr: &[&'a str], k: usize, buffer: &mut Vec<&'a str>, result: &mut Vec<Vec<&'a str>>){
if k == 0 {
result.push(buffer.clone());
} else {
for i in 0..arr.len() {
buffer.push( arr[i]);
permute_with_repetition(arr, k - 1, buffer, result);
buffer.pop();
}
}
}
//funzione per calcolare se quella combinazione è corretta
fn calculate_results(vettore: Vec<[i32; 5]>, all_operator_combinations: Vec<Vec<&str>>) -> Vec<Vec<String>> {
let mut results = Vec::new();
let mut result = 0;
let mut flag = 0;
for j in vettore.iter(){
for k in all_operator_combinations.iter(){
for w in 0..5{
if flag == 1 {
continue;
}
if w==0{
result = j[0];
}else{
match k[w-1] {
"+" => result += j[w],
"-" => result -= j[w],
"*" => result *= j[w],
"/" if ((j[w] != 0 && result % j[w] == 0) || (j[w] == 1) ) => {
result /= j[w]
},
_ => {
flag = 1
},
}
}
}
if result == 10 && flag != 1 {
let equation = format!("{}{}{}{}{}{}{}{}{}", j[0], k[0], j[1], k[1], j[2], k[2], j[3], k[3], j[4]);
results.push(vec![equation]);
}
result = 0;
flag = 0;
}
}
results
}
fn main() {
let mut vettore : Vec<[i32; 5]> = Vec::new();
let mut arr = [2, 7, 2, 2, 1];
permute(&mut arr, 0, &mut vettore);
/*println!("ciao");
for i in vettore.iter() {
println!("{:?}", i);
}*/
let mut set = HashSet::new();
let mut i = 0;
while i < vettore.len() {
let row = vettore[i];
if set.contains(&row) {
vettore.remove(i);
} else {
set.insert(row);
i += 1;
}
}
/*println!("ciao");
for i in vettore.iter() {
println!("{:?}", i);
}*/
let mut operators : Vec<[&str; 4]> = Vec::new();
let mut op = ["+", "-", "*", "/"];
permute_operators(&mut op, 0, &mut operators);
//let operators = ["+", "-", "*", "/"];
//let all_operator_combinations: Vec<Vec<&str>> = operators.iter().copied().combinations_with_replacement(4).collect();
//println!("{:?}", all_operator_combinations);
let operators = ["+", "-", "*", "/"];
let mut all_operator_combinations: Vec<Vec<&str>> = Vec::new();
for k in 1..=operators.len() {
let mut buffer = Vec::with_capacity(k);
permute_with_repetition(&operators, k, &mut buffer, &mut all_operator_combinations);
}
i = 0;
while i < all_operator_combinations.len() {
let row = all_operator_combinations[i].len();
if row < 4 {
all_operator_combinations.remove(i);
}else{
i += 1;
}
}
//println!("{:?}", all_operator_combinations.len());
let start_time = SystemTime::now();
let since_epoch = start_time.duration_since(UNIX_EPOCH).unwrap();
let nanos = since_epoch.as_nanos();
let lunghezza = vettore.len();
let divisione = lunghezza / 4;
let resto = lunghezza % 4;
let mut inizio = 0;
let mut fine = divisione+resto;
let arc_vettore = Arc::new(vettore);
let arc_operatori = Arc::new(all_operator_combinations);
let mut handles = Vec::new();
for i in 0..1 {
let arc1_clone = Arc::clone(&arc_vettore);
let arc2_clone = Arc::clone(&arc_operatori);
//let vettore1 = &vettore[inizio..fine];
let handle1 = thread::spawn(move || {
//let result = calculate_results(Vec::from(&vettore[inizio..fine]), all_operator_combinations1);
let mut results = Vec::new();
let mut result = 0;
let mut flag = 0;
for j in vettore1.iter(){
for k in arc2_clone.iter(){
for w in 0..5{
if flag == 1 {
continue;
}
if w==0{
result = j[0];
}else{
match k[w-1] {
"+" => result += j[w],
"-" => result -= j[w],
"*" => result *= j[w],
"/" if ((j[w] != 0 && result % j[w] == 0) || (j[w] == 1) ) => {
result /= j[w]
},
_ => {
flag = 1
},
}
}
}
if result == 10 && flag != 1 {
let equation = format!("{}{}{}{}{}{}{}{}{}", j[0], k[0], j[1], k[1], j[2], k[2], j[3], k[3], j[4]);
results.push(vec![equation]);
}
result = 0;
flag = 0;
}
}
results
});
handles.push(handle1);
inizio += divisione;
fine += divisione;
}
for handle in handles{
let result = handle.join().unwrap();
println!("{:?}", result);
}
/*
let lunghezza = vettore.len();
let divisione = lunghezza / 4;
let resto = lunghezza % 4;
let vettore1 = Vec::from(&vettore[..divisione+resto]);
let vettore2 = Vec::from(&vettore[divisione+resto..divisione+resto+divisione]);
let vettore3 = Vec::from(&vettore[divisione+resto+divisione..divisione+resto+divisione+divisione]);
let vettore4 = Vec::from(&vettore[divisione+resto+divisione+divisione..]);
let all_operator_combinations1 = all_operator_combinations.clone();
let all_operator_combinations2 = all_operator_combinations.clone();
let all_operator_combinations3 = all_operator_combinations.clone();
let all_operator_combinations4 = all_operator_combinations.clone();
let handle1 = thread::spawn(move || {
let result = calculate_results(vettore1, all_operator_combinations1);
result
});
let handle2 = thread::spawn(move || {
let result = calculate_results(vettore2, all_operator_combinations2);
result
});
let handle3 = thread::spawn(move || {
let result = calculate_results(vettore3, all_operator_combinations3);
result
});
let handle4 = thread::spawn(move || {
let result = calculate_results(vettore4, all_operator_combinations4);
result
});
let result1 = handle1.join().unwrap();
let result2 = handle2.join().unwrap();
let result3 = handle3.join().unwrap();
let result4 = handle4.join().unwrap();
let mut result = Vec::new();
result.extend(result1);
result.extend(result2);
result.extend(result3);
result.extend(result4);
println!("{}", result.len());
*/
//let result = calculate_results(vettore, all_operator_combinations);
//println!("{}", result.len());
let start_time = SystemTime::now();
let since_epoch = start_time.duration_since(UNIX_EPOCH).unwrap();
let nanos2 = since_epoch.as_nanos();
//Stampa tempo trascorso
println!("{}", nanos2-nanos);
/*
let mut result = 0;
let mut flag = 0;
for j in vettore.iter(){
for k in all_operator_combinations.iter(){
for w in 0..5{
if flag == 1 {
continue;
}
if w==0{
result = j[0];
}else{
match k[w-1] {
"+" => result += j[w],
"-" => result -= j[w],
"*" => result *= j[w],
"/" if ((j[w] != 0 && result % j[w] == 0) || (j[w] == 1) ) => {
result /= j[w]
},
_ => {
flag = 1
},
}
}
}
if result == 10 && flag != 1{
println!("Stringa corretta trovata {}{}{}{}{}{}{}{}{}", j[0], k[0], j[1], k[1], j[2], k[2], j[3], k[3], j[4]);
}
result = 0;
flag = 0;
}
}
*/
}