Processing math: 0%
\def\bra#1{\mathinner{\left\langle{#1}\right|}} \def\ket#1{\mathinner{\left|{#1}\right\rangle}} \def\braket#1#2{\mathinner{\left\langle{#1}\middle|#2\right\rangle}}

◇◇Microsoft Q# Coding Contest – Summer 2020 B2 - "Is the number divisible by 3?" oracle◇◇


☆問題URL

https://codeforces.com/contest/1357/problem/B2

☆問題の概要

N桁の量子状態\ket{x}とqubit\ket{y}が与えられる。\ket{y}をオラクルqubitとして、\ket{x}を二進数で表示した場合に3の倍数となっている場合のみf(x)=1となるようなオラクルを作成せよ。

☆解法

ある十進数が3の倍数かどうかを判定するには桁和が3の倍数かどうかを調べればよいですが、二進数の場合の判定方法を考えます。

x = 3n+1であるような任意の整数xについて、2x = 6n+2であり、y = 3n+2であるような任意の整数yについて2y = 3(2n+1) + 1であることから、3の倍数でない整数では、2倍するごとに3で割った余りが1\rightarrow 2 \rightarrow 1 \rightarrow 2 \rightarrow \ldotsと変化していくことがわかります。

よって、ある二進数を3で割った余りを調べるためには、偶数桁めのbitが立っていれば1、奇数桁めのbitが立っていれば2をそれぞれ{\rm mod}\;3でカウントすればよく、整数を{\rm mod}\;3でインクリメントする演算は実装済なので、これを流用して実現できます。

これで、この問題が解けました。

☆ソースコード

                
namespace Solution {
    open Microsoft.Quantum.Canon;
    open Microsoft.Quantum.Intrinsic;

    operation Count (qs : Qubit[]) : Unit is Adj+Ctl
    {
        (ControlledOnInt(0, X))([qs[0]], qs[1]);
        (ControlledOnInt(0, X))([qs[1]], qs[0]);
    }

    operation Solve (inputs : Qubit[], output : Qubit) : Unit is Adj+Ctl
    {
        using (cnt = Qubit[2])
        {
            within
            {
                //各状態の整数を3で割ったあまりをカウントする
                for (idx in 0..Length(inputs) - 1)
                {
                    (Controlled Count)([inputs[idx]], cnt);
                    if (idx % 2 == 1)
                    {
                        (Controlled Count)([inputs[idx]], cnt);
                    }
                }
            }
            apply
            {
                //余りが0の状態のみoutputを反転させる
                (ControlledOnInt(0, X))(cnt, output);
            }
        }
    }
}
                
            

戻る