paizaxQiitaコラボキャンペーン対象問題全部抜く Cランク編

## はじめに
paizaxQiitaコラボキャンペーンに参加して、対象問題をすべて解いてみました。
言語は全問題Rustで記述しました。

## 標準入力からの受け取りについて

Rustは標準入力の受け取りがめんどくさいと巷でよく言われています。
普段自分が遊んでいる競技プログラミングサイトでは`proconio`という偉大なるクレートを用いることができるためここら辺はストレスフリーなのですが、
残念ながらpaizaでは導入されていなかったため、proconioのソースから必要な一部分を拝借・修正して入力できるようにしています。(最小限のものだけとってきてるので簡易版です)

入力箇所のinputマクロは以下に記載しますが、問題の本質とはズレるので解答コードからは省略しています。


https://docs.rs/proconio/latest/proconio/


```rust
#!/usr/bin/env rust-script

use std::{collections::HashMap, io::Read};

macro_rules! input {
    (source = $s:expr, $($r:tt)*) => {
        let mut iter = $s.split_whitespace();
        input_inner!{iter, $($r)*}
    };
    ($($r:tt)*) => {
        let mut s = {
            let mut s = String::new();
            std::io::stdin().read_to_string(&mut s).unwrap();
            s
        };
        let mut iter = s.split_whitespace();
        input_inner!{iter, $($r)*}
    };
}

macro_rules! input_inner {
    ($iter:expr) => {};
    ($iter:expr, ) => {};

    ($iter:expr, $var:ident : $t:tt $($r:tt)*) => {
        let $var = read_value!($iter, $t);
        input_inner!{$iter $($r)*}
    };
}

macro_rules! read_value {
    ($iter:expr, ( $($t:tt),* )) => {
        ( $(read_value!($iter, $t)),* )
    };

    ($iter:expr, [ $t:tt ; $len:expr ]) => {
        (0..$len).map(|_| read_value!($iter, $t)).collect::<Vec<_>>()
    };

    ($iter:expr, chars) => {
        read_value!($iter, String).chars().collect::<Vec<char>>()
    };

    ($iter:expr, usize1) => {
        read_value!($iter, usize) - 1
    };

    ($iter:expr, $t:ty) => {
        $iter.next().unwrap().parse::<$t>().expect("Parse error")
    };
}

```

## 宝くじ

https://paiza.jp/works/mondai/c_rank_skillcheck_archive/lottery


<details><summary>私の解答</summary>


条件分岐の練習問題といったことでしょうか。
ちなみに、前後賞は当選番号の ±1 の番号ということで、100000 または 199999はコーナーケース考えなくちゃと思うかもしれませんが、
入力の制約といして100,000 ≦ a_i ≦ 199,999を満たしてくれているので特に何にも考えなくても大丈夫そうです。


```rust
fn main() {
    input! {
        b: usize,
        n: usize,
        a: [usize; n]
    }
    let b_second = &b.to_string()[2..];
    let b_third = &b.to_string()[3..];

    for &num in a.iter() {
        let second = &num.to_string()[2..];
        let third = &num.to_string()[3..];
        if num == b {
            println!("first");
        } else if num - 1 == b || num + 1 == b {
            println!("adjacent");
        } else if b_second == second {
            println!("second");
        } else if b_third == third {
            println!("third");
        } else {
            println!("blank");
        }
    }
}

```

</details>


## 野球の審判

https://paiza.jp/works/mondai/c_rank_skillcheck_archive/umpire

<details><summary>私の解答</summary>

制約としては3 ≦ N ≦ 6と小さいので計算量のことを何も気にしなくて良い問題なのですが、
気づいたらmapでストライク数、ボール数を管理する実装にしていました。
後々考えれば`strike_count`, `ball_count`だけで管理すればより簡潔に書けそうですが手癖でmapを使用していました。

```rust
fn main() {
    input! {
        n: usize,
        s: [String; n]
    }
    let mut map = HashMap::new();

    for word in s.into_iter() {
        let &count = map.get(&word).unwrap_or(&0usize);
        if word == "ball".to_string() {
            if count <= 2 {
                map.insert(word, count + 1);
                println!("ball!");
            } else {
                return println!("fourball!");
            }
        } else {
            if count <= 1 {
                map.insert(word, count + 1);
                println!("strike!");
            } else {
                return println!("out!");
            }
        }
    }
}

```

</details>

## みかんの仕分け 


https://paiza.jp/works/mondai/c_rank_skillcheck_archive/mikan


<details><summary>私の解答</summary>

上の箱に入れるか、下の箱に入れるかはその数のnでの余りをとってあげてその値が小さい方に入れてあげれば良いです。
0gの箱はないこと、二つの箱の差が等しい時には大きい方にいれるということを考慮して実装しています。


```rust
fn main() {
    input! {
        n: usize,
        m: usize,
        w: [usize; m]
    }
    for &num in w.iter() {
        let v1 = num % n;
        let v2 = n - v1;
        if v2 <= v1 || num - v1 == 0 {
            println!("{}", num + v2);
        } else {
            println!("{}", num - v1);
        }
    }
}
```

</details>


## Fizz Buzz

https://paiza.jp/works/mondai/c_rank_skillcheck_sample/fizz-buzz

<details><summary>私の解答</summary>

有名なFizz Buzzですね。
rustではmatch文で(5の余り, 3の余り)で分岐してあげればスッキリかけます。


```rust
fn main() {
    input! {
        n: usize,
    }

    for i in 1..=n {
        match (i % 3, i % 5) {
            (0, 0) => println!("Fizz Buzz"),
            (0, _) => println!("Fizz"),
            (_, 0) => println!("Buzz"),
            (_, _) => println!("{}", i),
        }
    }
}
```

</details>

## 残り物の量

https://paiza.jp/works/mondai/c_rank_skillcheck_archive/leftover

<details><summary>私の解答</summary>

算数問題ですね。
回答に小数入るのでf64で入力とります。


```rust
fn main() {
    input! {
        m: f64,
        p: f64,
        q: f64
    }

    let rest = (1.0 - p / 100.0) * m;
    let ans = (1.0 - q / 100.0) * rest;
    println!("{}", ans);
}
```

</details>


## まとめ・感想

この記事ではpaizaxQiitaコラボキャンペーン対象問題のCランク相当の問題5問を解きました。
CランクもDランクに引き続き易しい問題が多かったです。
プログラミング始めたての方とか新しい言語の始めの一歩にぴったりだなと思いました。

他のランクの問題も記事があるので併せて読んでいただけると嬉しいです！

https://qiita.com/haw_ohnuma/items/534541678945d6b33fc0

https://qiita.com/haw_ohnuma/items/e05532332128c2100139

https://qiita.com/haw_ohnuma/items/ca2f72c452792a353617

https://qiita.com/haw_ohnuma/items/12baf9f9d2a640f043c9