解答

// 著作権 2023 Google LLC
// SPDX-License-Identifier: Apache-2.0

/// Determine the length of the collatz sequence beginning at `n`.
fn collatz_length(mut n: i32) -> u32 {
    let mut len = 1;
    while n > 1 {
        n = if n % 2 == 0 { n / 2 } else { 3 * n + 1 };
        len += 1;
    }
    len
}

fn main() {
    println!("Length: {}", collatz_length(11)); // should be 15
}

この解答では、いくつかの重要な Rust の機能を示しています。

  • mut 引数: n 引数は mut n として宣言されています。これにより、ローカル変数 n は関数スコープ内で可変になります。整数は値渡しされる Copy 型であるため、これは呼び出し元の値には影響しません。
  • if 式: Rust の if は式であり、値を生成することを意味します。if/else ブロックの結果を直接 n に代入しています。これは、各分岐の中で n = ... と書くよりも簡潔です。
  • 暗黙の return: 関数は len で終わっており(セミコロンなし)、これが自動的に返されます。
  • Collatz 数列が有効であるためには、n は厳密に 0 より大きくなければならないことに注意してください。関数シグネチャは i32 を受け取りますが、問題文は正の整数を想定しています。より堅牢な実装では u32 を使うか、無効な入力(0 または負の数)を処理するために Option または Result を返すかもしれませんが、ここでは n <= 0 の場合に panic や無限ループが起こる可能性があります。
  • Fibonacci の演習と同様に、n が大きくなりすぎるとオーバーフローが潜在的な問題になります。