次の方法で共有


Visual Studio Code を使用して Q# プログラムを送信する方法

Visual Studio Code を使用して Q# プログラムを作成し、実際の量子ハードウェアに送信する方法について説明します。 量子コンピューティング ジョブをスタンドアロンの Q# プログラムとして Azure Quantum に送信し、Q# プロジェクトで Q# と Python を組み合わせて、Jupyter Notebook を実行できます。

Azure Quantum への Q# ジョブの送信

VS Code を使用して、Q# プログラムを実行、デバッグ、および Azure Quantum に送信する方法について説明します。

前提条件

インストールの詳細については、VS Code への QDK のインストールを参照してください

Q# サンプル プログラムを読み込む

  1. VS Code で、[ファイル>の新しいテキスト ファイル] を選択し、RandomNum.qs としてファイルを保存します

  2. RandomNum.qs を開き、「Random Bit sample」と入力sampleし、オプションの一覧から [Random Bit sample] を選択してファイルを保存します。

    Visual Studio Code の Q# ファイルのスクリーンショット。ファイルにサンプルという単語を書き込む際のコード サンプルの一覧が示されています。

Note

独自の Q# ファイルを開くこともできます。 以前の Q# プログラムを実行してエラーが発生した場合は、「テストとデバッグ」を参照してください

Q# プログラムを実行する

  1. 組み込みのシミュレーターでプログラムをローカルで実行するには、エントリ ポイント操作の横にあるコマンドの一覧から [実行] をクリックするか、Ctrl キーを押しながら F5 キーを押します。 出力がデバッグ コンソールに表示されます。

  2. プログラムを Azure Quantum に送信する前にデバッグするには、エントリ ポイント操作の横にあるコマンドの一覧から [デバッグ] をクリックするか、F5 キーを押します。 上部にあるデバッグ コントロールを使用して、コードのステップ オーバー、ステップ イン、ステップ アウトを行います。 Q# プログラムのデバッグの詳細については、「テストとデバッグ」を参照してください

    実行コマンドとデバッグ コマンドを使用してコード レンズを検索する場所を示す、Visual Studio Code の Q# ファイルのスクリーンショット。

頻度ヒストグラムを視覚化する

頻度ヒストグラムは、量子プログラムを複数回実行して得られた結果の分布("ショット") を表します。 ヒストグラムの各バーは、考えられる結果に対応し、その高さは結果が観察される回数を表します。 頻度ヒストグラムは、これらの結果の確率分布を視覚化するのに役立ちます。

  1. [表示 -> コマンド パレット] を選択し、「ヒストグラム」と入力すると、Q#: [ファイルの実行とヒストグラムの表示] オプションが表示されます。 エントリ ポイント操作の 横にあるコマンドの一覧から [ヒストグラム ] をクリックすることもできます。 Q# ヒストグラム ウィンドウを開くには、このオプションを選択します。

    ヒストグラム コマンドを使用してコード レンズを検索する場所を示す、Visual Studio Code の Q# ファイルのスクリーンショット。

  2. プログラムを実行するショット数 (100 ショットなど) を入力し、Enter キーを押します。 ヒストグラムが Q# ヒストグラム ウィンドウに表示されます。

  3. 左上 の設定アイコン をクリックすると、オプションが表示されます。

    設定を表示する方法を示す Visual Studio Code の Q# ヒストグラム ウィンドウのスクリーンショット。

  4. バーをクリックすると、その結果の 割合 が表示されます。 この場合、0 と 1 の 2 つの結果が考えられます。各結果の割合は 50% に近い値です。

    Visual Studio Code の Q# ヒストグラム ウィンドウのスクリーンショット。

ヒント

マウス スクロール ホイールまたはトラックパッド ジェスチャを使用して、ヒストグラムをズームできます。 拡大すると、スクロール中に 'Alt' キーを押してグラフをパンできます。

量子回路を視覚化する

量子回路図は、量子演算を視覚的に表現したものです。 量子プログラムを通る量子ビットの流れを示します。これには、ゲートとそれらに適用される測定値が含まれます。 詳細については、Visual Studio Code の量子回路図を参照してください

  1. [表示 ] -> [コマンド パレット] を選択し、「回線」と入力します。Q#: [回線の表示] オプションが表示されます。 エントリ ポイント操作の 横にあるコマンドの一覧から [回線 ] をクリックすることもできます。

    コード レンズ回線コマンドを検索する場所を示す Visual Studio Code の Q# ファイルのスクリーンショット。

  2. この回路は、Q# 回線ウィンドウに表示されます。 この回路図は、|0⟩ 状態に初期化された 1 つの量子ビット レジスタを示しています。 次に、ハダマールゲート Hが量子ビットに適用され、続いて 測定演算が行われ、これがメーターシンボルで表されます。 詳細については、「量子回路の規則」を参照してください

    ランダム ビット演算の結果の回路図を示す Q# 回線ウィンドウのスクリーンショット。

Azure Quantum に接続してジョブを送信する

VS Code からジョブを直接接続して送信できます。 この例では、Rigetti シミュレーターにジョブを送信します。

  1. [表示 ] -> [コマンド パレット] を選択し、「Q#: Azure Quantum ワークスペースに接続する」と入力しますEnter キーを押します。

  2. Azure アカウントを選択し、プロンプトに従って、優先するディレクトリ、サブスクリプション、ワークスペースに接続します。

    Note

    接続文字列がある場合は、[接続文字列] を選択し、Azure Quantum ワークスペースに対応する接続文字列を貼り付けることができます。 詳細については、「接続文字列を使用して Quantum ワークスペースに接続する」を参照してください

  3. 接続したら、[エクスプローラー] ウィンドウで [Quantum ワークスペース] を展開します。

  4. ワークスペースを展開し、Rigetti プロバイダーを展開します。

    Note

    Azure Quantum への接続に問題がある場合は、ワークスペース名の横に警告アイコンが表示されます。 ワークスペース名にカーソルを合わせると、エラー情報が表示されます。

  5. rigetti.sim.qvm を選択しますtarget。

    [Rigetti シミュレーター] を target選択する方法を示す Visual Studio Code のスクリーンショット。

  6. 名前の右側にある再生アイコンを選択して、現在の target Q# プログラムの送信を開始します。 ポップアップが表示されたら、[QIR target プロファイルの変更] を選択して続行します

    Rigetti シミュレーター targetを実行する方法を示す Visual Studio Code のスクリーンショット。

  7. ジョブを識別する名前を追加します。

  8. ショットの数、またはプログラムが実行される回数を追加します。

  9. Enter キーを押してジョブを送信します。 ジョブの状態が画面の下部に表示されます。

  10. [ジョブ] を展開し、ジョブの上にカーソルを合わせると、ジョブの時刻と状態が表示されます。

  11. 結果を表示するには、ジョブ名の横にあるクラウド アイコンを選択してワークスペース ストレージから結果をダウンロードし、VS Code に表示します。

    量子ジョブの結果をダウンロードして表示する方法を示す Visual Studio Code のスクリーンショット。

Jupyter Notebooks ジョブを Azure Quantum に送信する

VS Code を使用して、Q# Jupyter Notebook を実行、デバッグ、および Azure Quantum に送信する方法について説明します。 この記事の手順は、ローカルの Jupyter サーバー上の Jupyter Notebook または Azure Quantum ポータルのノートブックにも適用されます。

前提条件

インストールの詳細については、VS Code への QDK のインストールを参照してください

  • Azure サブスクリプションの Azure Quantum ワークスペース。 ワークスペースを作成するには、Azure Quantum ワークスペースの作成に関するページを参照してください。

  • Python と Pip がインストールされた Python 環境。

  • Azure Quantum Development Kit、PythonJupyter 拡張機能がインストールされた VS Code。

  • Azure Quantumqsharpqsharp-widgetsパッケージ、およびazure-quantumipykernelパッケージ。

    python -m pip install --upgrade qsharp qsharp-widgets azure-quantum ipykernel
    

ローカル シミュレーターでプログラムを実行してテストする

  1. VS Code で、[表示] > [コマンド パレット] を選択して、[作成: 新しい Jupyter Notebook] を選択します。

  2. 右上の VS Code は、Python のバージョンと、ノートブック用に選択された仮想 Python 環境を検出して表示します。 複数の Python 環境がある場合は、右上のカーネル ピッカーを使用してカーネルを選択する必要があります。 環境が検出されなかった場合は、セットアップ情報については VS Code の Jupyter Notebook を参照してください

  3. ノートブックの最初のセルで、次の Python コードを実行して、必要なモジュールをインポートします。

    import qsharp
    import azure.quantum
    
    • モジュールによって qsharp マジック コマンドが %%qsharp アクティブ化され、Q# コードをセルに直接入力できます。
    • このモジュールは azure-quantum 、Azure Quantum ワークスペースへの接続を提供します。

    Note

    Jupyter Python カーネル ipykernel が検出されない場合、VS Code によってインストールするように求められます。

  4. 別のセルを追加し、ユーザー指定のランダム ビット数を返す次の Q# コードを入力します。

    Note

    マジック コマンド%%qsharpを入力するとすぐに、ノートブック のセルの種類が Python から Q#変わります。

    %%qsharp
    
    operation Random() : Result {
        use q = Qubit();
        H(q);
        let result = M(q);
        Reset(q);
        return result
    }
    
    operation RandomNBits(N: Int): Result[] {
        mutable results = [];
        for i in 0 .. N - 1 {
            let r = Random();
            set results += [r];
        }
        return results
    }
    
  5. 操作をテストするには、ノートブックで以前に定義されている Q# 操作を呼び出すことができるメソッドを使用 eval できます。

    qsharp.eval("RandomNBits(4)")
    
    [Zero, One, One, Zero]
    
  6. ローカル シミュレーターに対してプログラムを実行するには、メソッドを使用します run 。 プログラムを shots実行する回数を指定すると、シミュレーターは結果を Python リストとして返します。

    qsharp.run("RandomNBits(4)", shots=10)
    
    [[One, One, One, One],
    [Zero, Zero, One, Zero],
    [One, Zero, Zero, One],
    [Zero, One, Zero, Zero],
    [One, Zero, One, One],
    [One, Zero, One, Zero],
    [One, One, One, Zero],
    [One, One, One, One],
    [Zero, Zero, Zero, One],
    [One, Zero, Zero, One]]
    

量子回路を視覚化する

パッケージを使用して qsharp-widgets 量子回路を視覚化できます。 このパッケージは、SVG 画像として量子回路図をレンダリングするウィジェットを提供します。 詳細については、「Jupyter Notebook を使用した量子回路図」を参照してください

次のコードを新しいセルに追加して、回線を視覚化します。

from qsharp_widgets import Circuit

Circuit(qsharp.circuit("RandomNBits(4)"))

Q# 操作の回線を視覚化する方法を示す Jupyter Notebook のスクリーンショット。

詳細については、「量子回路の規則」を参照してください

基本プロファイルを使用してジョブをコンパイルする

ローカル量子シミュレーターでプログラムを実行する場合は、任意の種類の Q# プログラムを送信できます。 ただし、Azure Quantum ハードウェア targets では、すべての Q# プログラムを実行するために必要な完全な機能はまだサポートされていません。 Q# プログラムをコンパイルして Azure Quantum に送信するには、ハードウェアでサポートされている機能を target Q# に伝えるプロファイルを設定する必要があります target 。 現時点では、基本プロファイルです。 詳細については、「Azure Quantum のプロファイルの種類」を参照してください

Q# インタープリターを再初期化し、基本プロファイルを使用してプログラムをコンパイルするには:

  1. プロファイルを init 設定するには、次のメソッドを使用します。

    qsharp.init(target_profile=qsharp.TargetProfile.Base)
    
  2. インタープリターを再初期化したので、新しいプロファイルでコードをもう一度実行する必要があります。

    %%qsharp
    
    operation Random() : Result {
        use q = Qubit();
        H(q);
        let result = M(q);
        Reset(q);
        return result
    }
    
    operation RandomNBits(N: Int): Result[] {
        mutable results = [];
        for i in 0 .. N - 1 {
            let r = Random();
            set results += [r];
        }
        return results
    }
    
  3. 次に、メソッドを compile 使用して、プログラムへのエントリ ポイントである操作または関数を指定します。 これにより、コードが QIR 形式にコンパイルされ、任意の量子ハードウェアに送信できます。

    MyProgram = qsharp.compile("RandomNBits(4)")
    

Azure Quantum に接続してジョブを送信する

