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);
}
}
}
}