<commit_before>// Genetic Algorithm for convergence to a given string
// Author: <NAME>
extern crate rand;
use rand::Rng;
extern crate time;
use time::PreciseTime;

fn rand_string(size: usize) -> String {
    return rand::thread_rng().gen_ascii_chars().take(size).collect();
}

fn crossover(chrome1: Chromosome, chrome2: Chromosome, cross_prob: f32, solution: &str) -> Chromosome {
    if rand::thread_rng().gen_range::<f32>(0.0, 1.0) <= cross_prob {
        let code_len = chrome1.code.len();
        let rand_index = rand::thread_rng().gen_range(0, code_len);
        let first_half = &chrome1.code[0..rand_index];
        let second_half = &chrome2.code[rand_index..code_len];
        let new_code = first_half.to_string() + second_half;
        Chromosome {
            code: new_code.to_string(),
            cost_score: cost_function(&new_code, solution),
            solution: solution.to_string(),
        }
    } else if chrome1.cost_score < chrome2.cost_score {
        chrome1.clone()
    } else {
        chrome2.clone()
    }
}


fn cost_function(code: &str, solution: &str) -> u32 {
    let chars = solution.as_bytes();
    let code_chars = code.as_bytes();
    let mut cost: u32 = 0;
    for i in 0..chars.len() {
        cost += ((chars[i] as i32) - (code_chars[i] as i32)).abs() as u32;
    }
    return cost;
}


#[derive(Clone)]
struct Chromosome {
    code: String,
    cost_score: u32,
    solution: String,
}

impl Chromosome {
    fn new(solution: String) -> Chromosome {
        let random_string = rand_string(solution.len());
        Chromosome {
            code: random_string.clone(),
            cost_score: cost_function(&random_string, &solution),
            solution: solution,
        }
    }

    fn mutate(&mut self, mut_prob:f64) -> Chromosome {
        if rand::thread_rng().gen_range::<f64>(0.0, 1.0) <= mut_prob {
            let rand_index = rand::thread_rng().gen_range(0, self.code.len());
            let mut new_code_vec: Vec<char> = self.code.chars().collect();
            new_code_vec[rand_index] = rand::thread_rng().gen_range(32, 123) as u8 as char;
            self.code = new_code_vec.iter().fold("".to_string(), |acc, s| acc + &s.to_string());
            self.cost_score = cost_function(&self.code, &self.solution);
            self.clone()

        } else {
            self.clone()
        }

    }


}


fn main() {
    let solution = "Tom looks tired".to_string();
    let pop_size = 160; // Must be greater than 1
    let max_pop = pop_size * 1;
    let mut_prob = 0.3;
    let kill_constant = 0.45;
    let cross_prob = 0.5;
    let mut population = Vec::new();<commit_msg>Simplified Chromosome::mutate<commit_after>// Genetic Algorithm for convergence to a given string
// Author: <NAME>
extern crate rand;
use rand::Rng;
extern crate time;
use time::PreciseTime;

fn rand_string(size: usize) -> String {
    return rand::thread_rng().gen_ascii_chars().take(size).collect();
}

fn crossover(chrome1: Chromosome, chrome2: Chromosome, cross_prob: f32, solution: &str) -> Chromosome {
    if rand::thread_rng().gen_range::<f32>(0.0, 1.0) <= cross_prob {
        let code_len = chrome1.code.len();
        let rand_index = rand::thread_rng().gen_range(0, code_len);
        let first_half = &chrome1.code[0..rand_index];
        let second_half = &chrome2.code[rand_index..code_len];
        let new_code = first_half.to_string() + second_half;
        Chromosome {
            code: new_code.to_string(),
            cost_score: cost_function(&new_code, solution),
            solution: solution.to_string(),
        }
    } else if chrome1.cost_score < chrome2.cost_score {
        chrome1.clone()
    } else {
        chrome2.clone()
    }
}


fn cost_function(code: &str, solution: &str) -> u32 {
    let chars = solution.as_bytes();
    let code_chars = code.as_bytes();
    let mut cost: u32 = 0;
    for i in 0..chars.len() {
        cost += ((chars[i] as i32) - (code_chars[i] as i32)).abs() as u32;
    }
    return cost;
}


#[derive(Clone)]
struct Chromosome {
    code: String,
    cost_score: u32,
    solution: String,
}

impl Chromosome {
    fn new(solution: String) -> Chromosome {
        let random_string = rand_string(solution.len());
        Chromosome {
            code: random_string.clone(),
            cost_score: cost_function(&random_string, &solution),
            solution: solution,
        }
    }

    fn mutate(&mut self, mut_prob:f64) -> Chromosome {
        if rand::thread_rng().gen_range::<f64>(0.0, 1.0) <= mut_prob {
            let rand_index = rand::thread_rng().gen_range(0, self.code.len());
            let mut code_vec = self.code.clone().into_bytes();
            code_vec[rand_index] = rand::thread_rng().gen_range(32, 123) as u8;
            self.code = String::from_utf8(code_vec).unwrap();
            self.cost_score = cost_function(&self.code, &self.solution);
        }
        self.clone()
    }


}


fn main() {
    let solution = "Tom looks tired".to_string();
    let pop_size = 160; // Must be greater than 1
    let max_pop = pop_size * 1;
    let mut_prob = 0.3;
    let kill_constant = 0.45;
    let cross_prob = 0.5;
    let mut population = Vec::new();
{'fraction_non_alphanumeric': 0.14004249565385357, 'fraction_numerical': 0.023372609619470738, 'mean_word_length': 2.6464788732394364, 'pattern_counts': {'":': 0, '<': 16, '<?xml version=': 0, '>': 20, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6556832', 'n_tokens_mistral': 1846, 'n_tokens_neox': 1718, 'n_words': 391}