paizaラーニングレベルアップ問題集のFizz Buzz (paizaランク C 相当)をやってみた

paiza×Qiita記事投稿キャンペーンということで、paizaラーニングレベルアップ問題集の[Fizz Buzz (paizaランク C 相当)](https://paiza.jp/works/mondai/c_rank_skillcheck_sample/fizz-buzz)をやってみました。言語はPython3です。

ちなみに、[Dランクレベルアップメニュー](https://paiza.jp/works/mondai/d_rank_level_up_problems/d_rank_level_up_problems__loop_boss)にもあるのですが、こちらは
- 入力値なし（$N=100$で固定）
- `Fizz`と`Buzz`の間に半角空白なし

となっております。
- - -
- サンプルプログラム（Python3）

    ```py
    n = int(input())
    for i in range(1, n + 1):
        if i % 3 == 0 and i % 5 == 0:
            print("Fizz Buzz")
        elif i % 3 == 0:
            print("Fizz")
        elif i % 5 == 0:
            print("Buzz")
        else:
            print(i)
    ```
    - 1行目にて、整数値$N$を標準入力から受け取ります。
    - 今回は$i=1,2,...,N$について処理していくので、`for i in range(1,n+1)`とします。
    - あとは、問題文に従って
        - 3の倍数かつ5の倍数のときには、"Fizz Buzz"
        - 3の倍数のときには、"Fizz"
        - 5の倍数のときには、"Buzz"
        - 上記以外のときには、数値
    を1から順に表示していきます。
- - -
- 別解1
    `and`を使わずに書くこともできます。
    ```py
    n = int(input())
    for i in range(1, n + 1):
        if i % 3 == 0:
            if i % 5 == 0:
                print("Fizz Buzz")
            else:
                print("Fizz")
        else:
            if i % 5 == 0:
                print("Buzz")
            else:
                print(i)
    ```

    改行無しの出力が容易な言語では、3で割り切れる判定をした直後に`Fizz`を出力するのもいいでしょう。（以下はJavaのサンプルです）
    ```java
    import java.util.*;
    
    public class Main {
        public static void main(String[] args) {
            Scanner sc = new Scanner(System.in);
            int n = sc.nextInt();
            sc.close();
            for (int i = 1; i <= n; i++) {
                if (i % 3 == 0) {
                    System.out.print("Fizz");
                    if (i % 5 == 0) {
                        System.out.print(" Buzz");
                    }
                } else if (i % 5 == 0) {
                    System.out.print("Buzz");
                } else {
                    System.out.print(i);
                }
                System.out.println();
            }
        }
    }
    ```

- - -
:::note warn
ここから先の内容は実務では非推奨と思われます。
:::
- 別解2
    PythonやC、C++等、一部の言語では、0はFalse、0以外はTrueとして扱われるので、先に「3で割り切れない、かつ5で割り切れない」を処理することにして、以下のように書くこともできます。
    ```py
    n = int(input())
    for i in range(1, n + 1):
        if i % 3 and i % 5:  # 3でも5でも割り切れない
            print(i)
        elif i % 3:  # 3で割り切れない（5では割り切れる）
            print("Buzz")
        elif i % 5:  # 5で割り切れない（3では割り切れる）
            print("Fizz")
        else:  # 3でも5でも割り切れる
            print("Fizz Buzz")
    ```
    ※JavaやC#では`if(i%3)`のような書き方はできません。
- - -
- 別解3
    Pythonでは、空文字列はFalse、1文字以上の文字列はTrueとして扱われます。
    更に、`or`演算子を用いて、`or`の前が`True`ならば`or`の後を処理しない、`or`の前が`False`ならば`or`の後を処理することを利用すれば、以下のように書くこともできます。（[短絡評価](https://ja.wikipedia.org/wiki/%E7%9F%AD%E7%B5%A1%E8%A9%95%E4%BE%A1)）
    ```py
    n = int(input())
    for i in range(1, n + 1):
        s = ""
        if i % 3 == 0:
            s += "Fizz"
            if i % 5 == 0:
                s += " "
        if i % 5 == 0:
            s += "Buzz"
        print(s or i)  # sが空文字ならiを、sが空文字でなければsを出力する
    ```
    上記の内容と内包表記を使えば、一行で書けてしまったりします。
    ```py
    print(*[(("Fizz"if i%3==0else"")+" "+("Buzz"if i%5==0else "")).strip()or i for i in range(1,int(input())+1)],sep="\n")
    ```
    更に、PythonやC、C++では、Trueは1、Falseは0と評価されるので、配列の添字に入れたりしてこんな書き方もできます。
    ```py
    print(*[(["","Fizz"][i%3==0]+" "+["","Buzz"][i%5==0]).strip() or i for i in range(1,int(input())+1)],sep="\n")
    ```
    Pythonでは、`文字列*整数`は`文字列`の`整数`回繰り返しになります。
    ```py
    print(*[("Fizz"*(i%3==0)+" "+"Buzz"*(i%5==0)).strip() or i for i in range(1,int(input())+1)],sep="\n")
    ```
　
あとは[コードゴルフ](https://ja.wikipedia.org/wiki/%E3%82%B3%E3%83%BC%E3%83%89%E3%82%B4%E3%83%AB%E3%83%95)ァーの方に短くしていただきましょう。
（真ん中の`+" "+`をどちらかに寄せるとか、$i=0$から始めて`i%3==0`の部分を`i%3>1`にするとか`or i`を`or-~i`にするとかかんとか）
- - -
今は[ChatGPT](https://chatgpt.com/)に「標準入力」「FizzBuzz」と言語名を入れればサンプルプログラムが出る時代ですね（ChatGPTの回答は必ずご自身で確かめてください）。