プログラムを正しい形式にコンパイルしたら、Azure Quantum に接続するオブジェクトを作成 azure.quantum.Workspace します。 接続するには、Azure Quantum ワークスペースのリソース ID を使用します。 リソース ID と場所は、Azure portal のワークスペースの概要ページからコピーできます。

  1. 新しいセルで、Azure Quantum ワークスペースのリソース ID と場所を入力します。

    MyWorkspace = azure.quantum.Workspace(
        resource_id = "MyResourceID",
        location = "MyLocation"
    )
    
  2. ワークスペースで get_targets 使用可能なハードウェア targets を確認するには、次のメソッドを使用します。

    MyTargets = MyWorkspace.get_targets()
    print("This workspace's targets:")
    MyTargets
    
  3. 次を選択します。rigetti.sim.qvmtarget

    MyTarget = MyWorkspace.get_targets("rigetti.sim.qvm")
    
  4. 最後に、メソッドを submit 使用して、そのパラメーターを使用してプログラムを送信し、結果を表示します。

    job = MyTarget.submit(MyProgram, "MyQuantumJob", shots=100)
    job.get_results()
    
    {'[0, 1, 1, 1]': 0.08,
     '[1, 1, 0, 0]': 0.1,
     '[0, 0, 1, 0]': 0.04,
     '[0, 1, 0, 0]': 0.05,
     '[1, 0, 1, 0]': 0.05,
     '[1, 0, 0, 0]': 0.07,
     '[0, 1, 0, 1]': 0.07,
     '[1, 0, 1, 1]': 0.07,
     '[0, 0, 0, 0]': 0.08,
     '[1, 1, 1, 0]': 0.05,
     '[0, 0, 0, 1]': 0.1,
     '[0, 0, 1, 1]': 0.04,
     '[0, 1, 1, 0]': 0.09,
     '[1, 0, 0, 1]': 0.04,
     '[1, 1, 1, 1]': 0.05,
     '[1, 1, 0, 1]': 0.02}
    
  5. ジョブのすべてのプロパティにアクセスできます job.details。次に例を示します。

    print(job.details)
    print("\nJob name:", job.details.name)
    print("Job status:", job.details.status)
    print("Job ID:", job.details.id)
    
    {'additional_properties': {'isCancelling': False}, 'id': '0150202e-9638-11ee-be2f-b16153380354', 'name': 'MyQuantumJob', 'provider_id': 'rigetti'...}
    Job name: MyQuantumJob
    Job status: Succeeded
    Job ID: 0150202e-9638-11ee-be2f-b16153380354
    

その他のジョブの詳細

azure.quantum Python パッケージには、より詳細なジョブ データを表示するための追加のメソッドが含まれています。

  • job.get_results_histogram():このメソッドは、各一意の測定の結果とショット数のディクショナリを返します。 たとえば、前のジョブの結果は次のようになります。

    print(job.get_results_histogram()) 
    
    {   
        '[0, 1, 1, 1]' : {'Outcome' : [0, 1, 1, 1], 'Count' : 8},  
        '[1, 1, 0, 0]' : {'Outcome' : [1, 1, 0, 0], 'Count' : 10},
        '[0, 0, 1, 0]' : {'Outcome' : [0, 0, 1, 0], 'Count' : 4},
        '[0, 1, 0, 0]' : {'Outcome' : [0, 1, 0, 0], 'Count' : 5},
        '[1, 0, 1, 0]' : {'Outcome' : [1, 0, 1, 0], 'Count' : 5},  
        '[1, 0, 0, 0]' : {'Outcome' : [1, 0, 0, 0], 'Count' : 7},
        '[0, 1, 0, 1]' : {'Outcome' : [0, 1, 0, 1], 'Count' : 7},
        '[1, 0, 1, 1]' : {'Outcome' : [1, 0, 1, 1], 'Count' : 7},
        '[0, 0, 0, 0]' : {'Outcome' : [0, 0, 0, 0], 'Count' : 8},  
        '[1, 1, 1, 0]' : {'Outcome' : [1, 1, 1, 0], 'Count' : 5},
        '[0, 0, 0, 1]' : {'Outcome' : [0, 0, 0, 1], 'Count' : 10},
        '[0, 0, 1, 1]' : {'Outcome' : [0, 0, 1, 1], 'Count' : 4},
        '[0, 1, 1, 0]' : {'Outcome' : [0, 1, 1, 0], 'Count' : 9},  
        '[1, 0, 0, 1]' : {'Outcome' : [1, 0, 0, 1], 'Count' : 4},
        '[1, 1, 1, 1]' : {'Outcome' : [1, 1, 1, 1], 'Count' : 5},
        '[1, 1, 0, 1]' : {'Outcome' : [1, 1, 0, 1], 'Count' : 2}
    }
    
  • job.get_results_shots() : このメソッドは、各ショット結果の一覧を返します。 たとえば、前のジョブの結果は次のようになります。

    print(job.get_results_shots()) 
    
    [ [0, 1, 1, 1], [1, 0, 1, 1], [0, 0, 1, 1], [1, 1, 0, 1], [1, 0, 0, 0], [1, 0, 1, 1], [1, 1, 0, 1], ...]
    

