0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

可変長の積を取るマクロ

Posted at

Rustでは関数で可変長引数を直接扱うことができないため、マクロを使って実現する必要があります。この記事では、可変長の引数を受け取って積を求めるマクロを紹介し、競技プログラミング向けに改造する方法も合わせて解説します。

可変長引数の積を求める基本マクロ

まずは、受け取った引数すべての積を求める基本的なマクロを紹介します。

#[macro_export]
macro_rules! product {
    ($( $x:expr ),* ) => {{
        let mut result = 1;
        $(
            result = result * $x;
        )*
        result
    }};
}

fn main() {
    assert_eq!(product!(2), 2);
    assert_eq!(product!(2, 3), 6);
    assert_eq!(product!(2, 3, 4), 24);
}

関数とは違い、マクロは引数の数に制限がないため、上記のように簡潔に記述できます。

競技プログラミング向けに MOD を加える

競技プログラミングでは、「ある素数で割った余り(mod)」を求める問題が頻出です。

例えば、次のような処理をよく見かけます:

let mut ret = 1;
ret *= a;
ret %= MOD;
ret *= b;
ret %= MOD;
ret *= c;
ret %= MOD;

あるいは、短く書いても次のようになります。

let ret = a * b % MOD * c % MOD;

このような記述は、冗長で読みにくい場合もあります。そこで、先ほどの product! マクロを少し改造して、MOD を使った積の計算を簡潔に行えるようにしましょう。

改良版:MODを含む積マクロ

以下のようにマクロを改良することで、積を計算しつつ各ステップで MOD を取ることができます。

const MOD: i128 = 1_000_000_007;

#[macro_export]
macro_rules! product {
    ($( $x:expr ),* ) => {{
        let mut result = 1;
        $(
            result = result * $x;
            result %= MOD; // ← ここが改造ポイント
        )*
        result
    }};
}

使い方はとてもシンプルです。

let a = 2;
let b = 3;
let c = 4;
let result = product!(a, b, c); // => 2 * 3 * 4 % MOD

環境情報

  • rustc 1.83.0 (90b35a623 2024-11-26)
  • cargo 1.83.0 (5ffbef321 2024-10-29)
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?