共用方式為


教學課程:用Q#探索量子糾纏

在這個教學中,你會寫一個 Q# 程式,準備兩個處於特定量子態的量子位元,對這些量子位元進行操作使它們相互糾纏,並進行測量以展示疊加與糾纏的影響。 你要逐步建立 Q# 程式,以引入量子位元狀態、量子操作和測量。

在開始之前,請複習以下量子運算概念:

  • 傳統位會保留單一二進位值,例如 0 或 1,但量子位元可以處於兩種狀態 0 和 1 的疊加狀態。 每個可能的量子位元狀態都會由一組機率幅度描述。
  • 當您測量量子位元的狀態時,一律會得到 0 或 1。 每個結果的機率由測量時定義疊加狀態的機率振幅決定。
  • 多個量子位元可能會糾纏在一起,因此您無法彼此獨立地描述它們。 當您測量糾纏配對中的一個量子位元時,您也會取得另一個量子位元的相關資訊,而不進行測量。

在本教學課程中,您將瞭解如何:

  • 建立 Q# 作業,將量子位初始化為所需的狀態。
  • 將量子位元置於疊加狀態。
  • 糾纏一對量子位。
  • 測量量子位並觀察結果。

提示

如果您想要加速量子計算的旅程,請參閱 Azure 量子程式碼,這是 Microsoft Quantum 網站 的一個獨特功能。 在這裡,您可以執行內建 Q# 範例或您自己的 Q# 程式,從提示產生新 Q# 程式碼,一鍵在 VS Code 網頁版 中開啟並執行程式碼,並向 Copilot 詢問有關量子運算的問題。

必要條件

要用 Azure Quantum 的 Copilot 執行程式碼範例,必須擁有 Microsoft(MSA)電子郵件帳號。

如需 Azure Quantum 的 Copilot 的詳細資訊,請參閱 探索 Azure Quantum

將量子位初始化為已知狀態

第一步是定義一個 Q# 運算,將量子位元初始化為期望的經典狀態,為 0 或 1。 此操作測量一個處於一般量子態的量子位元,回傳Q#Result的型別值為ZeroOne或 。 若測量結果與期望狀態不同,則操作會將狀態反轉,使操作回傳期望狀態的 100%。

開啟 Azure Quantum 的 Copilot,清除預設程式碼,然後將以下程式碼複製到程式碼編輯器視窗。 你無法單獨執行這段程式碼,因為它還不是一個完整的 Q# 程式。

operation SetQubitState(desired : Result, target : Qubit) : Unit {
    if desired != M(target) {
        X(target);
    }
}

程式碼範例引入了兩個標準 Q# 操作, MX與 ,分別轉換量子位元的狀態。

以下是 SetQubitState 操作運作方式的詳細描述:

  1. 需要兩個參數:Result 型別參數,其命名為 desired,代表期望的量子位元狀態(ZeroOne),以及一個 Qubit 型別參數。
  2. 執行一個測量運算, M測量量子位元(ZeroOne)的狀態,並將結果與你通過的 desired值比較。
  3. 若測量結果與 的 desired值不符,則 X 會對量子位元進行操作。 此操作會將量子位元的狀態翻轉,從而反轉 ZeroOne 的測量機率。

撰寫測試操作以測試 Bell 狀態

要在程式SetQubitState中呼叫該Q#操作,請建立另一個名為 Main的操作。 此操作分配兩個量子位元,呼叫 SetQubitState 將第一個量子位元設定為已知狀態,然後測量量子位元以觀察結果。

操作結束 SetQubitState 後,將以下程式碼複製到程式碼編輯器視窗。

operation Main() : (Int, Int, Int, Int) {
    mutable numOnesQ1 = 0;
    mutable numOnesQ2 = 0;
    let count = 1000;
    let initial = One;

    // allocate the qubits
    use (q1, q2) = (Qubit(), Qubit());   
    for test in 1..count {
        SetQubitState(initial, q1);
        SetQubitState(Zero, q2);
        
        // measure each qubit
        let resultQ1 = M(q1);            
        let resultQ2 = M(q2);           

        // Count the number of 'Ones' returned:
        if resultQ1 == One {
            numOnesQ1 += 1;
        }
        if resultQ2 == One {
            numOnesQ2 += 1;
        }
    }

    // reset the qubits
    SetQubitState(Zero, q1);             
    SetQubitState(Zero, q2);
    

    // Display the times that |0> is returned, and times that |1> is returned
    Message($"Q1 - Zeros: {count - numOnesQ1}");
    Message($"Q1 - Ones: {numOnesQ1}");
    Message($"Q2 - Zeros: {count - numOnesQ2}");
    Message($"Q2 - Ones: {numOnesQ2}");
    return (count - numOnesQ1, numOnesQ1, count - numOnesQ2, numOnesQ2 );
}