Q# ジョブを含む Python を Azure Quantum に送信する

VS Code を使用して、Q# 操作を呼び出す Python プログラムを記述し、Python コマンドまたは Azure CLI を使用して Azure に接続し、ジョブを送信する方法について説明します。

前提条件

インストールの詳細については、VS Code への QDK のインストールを参照してください

Q# 操作を作成してインポートする

qsharpこのパッケージを使用すると、関数と操作を Q# ファイルに格納し、Python コードからそれらを呼び出すことができる Q# プロジェクトを作成できます。 これは、入力パラメーターを受け取るプログラムを起動する必要がある場合に特に役立ちます。

  1. 手順に従って Q# プロジェクト作成します。

  2. 新しいテキスト ファイルを開き、ユーザー指定のランダム ビット数を返す次の Q# コードを追加し、ファイルを プロジェクトの /src ディレクトリに次のように Source.qs保存します。

    
        operation Random() : Result {
        use q = Qubit();
        H(q);
        let result = M(q);
        Reset(q);
        return result
    }
    
    operation RandomNBits(N: Int): Result[] {
        mutable results = [];
        for i in 0 .. N - 1 {
            let r = Random();
            set results += [r];
        }
        return results
    }
    
  3. (qsharp.json ファイルを含む) プロジェクト ルート フォルダーで、別のファイルを開き、次のようにrandomNum.py保存します。

  4. 次のコードを追加して、モジュールをqsharpazure.quantumインポートします。

    import qsharp
    import azure.quantum
    
  5. 次に、Q# プロジェクトのルート フォルダーを定義するコードを追加し、ローカル シミュレーターで操作を target テスト実行します。 この操作は名前空間>によって呼び出されます。< <operation_name( )>、この場合は、返すランダム ビットの数を渡します。

    Note

    名前空間が指定 Source.qsされていないため、コンパイラは既定の名前空間 Source.RandomNBits()としてファイル名を使用します。 詳細については、「プロジェクトと暗黙的な名前空間」を参照してください

    qsharp.init(project_root = '../MyProjectRootFolder')
    print(qsharp.eval("Source.RandomNBits(4)"))
    
    [Zero, One, One, Zero]
    
  6. メソッドを使用して操作を run テストすることもできます。メソッドは追加 shots のパラメーターを渡し、結果を Python リストで返します。 で randomNum.py、前の print ステートメントを次のように置き換えます。

    result = qsharp.run("Source.RandomNBits(4)", shots=10)
    for x in result:
        print(x)
    
    [[One, One, One, One],
    [Zero, Zero, One, Zero],
    [One, Zero, Zero, One],
    [Zero, One, Zero, Zero],
    [One, Zero, One, One],
    [One, Zero, One, Zero],
    [One, One, One, Zero],
    [One, One, One, One],
    [Zero, Zero, Zero, One],
    [One, Zero, Zero, One]]
    

基本プロファイルを使用してジョブをコンパイルする

ローカル量子シミュレーターでプログラムを実行する場合は、任意の種類の Q# プログラムを送信できます。 ただし、Azure Quantum ハードウェア targets では、すべての Q# プログラムを実行するために必要な完全な機能はまだサポートされていません。 Q# プログラムをコンパイルして Azure Quantum に送信するには、ハードウェアでサポートされている機能を target Q# に伝えるプロファイルを設定する必要があります target 。 現在、これはプロファイルですBaseAdpative_RI。 詳細については、「Azure Quantum のプロファイルの種類」を参照してください

Note

