【Rust】vending machine(自販機)のプログラム

### 前準備
コンソールからの入力の受け取り

fn main() {
    println!("文字を入力してください:");

    let mut word = String::new();
    std::io::stdin().read_line(&mut word).ok();
    let answer = word.trim().to_string();

    println!("{}", answer);
}

文字を入力してください:
aaa
aaa

### お札、硬貨の枚数も合わせて返却する。
Hashmapにinsertするところは関数化したい

use std::collections::HashMap;
use itertools::Itertools;

fn cash_change(mut change: u32) -> HashMap<u32, u32> {
    let mut change_map: HashMap<u32, u32> = HashMap::new();
    if change / 5000 > 0 {
        change_map.insert(5000, change/5000);
        change = change % 5000;
    }
    if change / 1000 > 0 {
        change_map.insert(1000, change/1000);
        change = change % 1000;
    }
    if change / 500 > 0 {
        change_map.insert(500, change/500);
        change = change % 500;
    }
    if change / 100 > 0 {
        change_map.insert(100, change/100);
        change = change % 100;
    }
    if change / 50 > 0 {
        change_map.insert(50, change/50);
        change = change % 50;
    }
    if change / 10 > 0 {
        change_map.insert(10, change/10);
        change = change % 10;
    }
    if change > 0 {
        change_map.insert(1, change);
    }
    change_map
}

fn main() {
    println!("投入する金額を入力してください:");

    let mut word = String::new();
    std::io::stdin().read_line(&mut word).ok();
    let cash: u32 = word.trim().parse().expect("entered string was not a number");


    println!("商品の金額を入力してください:");
    let mut word = String::new();
    std::io::stdin().read_line(&mut word).ok();
    let price: u32 = word.trim().parse().expect("entered string was not a number");

    println!("お釣りは[{}]です。", cash - price);
    let mut change_map = cash_change(cash - price);
    let mut v: Vec<_> = change_map.into_iter().collect();
    v.sort_by(|x,y| y.0.cmp(&x.0));
    println!("{:?}", v);
}

Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.25s
Running `target/debug/rust`
投入する金額を入力してください:
1000
商品の金額を入力してください:
333
お釣りは[667]です。
[(500, 1), (100, 1), (50, 1), (10, 1), (1, 7)]

### もっと簡潔に

use std::collections::HashMap;
use itertools::Itertools;

fn cash_change(mut change: u32) -> HashMap<u32, u32> {
    let mut change_map: HashMap<u32, u32> = HashMap::new();
    let coin = vec![5000, 1000, 500, 100, 50, 10, 1];
    for i in coin {
        if change / i > 0 {
            change_map.insert(i, change/i);
            change = change % i;
        }
    }
    change_map
}

fn main() {
    println!("投入する金額を入力してください:");

    let mut word = String::new();
    std::io::stdin().read_line(&mut word).ok();
    let cash: u32 = word.trim().parse().expect("entered string was not a number");


    println!("商品の金額を入力してください:");
    let mut word = String::new();
    std::io::stdin().read_line(&mut word).ok();
    let price: u32 = word.trim().parse().expect("entered string was not a number");

    println!("お釣りは[{}]です。", cash - price);
    let mut change_map = cash_change(cash - price);
    let mut v: Vec<_> = change_map.into_iter().collect();
    v.sort_by(|x,y| y.0.cmp(&x.0));
    println!("{:?}", v);
}

Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.01s
Running `target/debug/rust`
投入する金額を入力してください:
3000
商品の金額を入力してください:
200
お釣りは[2800]です。
[(1000, 2), (500, 1), (100, 3)]

おおおおおおお、なるほど〜。同じ処理のところはイテレータにしてforループで回せば、より簡潔に書けますね。