銀の光と碧い空

クラウドなインフラとC#なアプリ開発の狭間にいるエンジニアの日々

Microsoft Q# Coding Contest – Summer 2020の復習(3) 状態の生成

本日はC1 |01⟩ + |10⟩ + |11⟩状態の生成です。

https://codeforces.com/contest/1356/problem/C

Q#では任意の状態を作る操作が用意されていますが、問題の条件にPauliX,Y,Zゲート、Hゲートおよびそれらのcontrolledバージョンのみが利用可能です。そして、問題の注にもある通り、以前のCoding Contestの問題であり、Quantum Katasに入っている問題とよく似ています。

QuantumKatas/Tasks.qs at master · microsoft/QuantumKatas · GitHub

以前の問題は|00⟩ + |01⟩ + |10⟩ という状態を作っているので、この状態を作ったあと、Xゲートを適用すればOKです。今回は解説に書いている事後選択(post-selection)とある方法を使って実装しました。Q#では repeat~until~fixup 構文により、ある条件を満たすまで一連の操作を試みる(=都合のいい状態を事後で選択できる。当たるまでまわせばガチャはあたる)ことができます。

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

    operation Solve (qs : Qubit[]) : Unit {
        using (ancilla = Qubit()) {
            repeat {
                // |00⟩ + |01⟩ + |10⟩ + |11⟩ 状態を作る
                ApplyToEach(H, qs);
                // (|00⟩ + |01⟩ + |10⟩) ⊗ |0⟩ + |11⟩ ⊗ |1⟩ 状態を作る
                Controlled X(qs, ancilla);
                //  (|11⟩ + |10⟩ + |01⟩) ⊗ |0⟩ + |00⟩ ⊗ |1⟩ 状態にする
                ApplyToEach(X, qs);
                // 測定して|0⟩のときだけ残すようにする
                let res = MResetZ(ancilla);
            }
            until (res == Zero)
            fixup {
                ResetAll(qs);
            }
        }
    }
}

次回が量子機械学習と新しいテーマなので今回は短いですがここまでです。