在程式代碼中, countinitial 變數會分別設定為 1000One 。 這會將第一個量子位元初始化為 One,並測量每個量子位元 1000 次。

Main 工作會執行下列作業:

  1. 設定射擊次數(count)及初始量子位元狀態(One)變數。
  2. 呼叫 use 陳述式來初始化兩個量子位元。
  3. 重複進行實驗 count 次。
  4. 在迴圈中,呼叫 SetQubitState 將第一個量子位元的指定 initial 值設定為該狀態,然後再次呼叫 SetQubitState 將第二個量子位元設定為狀態 Zero
  5. 在迴圈中,應用 M 運算來測量每個量子位元,然後儲存每個量子位元回傳 One的測量次數。
  6. 迴圈結束後,再次呼叫 SetQubitState 量子位元以重置為已知狀態(Zero)。 你必須重置你用 use 語句分配的量子位元。
  7. 請呼叫 Message 函式以在輸出視窗中列印您的結果。

在適用於 Azure Quantum 的 Copilot 中執行程式碼

在撰寫疊加與糾纏的程式碼前,先測試你目前的程式,看看量子位元的初始化與測量情況。

要將你的程式碼當作獨立程式執行, Q# Copilot 的編譯器需要知道從哪裡開始程式。 因為你沒有指定命名空間,編譯器會將預設的入口點視為操作。Main 如需詳細資訊,請參閱 專案和隱含命名空間

你的 Q# 程式現在看起來是這樣的:

operation SetQubitState(desired : Result, target : Qubit) : Unit {
    if desired != M(target) {
        X(target);
    }
}

operation Main() : (Int, Int, Int, Int) {
    mutable numOnesQ1 = 0;
    mutable numOnesQ2 = 0;
    let count = 1000;
    let initial = One;

    // allocate the qubits
    use (q1, q2) = (Qubit(), Qubit());   
    for test in 1..count {
        SetQubitState(initial, q1);
        SetQubitState(Zero, q2);
        
        // measure each qubit
        let resultQ1 = M(q1);            
        let resultQ2 = M(q2);           

        // Count the number of 'Ones' returned:
        if resultQ1 == One {
            numOnesQ1 += 1;
        }
        if resultQ2 == One {
            numOnesQ2 += 1;
        }
    }

    // reset the qubits
    SetQubitState(Zero, q1);             
    SetQubitState(Zero, q2);
        
    
    // Display the times that |0> is returned, and times that |1> is returned
    Message($"Q1 - Zeros: {count - numOnesQ1}");
    Message($"Q1 - Ones: {numOnesQ1}");
    Message($"Q2 - Zeros: {count - numOnesQ2}");
    Message($"Q2 - Ones: {numOnesQ2}");
    return (count - numOnesQ1, numOnesQ1, count - numOnesQ2, numOnesQ2 );
}

將完整的程式碼範例複製貼上到 Copilot for Azure Quantum 的程式碼視窗,將射擊數量的滑桿設為「1」,然後選擇 執行。 結果會顯示在直方圖和 結果 欄位中。

Q1 - Zeros: 0
Q1 - Ones: 1000
Q2 - Zeros: 1000
Q2 - Ones: 0

你的程式還沒修改量子位元狀態,所以第一個量子位元的測量總是回傳 One,第二個量子位元總是回傳 Zero

如果你將 的 initial 值改為 並 Zero 再次執行程式,那麼第一個量子位元也會返回 Zero

Q1 - Zeros: 1000
Q1 - Ones: 0
Q2 - Zeros: 1000
Q2 - Ones: 0

將一個量子位元置於疊加態

目前,你程式中的量子位元處於經典狀態,可能是1或0,就像一般電腦上的位元一樣。 要糾纏這些量子位元,首先必須將其中一個量子位元置於相等疊加態。 在相等疊加態下測量量子位元有50%的機率回傳Zero,有50%的機率回傳One