VS Code の Q# のみのプログラムでは 、VS Code によってプロファイルが自動的に Base 設定されます。

  1. プロファイルを init 設定するには、次のメソッドを使用します。

    qsharp.init(project_root = '../MyProjectRootFolder', target_profile=qsharp.TargetProfile.Base)
    

    Note

    qsharp 状態を再初期化するため、コンパイラが操作を検索する場所を project_root 認識できるように、もう一度パラメーターを RandomNBits 設定する必要があります。 これは、前の手順の手順 5 でも実行できました。

  2. 次に、このメソッドを compile 使用して、プログラムへのエントリ ポイントである操作または関数を指定します。 コンパイルされたプログラムは、任意の量子ハードウェアに送信できます。

    MyProgram = qsharp.compile("Source.RandomNBits(4)")
    

Azure Quantum に接続してジョブを送信する

Azure Quantum に接続し、Python で作成された Workspace オブジェクトを使用してジョブを送信するか、Azure CLI を使用して接続してジョブを送信できます。 Azure CLI を使用するには、コンパイル済みのプログラムをテキスト ファイルとして保存し、CLI コマンドを使用してそのファイルを送信する必要があります。

プログラムを正しい形式にコンパイルしたら、Azure Quantum に接続するオブジェクトを作成 azure.quantum.Workspace します。 接続するには、Azure Quantum ワークスペースのリソース ID を使用します。 リソース ID と場所は、Azure portal のワークスペースの概要ページからコピーできます。

  1. 次のコードを追加し randomNum.py、Azure Quantum ワークスペースからリソース ID と場所を入力します。

    workspace = azure.quantum.Workspace(
        resource_id = "MyResourceID",
        location = "MyLocation"
    )
    
  2. ワークスペースで get_targets 使用可能なハードウェア targets を表示するには、次のメソッドを使用します。

    MyTargets = workspace.get_targets()
    print("This workspace's targets:")
    for x in MyTargets:
        print(x)
    
  3. 次を選択します。rigetti.sim.qvmtarget

    MyTarget = workspace.get_targets("rigetti.sim.qvm")
    
  4. 最後に、メソッドを submit 使用して、そのパラメーターを使用してプログラムを送信します。 ジョブの結果は Python ディクショナリとして返されます。

    job = MyTarget.submit(MyProgram, "MyPythonJob", shots=100)
    results = job.get_results()
    print("\nResults: ", results)
    
  5. 値だけを抽出して表示するには:

    for x in results:
        print(x)
    
    [0, 0, 0, 0]
    0.3
    [1, 0, 0, 0]
    0.1
    [1, 1, 1, 1]
    0.3
    [0, 1, 1, 1]
    0.3
    
  6. ジョブのすべてのプロパティにアクセスできます job.details。次に例を示します。

    print(job.details)
    print("\nJob name:", job.details.name)
    print("Job status:", job.details.status)
    print("Job ID:", job.details.id)
    
    {'additional_properties': {'isCancelling': False}, 'id': '0fc396d2-97dd-11ee-9958-6ca1004ff31f', 'name': 'MyPythonJob', 'provider_id': 'rigetti'...}
    Job name: MyPythonJob
    Job status: Succeeded
    Job ID: fc396d2-97dd-11ee-9958-6ca1004ff31f
    

その他のジョブの詳細

azure.quantum Python パッケージには、より詳細なジョブ データを表示するための追加のメソッドが含まれています。

  • job.get_results_histogram():このメソッドは、各一意の測定の結果とショット数のディクショナリを返します。 たとえば、前のジョブの結果は次のようになります。

    results = job.get_results_histogram()
    for x in results.items():
        print(x)
    
    {   
        '[0, 0, 0, 0]' : {'Outcome' : [0, 0, 0, 0], 'Count' : 30},  
        '[1, 0, 0, 0]' : {'Outcome' : [1, 0, 0, 0], 'Count' : 10},
        '[1, 1, 1, 1]' : {'Outcome' : [1, 1, 1, 1], 'Count' : 30},
        '[0, 1, 1, 1]' : {'Outcome' : [0, 1, 1, 1], 'Count' : 30}
    }
    
  • job.get_results_shots() : このメソッドは、各ショット結果の一覧を返します。 たとえば、前のジョブの結果は次のようになります。

    print(job.get_results_shots()) 
    
    [ [0, 0, 0, 0], [1, 1, 1, 1], [0, 1, 1, 1], [1, 1, 1, 1], [1, 0, 0, 0], [0, 1, 1, 1], [0, 0, 0, 0], ...]