Untitled

mail@pastecode.io avatar
unknown
plain_text
2 years ago
9.7 kB
4
Indexable
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;
        }
    }
    */


}