要將量子位元置於疊加態,請使用 Q#H或 Hadamard 操作。 這個 H 操作會將處於純 Zero 態或 One 狀態的量子位元轉換成介於 ZeroOne之間的一種中間狀態。

請在 Main 操作中修改你的程式碼。 將初始值重設為 , One 並插入一行執行以下 H 操作:

for test in 1..count {
    use (q1, q2) = (Qubit(), Qubit());   
    for test in 1..count {
        SetQubitState(initial, q1);
        SetQubitState(Zero, q2);
        
        H(q1);  // Add the H operation after initialization and before measurement

        // measure each qubit
        let resultQ1 = M(q1);            
        let resultQ2 = M(q2); 
        ...

再跑一次你的程式。 因為第一個量子位元在測量時處於相等的疊加態,因此對於ZeroOne,你得到的結果接近50/50。 舉例來說,你的輸出看起來像這樣:

Q1 - Zeros: 523
Q1 - Ones: 477
Q2 - Zeros: 1000
Q2 - Ones: 0

每次執行程式時,第一個量子位元的結果會略有變化,但接近 50% One 和 50% Zero,而第二個量子位元的結果仍然總是 Zero

將第一個量子位元初始化為 ,Zero而不是 ,One然後再次執行程式。 你會得到類似的結果,因為這個 H 操作會將純 Zero 態和純態 One 都變成相等的疊加態。

注意

若要查看疊加結果在鏡頭分佈上的變化,請移動 Copilot for Azure Quantum 中的滑桿並增加鏡頭數。

糾纏兩個量子位

糾纏的量子位元彼此相關,無法彼此獨立描述。 當你測量一個糾纏量子位元的狀態時,你也知道另一個量子位元的狀態,即使沒有測量它。 這個教學範例是兩個糾纏的量子位元,但你也可以糾纏三個或以上的量子位元。

要建立糾纏狀態,請使用 Q#CNOT,或 Controlled-NOT 操作。 當你套用 CNOT 到兩個量子位元時,一個量子位元是控制量子位元,另一個是目標量子位元。 若控制量子位元的狀態為 One,則操作 CNOT 會翻轉目標量子比特的狀態。 否則, CNOT 對量子位元沒有任何影響。

CNOT作業之後立即將H作業新增至程式。 你完整的課程內容如下:

operation SetQubitState(desired : Result, target : Qubit) : Unit {
    if desired != M(target) {
        X(target);
    }
}

operation Main() : (Int, Int, Int, Int) {
    mutable numOnesQ1 = 0;
    mutable numOnesQ2 = 0;
    let count = 1000;
    let initial = Zero;

    // allocate the qubits
    use (q1, q2) = (Qubit(), Qubit());   
    for test in 1..count {
        SetQubitState(initial, q1);
        SetQubitState(Zero, q2);
    
        H(q1);            
        CNOT(q1, q2);      // Add the CNOT operation after the H operation

        // measure each qubit
        let resultQ1 = M(q1);            
        let resultQ2 = M(q2);           

        // Count the number of 'Ones' returned:
        if resultQ1 == One {
            numOnesQ1 += 1;
        }
        if resultQ2 == One {
            numOnesQ2 += 1;
        }
    }

    // reset the qubits
    SetQubitState(Zero, q1);             
    SetQubitState(Zero, q2);
    

    // Display the times that |0> is returned, and times that |1> is returned
    Message($"Q1 - Zeros: {count - numOnesQ1}");
    Message($"Q1 - Ones: {numOnesQ1}");
    Message($"Q2 - Zeros: {count - numOnesQ2}");
    Message($"Q2 - Ones: {numOnesQ2}");
    return (count - numOnesQ1, numOnesQ1, count - numOnesQ2, numOnesQ2 );
 }

執行程式並查看輸出。 每次執行程式時,你的結果都會有些微不同。

Q1 - Zeros: 502
Q1 - Ones: 498
Q2 - Zeros: 502
Q2 - Ones: 498

第一個量子比特的統計數據仍顯示約有 50% 機率同時測量 OneZero,但第二個量子比特的測量結果並不總是 Zero 現在。 每個量子位元都有相同數量的Zero結果和One結果。 第二個量子位元的測量結果總是與第一個量子位元相同,因為兩個量子比特是糾纏的。 若第一個量子位元被測量為 Zero,則糾纏量子比特也必須是 Zero。 若第一個量子位元被測量為 One,則糾纏量子比特也必須是 One

必要條件

要在您的本地開發環境中開發並執行範例程式碼,請安裝以下工具:

建立新 Q# 檔案

  1. 在 VS Code 中,打開 檔案 選單並選擇 新文字檔案 以建立新檔案。
  2. 將檔案儲存為 CreateBellStates.qs。 這個檔案是你為程式撰寫 Q# 程式碼的地方。

將量子位初始化為已知狀態

第一步是定義一個 Q# 運算,將量子位元初始化為期望的經典狀態,為 0 或 1。 此操作測量一個處於一般量子態的量子位元,回傳Q#Result的型別值為ZeroOne或 。 若測量結果與期望狀態不同,則操作會將狀態反轉,使操作回傳期望狀態的 100%。

開啟 CreateBellStates.qs 並複製下列程式代碼:

operation SetQubitState(desired : Result, target : Qubit) : Unit {
    if desired != M(target) {
        X(target);
    }
}

程式碼範例引入了兩個標準 Q# 操作, MX與 ,分別轉換量子位元的狀態。

以下是 SetQubitState 操作運作方式的詳細描述:

  1. 需要兩個參數:Result 型別參數,其命名為 desired,代表期望的量子位元狀態(ZeroOne),以及一個 Qubit 型別參數。
  2. 執行一個測量運算, M測量量子位元(ZeroOne)的狀態,並將結果與你通過的 desired值比較。
  3. 若測量結果與 的 desired值不符,則 X 會對量子位元進行操作。 此操作會將量子位元的狀態翻轉,從而反轉 ZeroOne 的測量機率。

撰寫測試操作以測試 Bell 狀態

要在程式SetQubitState中呼叫該Q#操作,請建立另一個名為 Main的操作。 此操作分配兩個量子位元,呼叫 SetQubitState 將第一個量子位元設定為已知狀態,然後測量量子位元以觀察結果。

CreateBellStates.qs操作之後,將下列操作新增至您的SetQubitState檔案:

operation Main() : (Int, Int, Int, Int) {
    mutable numOnesQ1 = 0;
    mutable numOnesQ2 = 0;
    let count = 1000;
    let initial = One;

    // allocate the qubits
    use (q1, q2) = (Qubit(), Qubit());   
    for test in 1..count {
        SetQubitState(initial, q1);
        SetQubitState(Zero, q2);
        
        // measure each qubit
        let resultQ1 = M(q1);            
        let resultQ2 = M(q2);           

        // Count the number of 'Ones' returned:
        if resultQ1 == One {
            numOnesQ1 += 1;
        }
        if resultQ2 == One {
            numOnesQ2 += 1;
        }
    }

    // reset the qubits
    SetQubitState(Zero, q1);             
    SetQubitState(Zero, q2);
    

    // Display the times that |0> is returned, and times that |1> is returned
    Message($"Q1 - Zeros: {count - numOnesQ1}");
    Message($"Q1 - Ones: {numOnesQ1}");
    Message($"Q2 - Zeros: {count - numOnesQ2}");
    Message($"Q2 - Ones: {numOnesQ2}");
    return (count - numOnesQ1, numOnesQ1, count - numOnesQ2, numOnesQ2 );
}

在程式代碼中, countinitial 變數會分別設定為 1000One 。 這會將第一個量子位元初始化為 One,並測量每個量子位元 1000 次。

Main 工作會執行下列作業:

  1. 設定射擊次數(count)及初始量子位元狀態(One)變數。
  2. 呼叫 use 陳述式來初始化兩個量子位元。
  3. 重複進行實驗 count 次。
  4. 在迴圈中,呼叫 SetQubitState 將第一個量子位元的指定 initial 值設定為該狀態,然後再次呼叫 SetQubitState 將第二個量子位元設定為狀態 Zero
  5. 在迴圈中,應用 M 運算來測量每個量子位元,然後儲存每個量子位元回傳 One的測量次數。
  6. 迴圈結束後,再次呼叫 SetQubitState 量子位元以重置為已知狀態(Zero)。 你必須重置你用 use 語句分配的量子位元。
  7. 呼叫 Message 函數以在主控台中列印結果。

執行程式碼

在撰寫疊加與糾纏的程式碼前,先測試你目前的程式,看看量子位元的初始化與測量情況。

要將程式碼作為獨立程式執行, Q# 編譯器需要知道從哪裡開始程式。 因為你沒有指定命名空間,編譯器會將預設的入口點視為操作。Main 如需詳細資訊,請參閱 專案和隱含命名空間

你的 CreateBellStates.qs 檔案現在看起來是這樣:

operation SetQubitState(desired : Result, target : Qubit) : Unit {
    if desired != M(target) {
        X(target);
    }
}

operation Main() : (Int, Int, Int, Int) {
    mutable numOnesQ1 = 0;
    mutable numOnesQ2 = 0;
    let count = 1000;
    let initial = One;

    // allocate the qubits
    use (q1, q2) = (Qubit(), Qubit());   
    for test in 1..count {
        SetQubitState(initial, q1);
        SetQubitState(Zero, q2);
        
        // measure each qubit
        let resultQ1 = M(q1);            
        let resultQ2 = M(q2);           

        // Count the number of 'Ones' returned:
        if resultQ1 == One {
            numOnesQ1 += 1;
        }
        if resultQ2 == One {
            numOnesQ2 += 1;
        }
    }

    // reset the qubits
    SetQubitState(Zero, q1);             
    SetQubitState(Zero, q2);
        
    
    // Display the times that |0> is returned, and times that |1> is returned
    Message($"Q1 - Zeros: {count - numOnesQ1}");
    Message($"Q1 - Ones: {numOnesQ1}");
    Message($"Q2 - Zeros: {count - numOnesQ2}");
    Message($"Q2 - Ones: {numOnesQ2}");
    return (count - numOnesQ1, numOnesQ1, count - numOnesQ2, numOnesQ2 );
}

要執行程式,請從操作前的程式碼鏡頭中選擇Main指令,或輸入 Ctrl + F5。 程式會在預設模擬器上執行 Main 作業。

您的輸出會出現在偵錯控制台中。

Q1 - Zeros: 0
Q1 - Ones: 1000
Q2 - Zeros: 1000
Q2 - Ones: 0

你的程式還沒修改量子位元狀態,所以第一個量子位元的測量總是回傳 One,第二個量子位元總是回傳 Zero

如果你將 的 initial 值改為 並 Zero 再次執行程式,那麼第一個量子位元也會返回 Zero

Q1 - Zeros: 1000
Q1 - Ones: 0
Q2 - Zeros: 1000
Q2 - Ones: 0

將一個量子位元置於疊加態

目前,你程式中的量子位元處於經典狀態,可能是1或0,就像一般電腦上的位元一樣。 要糾纏這些量子位元,首先必須將其中一個量子位元置於相等疊加態。 在相等疊加態下測量量子位元有50%的機率回傳Zero,有50%的機率回傳One

要將量子位元置於疊加態,請使用 Q#H或 Hadamard 操作。 這個 H 操作會將處於純 Zero 態或 One 狀態的量子位元轉換成介於 ZeroOne之間的一種中間狀態。

請在 Main 操作中修改你的程式碼。 將初始值重設為 , One 並插入一行執行以下 H 操作:

for test in 1..count {
    use (q1, q2) = (Qubit(), Qubit());   
    for test in 1..count {
        SetQubitState(initial, q1);
        SetQubitState(Zero, q2);
        
        H(q1);  // Add the H operation after initialization and before measurement

        // measure each qubit
        let resultQ1 = M(q1);            
        let resultQ2 = M(q2); 
        ...

再跑一次你的程式。 因為第一個量子位元在測量時處於相等疊加態,所以當你測量時,ZeroOne 的結果接近 50/50。 舉例來說,你的輸出看起來像這樣:

Q1 - Zeros: 523
Q1 - Ones: 477
Q2 - Zeros: 1000
Q2 - Ones: 0

每次執行程式時,第一個量子位元的結果會略有變化,但接近 50% One 和 50% Zero,而第二個量子位元的結果仍然總是 Zero

將第一個量子位元初始化為 ,Zero而不是 ,One然後再次執行程式。 你會得到類似的結果,因為這個 H 操作會將純 Zero 態和純態 One 都變成相等的疊加態。

糾纏兩個量子位

糾纏的量子位元彼此相關,無法彼此獨立描述。 當你測量一個糾纏量子位元的狀態時,你也知道另一個量子位元的狀態,即使沒有測量它。 這個教學範例是兩個糾纏的量子位元,但你也可以糾纏三個或以上的量子位元。

要建立糾纏狀態,請使用 Q#CNOT,或 Controlled-NOT 操作。 當你套用 CNOT 到兩個量子位元時,一個量子位元是控制量子位元,另一個是目標量子位元。 若控制量子位元的狀態為 One,則操作 CNOT 會翻轉目標量子比特的狀態。 否則, CNOT 對量子位元沒有任何影響。

CNOT作業之後立即將H作業新增至程式。 你完整的課程內容如下:

operation SetQubitState(desired : Result, target : Qubit) : Unit {
    if desired != M(target) {
        X(target);
    }
}

operation Main() : (Int, Int, Int, Int) {
    mutable numOnesQ1 = 0;
    mutable numOnesQ2 = 0;
    let count = 1000;
    let initial = Zero;

    // allocate the qubits
    use (q1, q2) = (Qubit(), Qubit());   
    for test in 1..count {
        SetQubitState(initial, q1);
        SetQubitState(Zero, q2);
    
        H(q1);            
        CNOT(q1, q2);      // Add the CNOT operation after the H operation

        // measure each qubit
        let resultQ1 = M(q1);            
        let resultQ2 = M(q2);           

        // Count the number of 'Ones' returned:
        if resultQ1 == One {
            numOnesQ1 += 1;
        }
        if resultQ2 == One {
            numOnesQ2 += 1;
        }
    }

    // reset the qubits
    SetQubitState(Zero, q1);             
    SetQubitState(Zero, q2);
    

    // Display the times that |0> is returned, and times that |1> is returned
    Message($"Q1 - Zeros: {count - numOnesQ1}");
    Message($"Q1 - Ones: {numOnesQ1}");
    Message($"Q2 - Zeros: {count - numOnesQ2}");
    Message($"Q2 - Ones: {numOnesQ2}");
    return (count - numOnesQ1, numOnesQ1, count - numOnesQ2, numOnesQ2 );
}

執行程式並查看輸出。 每次執行程式時,你的結果都會有些微不同。

Q1 - Zeros: 502
Q1 - Ones: 498
Q2 - Zeros: 502
Q2 - Ones: 498

第一個量子比特的統計數據仍顯示約有 50% 機率同時測量 OneZero,但第二個量子比特的測量結果並不總是 Zero 現在。 每個量子位元都有相同數量的Zero結果和One結果。 第二個量子位元的測量結果總是與第一個量子位元相同,因為兩個量子比特是糾纏的。 若第一個量子位元被測量為 Zero,則糾纏量子比特也必須是 Zero。 若第一個量子位元被測量為 One,則糾纏量子比特也必須是 One

繪製頻率直方圖

要繪製一個頻率直方圖,顯示多次執行程式時結果的分布,請完成以下步驟:

  1. 在 VS Code 中開啟你的 CreateBellStates.qs 檔案。

  2. 開啟 [檢視] 功能表,然後選擇 [命令面板]。

  3. 輸入 直方圖 即可跳出 QDK:執行檔案並顯示直方圖 選項。 或者,從操作Main前的程式碼透鏡選項中選擇直方圖指令。 接著輸入拍攝數量(例如100張)。 Q#直方圖會在一個新分頁打開。

    直方圖中的每條條對應糾纏電路運行1000次時可能的結果。 條狀棒的高度代表該結果發生的次數。 例如,以下直方圖顯示一個包含50個獨特結果的分布。 請注意,對於每個結果,第一個和第二個量子位元的測量結果總是相同的。

    Visual Studio Code 直方圖視窗的截圖 Q# 。

    提示

    要放大直方圖,請使用滑鼠滾輪或觸控板手勢。 放大時要平移圖表,請按住 Alt 鍵並同時滾動滑鼠。

  4. 選擇一條條來顯示產生該結果的總投籃百分比。

  5. 請選擇左上角 的設定圖示 以顯示視覺化選項。

    Visual Studio Code 直方圖視窗的顯示設定截圖 Q#。

  6. 再跑一次程式碼,但這次用1000發子彈。 隨著射擊次數增加,結果分布趨近常態分布。

探索其他 Q# 教學課程: