Rust - chapter 8 quiz


8 챕터 마지막 정리에 퀴즈가 있었다. 쉽겠거니 했는데 나한테는 생각보다 어려웠다. 🥶
풀기는 지난주에 풀었는데 정리차 올려본다. 링크 최하단에서 확인이 가능하다.
&, * 로 그리고 소유권 등 평소 사용하지 않는 개념이다 보니 확실히 낯설었다.

불과 지난주에 작성한 건데 정리하면서 다시보니 놓친부분이나 고칠 부분이 보인다. 얼마나 대충 작성했던 거야… 💩

코드가 이상해도.. 봐주십셔. 문제되는 부분이나 개선점은 메일로 보내주시면 정말 감사드리겠습니다!

원문링크

퀴즈 1

정수리스트가 주어졌을 때 평균값, 중간값, 최빈값을 구하라.

입력으로 받아서 할까 하다가 코드 내에 직접 넣어서 작업하였다.
하는 김에 최대값, 최솟값도 추가하였다.

use std::collections::HashMap;

fn main() {
   let temp_integers = vec![1,2,3,4,5,5,6,6,7,8,9,10];

    println!("Max: {}", match max(&temp_integers) {
        Some(max) => max.to_string(),
        None => "Vector is empty".to_string(),
    });

    println!("Min: {}", match min(&temp_integers) {
        Some(min) => min.to_string(),
        None => "Vector is empty".to_string(),
    });

    println!("Mean: {}", match mean(&temp_integers) {
        Some(mean) => mean.to_string(),
        None => "Vector is empty".to_string(),
    });

    println!("Median: {}", match median(&temp_integers) {
        Some(median) => median.to_string(),
        None => "Vector is empty".to_string(),
    });

    mode(&temp_integers);
}

fn max(temp_vec: &Vec<i32>) -> Option<i32> {
    let mut max = None;
    for i in temp_vec {
        if max.is_none() {
            max = Some(*i);
        } else {
            if *i > max.unwrap() {
                max = Some(*i);
            }
        }
    }
    max
}

fn min(temp_vec: &Vec<i32>) -> Option<i32> {
    let mut min = None;
    for i in temp_vec {
        if min.is_none() {
            min = Some(*i);
        } else {
            if *i < min.unwrap() {
                min = Some(*i);
            }
        }
    }
    min
}

fn mean(temp_vec: &Vec<i32>) -> Option<f32> {
    if temp_vec.len() == 0 {
        return None;
    }

    let mut sum = 0.0;
    for i in temp_vec {
        sum += *i as f32;
    }

    Some(sum / temp_vec.len() as f32)
}

fn median(temp_vec: &Vec<i32>) -> Option<i32> {
    if temp_vec.len() == 0 {
        return None;
    }

    let mut cloned_vec = temp_vec.clone();
    cloned_vec.sort();

    Some(cloned_vec[cloned_vec.len() / 2])
}

fn mode(temp_vec: &Vec<i32>) {
    if temp_vec.len() == 0 {
        println!("Vector is empty");
        return;
    }

    let mut map: HashMap<i32, i32> = HashMap::new();
    let mut max_count = 0;

    for i in temp_vec {
        let count = map.entry(*i).or_insert(0);
        *count += 1;
        if *count > max_count {
            max_count = *count;
        }
    }

    let mut result = map.iter().filter(|&(_, v)| v == &max_count).map(|(k, _)| k).collect::<Vec<&i32>>();
    result.sort();

    println!("Mode: {:?}", result);
}

퀴즈 2

스트링을 피그 라틴으로 변경하라.

첫 자음을 따서 단어 뒤에 -${첫자음}ay 이런식의 문자열을 붙여서 리턴하고 첫글자가 모음일 경우에는 -hay 를 붙여 리턴하는 프로그램이다.
rust 에 ? : 형태의 삼항연산자는 없는 것 같다. 못 찾았다.

fn main() {
    const VOWELS: &str = "aeiou";
    println!("Enter a word for Pig-Latin(Only English): ");
    let mut input_text = String::new();
    std::io::stdin().read_line(&mut input_text).expect("Failed to read line");

    if input_text.trim().is_empty() {
        println!("Input is empty");
        return;
    }

    let mut result = String::new();
    let input_text_length = input_text.len();
    let start_char = &input_text[0..1];

    result = if VOWELS.contains(start_char) { format!("{}-hay", input_text.trim()) }
        else { format!("{}-{}ay", &input_text[1..].trim(), start_char) };

    println!("Pig Latin: {}", result);
}

퀴즈 3

회사 내 부서에 사람을 추가하고 확인 할 수 있는 텍스트 인터페이스를 만들어라.

예제에 주어진 형태로 명령문을 만들어서 작업하였다.
삭제하는 명령 추가 작업하였다. 코드를 보면 어질어질한데 뭔가 생각나는 방법이 없어서 일단 여기까지만 작업하였다.

use std::collections::HashMap;

fn main() {
    print_manual();

    let mut company_db: HashMap<String, Vec<String>> = HashMap::new();

    loop {
        let mut command = String::new();

        println!("Enter your command: ");
        std::io::stdin().read_line(&mut command).expect("Failed to read line");
        if command.trim() == "Exit" {
            break;
        }
        if command.trim() == "Show all" {
            println!("{:?}", company_db);
        } else {
            let command_split: Vec<&str> = command.split(" ").collect();
            let command_type = command_split[0];

            if command_type == "Add" {
                let command_name = command_split[1];
                let command_department = command_split[3].trim();
                let mut employees = company_db.entry(command_department.to_string()).or_insert(Vec::new());
                employees.push(command_name.to_string());
            } else if command_type == "Remove" {
                let command_name = command_split[1];
                let command_department = command_split[3].trim();
                let mut employees = company_db.entry(command_department.to_string()).or_insert(Vec::new());
                employees.retain(|x| x != command_name);
            } else if command_type == "Show" {
                let command_department = command_split[1].trim();
                let employees = company_db.get(command_department);
                if employees.is_some() {
                    println!("{:?}", employees.unwrap());
                } else {
                    println!("No employees in this department");
                }
            } else {
                println!("Invalid command");
            }
        }
    }
}

fn print_manual() {
    println!("> Company data text editor is running!!!!");
    println!("> Use 'Add  to ' to insert");
    println!("> Use 'Remove  to ' to delete");
    println!("> Use 'Show ' to select specific department");
    println!("> Use 'Show all' to select all");
    println!("> Use 'Exit' to quit this program");
}

개인이 참고하고자 작성한 글이며, 잘못된 정보가 있을 수 있습니다. 잘못된 정보는 메일로 보내주시면 감사하겠습니다. 🙏