├── README.md ├── a_tale_of_timbits ├── a_tale_of_timbits_100 │ ├── README.md │ ├── images │ │ └── bv.png │ └── the_magic_5_ball.ipynb ├── a_tale_of_timbits_200 │ ├── README.md │ ├── cascadar.ipynb │ └── images │ │ ├── box.png │ │ └── prod.png ├── a_tale_of_timbits_300 │ ├── README.md │ └── a_pauli_worded_problem.ipynb ├── a_tale_of_timbits_400 │ ├── README.md │ ├── entangled_robot_swarms.ipynb │ └── images │ │ ├── hub.jpeg │ │ └── swarm.jpeg └── a_tale_of_timbits_500 │ ├── README.md │ ├── images │ └── timbit.png │ └── one_bit_wonder.ipynb ├── bending_bennetts_laws ├── bending_bennets_laws_100 │ ├── Ctrl-Z.ipynb │ ├── README.md │ └── images │ │ ├── and.png │ │ └── ctrl-Z.png ├── bending_bennets_laws_200 │ ├── README.md │ ├── images │ │ ├── model_superdense.jpeg │ │ └── sd.png │ └── sub_superdense_coding.ipynb ├── bending_bennets_laws_300 │ ├── README.md │ ├── images │ │ ├── operator_encoder.jpeg │ │ └── tel-bell.png │ └── secrets_in_spacetime.ipynb ├── bending_bennets_laws_400 │ ├── README.md │ ├── a_halfway_decent_photocopier.ipynb │ └── images │ │ ├── circuit_copy.jpeg │ │ └── cobit.png └── bending_bennets_laws_500 │ ├── README.md │ ├── images │ ├── magic_zr.jpeg │ └── ove-hat.png │ └── the_itch_to_switch.ipynb ├── fall_of_sqynet ├── fall_of_sqynet_100 │ ├── README.md │ ├── images │ │ └── spaceship_1.png │ └── sqy_trotter.ipynb ├── fall_of_sqynet_200 │ ├── README.md │ ├── images │ │ └── spaceship_2.png │ └── unitary_operators_and_beyond.ipynb ├── fall_of_sqynet_300 │ ├── README.md │ ├── dont_hit_the_ground.ipynb │ └── images │ │ └── spaceship_3.png ├── fall_of_sqynet_400 │ ├── README.md │ └── desperate_measures.ipynb └── fall_of_sqynet_500 │ ├── README.md │ ├── images │ └── spaceship_4.png │ └── ising_uprising.ipynb ├── office_hijinks ├── office_hijinks_100 │ ├── README.md │ ├── images │ │ ├── clock1.jpeg │ │ ├── clock2.jpeg │ │ └── clock3.jpeg │ └── tick_tock_bloch.ipynb ├── office_hijinks_200 │ ├── README.md │ ├── images │ │ └── example_sol.jpeg │ └── the_super_parameter.ipynb ├── office_hijinks_300 │ ├── README.md │ ├── images │ │ ├── image1_qubit_change.jpeg │ │ └── image2_qubit_change.jpeg │ └── the_change_of_qubit.ipynb ├── office_hijinks_400 │ ├── README.md │ ├── images │ │ └── project_execution.jpeg │ └── the_lazy_colleague.ipynb └── office_hijinks_500 │ ├── README.md │ ├── images │ └── 2is4.jpeg │ └── the_false_proof.ipynb └── tutorial_challenges ├── tutorial_1 ├── README.md └── it_adds_up.ipynb ├── tutorial_2 ├── README.md ├── affairs_of_state.ipynb └── images │ └── daily2.png ├── tutorial_3 ├── README.md ├── a_shor_thing.ipynb └── images │ └── daily3.png ├── tutorial_4 ├── README.md └── product_management.ipynb ├── tutorial_5 ├── README.md ├── hi_hydrogen.ipynb └── images │ ├── daily5.png │ └── daily5_2.png ├── tutorial_6 ├── README.md ├── hamiltonian_sandwich.ipynb └── images │ └── daily6.png ├── tutorial_7 ├── README.md ├── images │ └── daily7.png └── optimize_this.ipynb └── tutorial_8 ├── README.md ├── images └── daily8.png └── stuck_in_the_middle_with_u.ipynb /README.md: -------------------------------------------------------------------------------- 1 | ### Get ready for QHack 2024! 2 | 3 | [QHack 2024](https://qhack.ai/) brings even more coding challenges for you to showcase your Quantum Programming skills. Solve some [PennyLane Challenges](https://pennylane.ai/challenges/) to get the gears turning. See you at QHack! 4 | 5 | # qhack_2023_coding_challenges 6 | Find the QHack 2023 coding challenges here! 7 | 8 | ## Organization of this repo 9 | 10 | The challenges are organized into 5 categories or *stories*: 11 | 12 | 1. Tutorial challenges 13 | 2. A tale of timbits 14 | 3. Bending Bennett's Laws 15 | 4. Fall of Sqynet 16 | 5. Office Hijinks 17 | 18 | Within each of the folders corresponding to the stories above, you will find a number of subfolders, one for each challenge in that story. Inside each of these folders, you will find a README file containing the challenge statement, a Jupyter Notebook containing the template for solving the challenge, and (sometimes) a folder with images. 19 | 20 | There are eight tutorial challenges, worth zero points, and 5 challenges in each of the other categories, worth points ranging between 100 and 500. The name of the folder containing the challenge specifies the numbers of points. For example, within `office_hijinks`, the folder `office_hijinks_100` contains the challenge worth 100 points in this story. 21 | 22 | ### Running the coding challenge 23 | 24 | The Jupyter Notebook contains the following sections: 25 | 26 | 1. **Imports:** A cell that imports the libraries needed for this challenge. You should not need to import any additional libraries. 27 | 2. **Code:** Where you can write your code. Note that in QHack 2023's Coding Challenges, there were some uneditable blocks. If you want to relive the full QHack 2023 Coding Challenges experience, do not edit any code between the markers `### Uneditable section ###` and `### End of uneditable section ###`. There is also a cell with the `run` and `check` functions. They are helper functions to help judge your solution, and you shouldn't modify anything within these. You need to run this cell. 28 | 3. **Test cases:** The public test cases available during QHack 2023 are shown here. You need to run the cell that defines the variable `test_cases`. 29 | 4. **Solution testing:** Run the cell here to see whether your solution is correct! 30 | 31 | -------------------------------------------------------------------------------- /a_tale_of_timbits/a_tale_of_timbits_100/README.md: -------------------------------------------------------------------------------- 1 | ### Backstory 2 | 3 | Doc Trine has been kidnapped by a freelance security analyst, Ove, and 4 | held in some sort of 'hyperjail'. Zenda and Reece need to figure out 5 | where it is and how to get there, using only the janky equipment lying 6 | around the office. Once they've rescued her, maybe Doc Trine will finally 7 | reveal the secret of timbits! 8 | 9 | At Trine's desk, they find her notebook, full of diagrams, 10 | calculations, and dense, messy handwriting. Leafing through 11 | them, Zenda and Reece discover a note helpfully explaining 12 | what this hyperjail is: "*A 5-dimensional hypercube, accessed from some 13 | unknown point in deep space. Should get those robots out there some 14 | time.*" Robots? They keep reading: "*Cell number is in the magic 15 | 5-ball.*" They root around in the games room and find a dusty old magic 16 | 5-ball, which outputs 'yes' and 'no' answers to a 5-bit input. 17 | Presumably (though who knows how) Trine has concealed her location in 18 | this oracle. They have another problem, though. The fault-tolerant 19 | office equipment has disappeared along with Trine, leaving only noisy 20 | old circuitry! 21 | 22 | ### Noisy Bernstein–Vazirani 23 | 24 | The oracle encodes the cell number $c \in \\{0, 1\\}^5$, a $5$-bit string. 25 | Consider the dot product 26 | 27 | $$ 28 | f(x) = x \cdot c = x_0 c_0 + x_1 c_1 + \cdots + x_5 c_5 \mod 2, 29 | $$ 30 | 31 | where $x \in \\{0, 1\\}^5$ is an arbitrary $5$-bit string. The oracle is 32 | a unitary operator $U_f$ which encodes the dot product $f$ 33 | as a phase: 34 | 35 | $$ 36 | U_f \vert x\rangle = (-1)^{f(x)} \vert x\rangle. 37 | $$ 38 | 39 | Zenda and Reece need to use this oracle to learn the starting positions 40 | $c$, but equipment in the old lab is noisy, with *depolarizing noise*, 41 | which with some probability $\lambda$ replaces a qubit state with 42 | something random. 43 | Despite the noise, Zenda and Reece can attempt to learn Doc Trine's 44 | coordinates using the *Bernstein–Vazirani algorithm*. 45 | We picture the noisy circuit below: 46 | 47 |
48 | Noisy Bernstein-Vazirani 49 |
50 | 51 | Your goal: implement a noisy version of the Bernstein–Vazirani 52 | algorithm, using the noisy Hadamard gates provided. 53 | Will it work on the old computer? 54 | 55 | ## Challenge code 56 | 57 | In the code below, you are given various functions: 58 | - `oracle_matrix`: which encodes Doc Trine's location in the hypercube. 59 | - `noisy_Hadamard`: which applies a noisy Hadamard gate, with a 60 | probability `lmbda` of replacing an incoming or outgoing qubit 61 | state with something random. 62 | - `noisy_BernsteinVazirani`: which implements the Bernstein-Vazirani 63 | algorithm using the oracle and the noisy Hadamard operation `noisy_Hadamard`. **You must complete this 64 | function**. 65 | 66 | You may find this resource helpful: 67 | 68 | - [Bernstein-Vazirani algorithm](https://en.wikipedia.org/wiki/Bernstein%E2%80%93Vazirani_algorithm) 69 | 70 | ### Inputs 71 | 72 | The noisy Bernstein-Vazirani circuit `noisy_BernsteinVazirani` takes as input the 73 | probability `lmbda (float)` of replacing the state of a qubit. 74 | 75 | ### Output 76 | 77 | Your `noisy_BernsteinVazirani` circuit should correctly output the expectation value 78 | of the Pauli-$Z$ operator on each qubit (`[float]`). The pattern of 79 | positive and negative expectations gives the cell number for any value 80 | of $\lambda$, showing that Bernstein–Vazirani is robust to noise. 81 | 82 | If your solution matches the correct one within the given tolerance 83 | specified in `check` (in this case it's a `1e-4` relative error 84 | tolerance), the output will be `"Correct!"` Otherwise, you will 85 | receive a `"Wrong answer"` prompt. 86 | -------------------------------------------------------------------------------- /a_tale_of_timbits/a_tale_of_timbits_100/images/bv.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/XanaduAI/qhack_2023_coding_challenges/efc516ac412dc351ae8bf9745e304717b81d1ff3/a_tale_of_timbits/a_tale_of_timbits_100/images/bv.png -------------------------------------------------------------------------------- /a_tale_of_timbits/a_tale_of_timbits_100/the_magic_5_ball.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "id": "9c3156e5", 6 | "metadata": {}, 7 | "source": [ 8 | "## Challenge code\n", 9 | " \n", 10 | " In the code below, you are given various functions:\n", 11 | " - `oracle_matrix`: which encodes Doc Trine's location in the hypercube.\n", 12 | " - `noisy_Hadamard`: which applies a noisy Hadamard gate, with a\n", 13 | " \tprobability `lmbda` of replacing an incoming or outgoing qubit\n", 14 | " \tstate with something random.\n", 15 | " - `noisy_BernsteinVazirani`: which implements the Bernstein-Vazirani\n", 16 | " algorithm using the oracle and the noisy Hadamard operation `noisy_Hadamard`. **You must complete this\n", 17 | " function**.\n", 18 | " \n", 19 | " You may find this resource helpful:\n", 20 | " \n", 21 | " - [Bernstein-Vazirani algorithm](https://en.wikipedia.org/wiki/Bernstein%E2%80%93Vazirani_algorithm)\n", 22 | " \n", 23 | " ### Inputs\n", 24 | " \n", 25 | " The noisy Bernstein-Vazirani circuit `noisy_BernsteinVazirani` takes as input the\n", 26 | " probability `lmbda (float)` of replacing the state of a qubit.\n", 27 | " \n", 28 | " ### Output\n", 29 | " \n", 30 | " Your `noisy_BernsteinVazirani` circuit should correctly output the expectation value\n", 31 | " of the Pauli-$Z$ operator on each qubit (`[float]`). The pattern of\n", 32 | " positive and negative expectations gives the cell number for any value\n", 33 | " of $\\lambda$, showing that Bernstein–Vazirani is robust to noise.\n", 34 | " \n", 35 | " If your solution matches the correct one within the given tolerance\n", 36 | " specified in `check` (in this case it's a `1e-4` relative error\n", 37 | " tolerance), the output will be `\"Correct!\"` Otherwise, you will\n", 38 | " receive a `\"Wrong answer\"` prompt.\n", 39 | " ### Imports\n", 40 | " The cell below specifies the libraries you should use in this challenge. Run the cell to import the libraries. ***Do not modify the cell.***" 41 | ] 42 | }, 43 | { 44 | "cell_type": "code", 45 | "execution_count": null, 46 | "id": "d9759717", 47 | "metadata": {}, 48 | "outputs": [], 49 | "source": [ 50 | "import json\n", 51 | "import pennylane as qml\n", 52 | "from pennylane import numpy as np" 53 | ] 54 | }, 55 | { 56 | "cell_type": "markdown", 57 | "id": "9a1ff1da", 58 | "metadata": {}, 59 | "source": [ 60 | "### Code\n", 61 | " Complete the code below. Note that during QHack, some sections were not editable. We've marked those sections accordingly here, but you can still edit them if you wish." 62 | ] 63 | }, 64 | { 65 | "cell_type": "code", 66 | "execution_count": null, 67 | "id": "346f9286", 68 | "metadata": {}, 69 | "outputs": [], 70 | "source": [ 71 | "# Uneditable section #\n", 72 | "def noisy_Hadamard(lmbda, wire):\n", 73 | " \"\"\"A Hadamard gate with depolarizing noise on either side.\n", 74 | " \n", 75 | " Args:\n", 76 | " lmbda (float): The parameter defining the depolarizing channel.\n", 77 | " wire (int): The wire the depolarizing channel acts on.\n", 78 | " \"\"\"\n", 79 | " qml.DepolarizingChannel(lmbda, wires=wire)\n", 80 | " qml.Hadamard(wire)\n", 81 | " qml.DepolarizingChannel(lmbda, wires=wire)\n", 82 | "\n", 83 | "# Oracle matrix for Doc Trine's cell number\n", 84 | "\n", 85 | "flips = [1, 3, 5, 7, 8, 10, 12, 14, 16, 18, 20, 22, 25, 27, 29, 31]\n", 86 | "\n", 87 | "oracle_matrix = np.eye(2**5)\n", 88 | "for i in flips:\n", 89 | " oracle_matrix[i, i] = -1\n", 90 | "\n", 91 | "# Implement the Bernstein-Vazirani algorithm with depolarizing noise\n", 92 | "\n", 93 | "dev = qml.device(\"default.mixed\", wires = 5)\n", 94 | "@qml.qnode(dev)\n", 95 | "def noisy_BernsteinVazirani(lmbda):\n", 96 | " \"\"\"Runs the Bernstein-Vazirani algorithm with depolarizing noise.\n", 97 | "\n", 98 | " Args:\n", 99 | " lmbda (float): The probability of erasing the state of a qubit.\n", 100 | "\n", 101 | " Returns:\n", 102 | " (list(float)): Expectation values for PauliZ on all n wires.\n", 103 | " \"\"\"\n", 104 | "\n", 105 | " # End of uneditable section #\n", 106 | "\n", 107 | "\n", 108 | " # Put your code here #\n", 109 | "\n", 110 | "\n", 111 | "# Uneditable section #\n", 112 | "\n", 113 | " return [qml.expval(qml.PauliZ(i)) for i in range(5)]" 114 | ] 115 | }, 116 | { 117 | "cell_type": "markdown", 118 | "id": "99867155", 119 | "metadata": {}, 120 | "source": [ 121 | "These functions are responsible for testing the solution. You will need to run the cell below. ***Do not modify the cell.***" 122 | ] 123 | }, 124 | { 125 | "cell_type": "code", 126 | "execution_count": null, 127 | "id": "bc2481f2", 128 | "metadata": {}, 129 | "outputs": [], 130 | "source": [ 131 | "def run(test_case_input: str) -> str:\n", 132 | "\n", 133 | " lmbda = json.loads(test_case_input)\n", 134 | " output = noisy_BernsteinVazirani(lmbda).tolist()\n", 135 | "\n", 136 | " return str(output)\n", 137 | "\n", 138 | "def check(solution_output: str, expected_output: str) -> None:\n", 139 | " \n", 140 | " solution_output = json.loads(solution_output)\n", 141 | " expected_output = json.loads(expected_output)\n", 142 | " assert np.allclose(\n", 143 | " solution_output, expected_output, rtol=1e-4\n", 144 | " ), \"Your noisy Bernstein-Vazirani algorithm isn't giving the right answers!\"" 145 | ] 146 | }, 147 | { 148 | "cell_type": "markdown", 149 | "id": "7ee648dd", 150 | "metadata": {}, 151 | "source": [ 152 | "### Test cases\n", 153 | " Running the cell below will load the test cases. ***Do not modify the cell***.\n", 154 | " - input: 0.1\n", 155 | " \t+ expected output: [-0.5641679, -0.5641679, 0.5641679, 0.5641679, -0.5641679]\n", 156 | " - input: 0.99\n", 157 | " \t+ expected output: [-0.01048576, -0.01048576, 0.01048576, 0.01048576, -0.01048576]" 158 | ] 159 | }, 160 | { 161 | "cell_type": "code", 162 | "execution_count": null, 163 | "id": "ec7b17ae", 164 | "metadata": {}, 165 | "outputs": [], 166 | "source": [ 167 | "test_cases = [['0.1', '[-0.5641679, -0.5641679, 0.5641679, 0.5641679, -0.5641679]'], ['0.99', '[-0.01048576, -0.01048576, 0.01048576, 0.01048576, -0.01048576]']]" 168 | ] 169 | }, 170 | { 171 | "cell_type": "markdown", 172 | "id": "1a8cbe1e", 173 | "metadata": {}, 174 | "source": [ 175 | "### Solution testing\n", 176 | " Once you have run every cell above, including the one with your code, the cell below will test your solution. Run the cell. If you are correct for all of the test cases, it means your solutions is correct. Otherwise, you need to double check your work. ***Do not modify the cell below.***" 177 | ] 178 | }, 179 | { 180 | "cell_type": "code", 181 | "execution_count": null, 182 | "id": "a04b2280", 183 | "metadata": {}, 184 | "outputs": [], 185 | "source": [ 186 | "for i, (input_, expected_output) in enumerate(test_cases):\n", 187 | " print(f\"Running test case {i} with input '{input_}'...\")\n", 188 | "\n", 189 | " try:\n", 190 | " output = run(input_)\n", 191 | "\n", 192 | " except Exception as exc:\n", 193 | " print(f\"Runtime Error. {exc}\")\n", 194 | "\n", 195 | " else:\n", 196 | " if message := check(output, expected_output):\n", 197 | " print(f\"Wrong Answer. Have: '{output}'. Want: '{expected_output}'.\")\n", 198 | "\n", 199 | " else:\n", 200 | " print(\"Correct!\")" 201 | ] 202 | } 203 | ], 204 | "metadata": {}, 205 | "nbformat": 4, 206 | "nbformat_minor": 5 207 | } 208 | -------------------------------------------------------------------------------- /a_tale_of_timbits/a_tale_of_timbits_200/README.md: -------------------------------------------------------------------------------- 1 | ### Backstory 2 | 3 | Zenda and Reece have determined Doc Trine's cell number in 4 | hyperjail. 5 | Searching through Trine's notebooks, they find another note, 6 | explaining how the hypercube is patrolled by a fearsome quantum 7 | warden, which is able to place itself in a superposition and inspect 8 | multiple cells at once. 9 | To avoid detection and rescue Doc Trine, they need to build a quantum 10 | radar! 11 | 12 | ### A quantum radar 13 | 14 | The quantum guard can place itself in a superposition 15 | 16 | $$ 17 | \vert \text{guard}\rangle = \sum_{x} g_x \vert x\rangle, 18 | $$ 19 | 20 | where $x \in \\{0, 1\\}^5$ ranges over all cell numbers, and $g_x$ are complex-valued amplitudes. Seen in this way, $|g_x|^2$ is the probability that the guard is at position $|x\rangle.$ 21 | They know that Doc Trine is located in a cell $c = (1, 1, 0, 0, 1).$ 22 | Ideally, they would like to wait until the guard's attention, captured by the probability $|g_c|^2$, is sufficiently low. 23 | 24 | In this challenge, we will look for a way to be able to measure $|g_c|^2.$ Unfortunately, there isn't much equipment in the office, and what is there is noisy! 25 | But Trine has left a collection of "Toffoli cascades" lying around, circuits made from a string of noisy Toffoli gates. Here is an example for three input qubits $\vert x_1\rangle \vert x_2\rangle \vert x_3\rangle$: 26 | 27 |
28 | A productive circuit 29 |
30 | 31 | Measuring the last qubit in the computational basis gives $\vert (x_1 \cdot x_2 \cdot x_3)\rangle$ with probability $1$, where $x_1 \cdot x_2 \cdot x_3$ indicates the *product* of classical bits $x_1$, $x_2$, and $x_3.$ 32 | There is a Toffoli cascade acting on $5$ input qubits (and with four auxiliary qubits) that Zenda and Reece can use, as well as some Pauli $X$ gates. 33 | All are subject to *depolarizing noise*, such that after each gate, the state on each qubit is replaced with something random with probability $\lambda.$ 34 | 35 | Your task: use noisy Toffoli cascades and noisy-Pauli X gates to build 36 | a *quantum radar*, which outputs $\vert g_c\vert^2$, the guard's 37 | attention on Trine's cell. 38 | The guard state will be an input, along with four auxiliary qubits 39 | starting in the $\vert 0 \rangle$ state. 40 | 41 | ## Challenge code 42 | 43 | In the code below, you are given various functions: 44 | - `noisy_PauliX`: which applies the Pauli-X gate and then a layer of depolarizing noise with parameter `lmbda`. (The noise is added for you.) 45 | - `Toffoli_cascade`: a cascade of noisy Toffoli gates (noise parameter 46 | `lmbda`) which help compute a product, as in the circuit pictured above, with the input qubits on `in_wires` and auxiliary system `aux_wires`. (The noise is added for you.) 47 | - `cascadar`: which takes a `guard_state (numpy.tensor)` and returns $|g_c|^2$, 48 | using noisy equipment with parameter `lmbda`. **You must complete this function**. 49 | 50 | ### Inputs 51 | 52 | The noisy quantum radar `cascadar` takes as input the guard state 53 | `guard_state (numpy.tensor)`, and a noise parameter `lmbda (float)` controlling the depolarizing noise. 54 | 55 | ### Output 56 | 57 | Your `cascadar` function should gives the correct probability 58 | $|g_c|^2$ for test cases, including the effects of noise. 59 | 60 | If your solution matches the correct one within the given tolerance 61 | specified in `check` (in this case it's a `1e-4` relative error 62 | tolerance), the output will be `"Correct!"` Otherwise, you will 63 | receive a `"Wrong answer"` prompt. 64 | -------------------------------------------------------------------------------- /a_tale_of_timbits/a_tale_of_timbits_200/images/box.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/XanaduAI/qhack_2023_coding_challenges/efc516ac412dc351ae8bf9745e304717b81d1ff3/a_tale_of_timbits/a_tale_of_timbits_200/images/box.png -------------------------------------------------------------------------------- /a_tale_of_timbits/a_tale_of_timbits_200/images/prod.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/XanaduAI/qhack_2023_coding_challenges/efc516ac412dc351ae8bf9745e304717b81d1ff3/a_tale_of_timbits/a_tale_of_timbits_200/images/prod.png -------------------------------------------------------------------------------- /a_tale_of_timbits/a_tale_of_timbits_300/README.md: -------------------------------------------------------------------------------- 1 | ### Backstory 2 | 3 | Now Zenda and Reece know where Trine is in hyperjail, and how to evade 4 | the quantum guard who patrols the hypercube. 5 | The only question is how to get there! 6 | Doc Trine's journal explains that the portal to hyperjail is held open by exotic 7 | matter, and the quantum sensor not only helps avoid the guard, but can 8 | be used to detect this matter! 9 | But the galaxy is a big place. 10 | How do Zenda and Reece find the entrance to hyperjail? 11 | 12 | Thankfully, they stumble onto a section of Trine's journal entitled 13 | 'How to build a robot swarm'. 14 | This not only directs them to an old storage cupboard with hundreds of 15 | jetpack-equipped robots, but instructions for coordinating them using a special entangled state. 16 | Zenda and Reece need to search the office and see if this state can be 17 | found! 18 | There are several mysterious boxes which, at the push of a button, 19 | output a quantum state $\rho.$ 20 | Zenda and Reece would like to figure out if any of these states will do. 21 | Unfortunately, noise makes it harder to tell what the states are! 22 | 23 | ### Blurry shadows 24 | 25 | Whenever Zenda and Reece push the button on a box and output a state in order to test it, it goes into a noisy circuit, where each qubit is subject to [depolarizing noise](https://docs.pennylane.ai/en/stable/code/api/pennylane.DepolarizingChannel.html), $\Delta_\lambda.$ If $\rho$ is a single-qubit density matrix, $\Delta_\lambda$ is defined by 26 | 27 | $$ 28 | \Delta_\lambda [\rho] = (1 - \lambda)\rho + \frac{\lambda}{2}I, 29 | $$ 30 | 31 | and with probability $\lambda$, the state is deleted and replaced with something random. 32 | Zenda and Reece suspect that noisy is making the states coming out of the box very hard to distinguish from random, and would like some way to test just how badly blurred they are. 33 | 34 | To explore this, we first note that any density matrix on $n$ qubits can be written as a linear combination of a special set of "Pauli" density matrices. These have the form 35 | 36 | $$ 37 | \rho_P = \frac{1}{2^n}(I + P), 38 | $$ 39 | 40 | where $P \in \\{I, X, Y, Z\\}^{\otimes n}$ is a tensor product of $n$ single-qubit Pauli operators, called a [Pauli word](https://docs.pennylane.ai/en/stable/code/qml_pauli.html). We'll let $\rho_P(\lambda) = \Delta_\lambda^{\otimes n}[\rho_P]$ label the result of applying a layer of depolarizing noise to the Pauli density $\rho_P.$ 41 | 42 | If adding noise makes a Pauli density matrix look random, a combination of Pauli densities — in other words, any matrix! — will look random. Here, "looks random" means "the expectation of any measurement is similar to the maximally mixed density matrix $\rho_0 = I/2^n$". 43 | Remarkably, we can capture all expectations at once using something called *trace 44 | distance* between density matrices. This is defined as 45 | 46 | $$ 47 | T(\rho, \sigma) = \frac{1}{2}\text{Tr}|\rho-\sigma|, 48 | $$ 49 | 50 | where $|A| = \sqrt{A^\dagger A}$ for a generic matrix $A$ (to calculate $|\rho-\sigma|$ you will be provided with the function `abs_dist`). 51 | For any (projective) measurement $M$, the trace distance between two density matrices $\rho$ and $\sigma$ bounds the difference in expectations: 52 | 53 | $$ 54 | \langle M\rangle_\rho - \langle M\rangle_\sigma = \text{Tr}[M(\rho -\sigma)] \leq T(\rho, \sigma). 55 | $$ 56 | 57 | If the trace distance is small, the two states are hard to tell apart with *any* measurement. 58 | 59 | Zenda and Reece suspect that the noise in their circuitry is blurring the states and making them hard to distinguish. 60 | Your goal is to write a function which verifies the bound 61 | 62 | $$ 63 | T(\rho_P(\lambda), \rho_0) \leq (1 - \lambda)^{|P|}, 64 | $$ 65 | 66 | by computing the difference between the right-hand side and left-hand side, where $|P|$ is the number of **non-identity** operators in the Pauli word $P.$ You should find this is always positive! Since a Pauli density matrix gets *exponentially* blurry, and all states can be built from these Pauli densities, most states will be exponentially hard to distinguish. 67 | 68 | 69 | ## Challenge code 70 | 71 | In the code below, you are given various functions: 72 | - `word_dist`: which counts the number of non-identity operators in a 73 | Pauli word. 74 | - `abs_dist`: which computes the distance $\vert \rho - \sigma \vert$ between density matrices (`rho` and `sigma`). 75 | - `noisy_Pauli_density`: a helper subcircuit which produces the density matrix $\rho_P$ 76 | associated with a Pauli word $P$ (`word`) and applies depolarizing 77 | noise to each qubit with parameter `lmbda`. It is merely a 78 | collection of gates, and should not return anything. **You must complete this function**. 79 | - `maxmix_trace_dist`: a helper function which calculates the trace distance 80 | $T(\rho_P(\lambda), \rho_0)$, from the noisy 81 | $\rho_Q$ (specified by `word` and `lmbda`) to the maximally mixed 82 | density $\rho_0.$ **You must complete this function**. 83 | - `bound_verifier`: a function which computes the difference 84 | $$(1-\lambda)^{|P|} - T(\rho_P(\lambda), \rho_0),$$ with both terms specified by `lmbda` and `P`. **You must complete this function**. 85 | 86 | ### Inputs 87 | 88 | The functions `noisy_Pauli_density`, `maxmix_trace_dist` and `bound_verifier` take as input a 89 | Pauli word (`word (str)`) represented as a string of characters `I`, 90 | `X`, `Y` and `Z`, and a noise parameter `lmbda (float)` giving 91 | probability of erasing the state of a qubit. 92 | 93 | Note that, for `noisy_Pauli_density`, you are working with the 94 | `default.mixed` device and can create a density matrix using 95 | [`qml.QubitDensityMatrix`](https://docs.pennylane.ai/en/stable/code/api/pennylane.QubitDensityMatrix.html). 96 | 97 | ### Output 98 | 99 | Your function `bound_verifier` must correctly compute the difference between the upper bound $(1 - \lambda)^{|P|}$ and the trace distance $T(\rho_P(\lambda), \rho_0)$ on test cases. 100 | 101 | If your solution matches the correct one within the given tolerance 102 | specified in `check` (in this case it's a `1e-4` relative error 103 | tolerance), the output will be `"Correct!"` Otherwise, you will 104 | receive a `"Wrong answer"` prompt. 105 | -------------------------------------------------------------------------------- /a_tale_of_timbits/a_tale_of_timbits_400/README.md: -------------------------------------------------------------------------------- 1 | ### Backstory 2 | 3 | Zenda and Reece have sore fingers from pushing buttons on the mystery 4 | boxes exponentially many times, but they finally have a catalogue of states. 5 | They can return to the fun problem of designing their robot swarm to 6 | explore the galaxy! 7 | The basic idea is that the robots share a state that allows them to move in a 8 | coordinated but random way (to avoid being Ove. A. Heard), and for 9 | individual robots to abort movement if they suspect (from their 10 | quantum radar) that they are being watched. 11 | 12 | ### Robot swarms and multipartite entanglement 13 | 14 | At this point, Zenda and Reece decide to build a swarm of robots to facilitate the search and exploration of space. Not only that, but they decide to use these robots to transport states in a secure way. In this case, they want to transport the "canonical" Bell state 15 | 16 | $$ 17 | \lvert \Phi \rangle = \frac{|0\rangle_H|000\rangle + |1\rangle_H|111\rangle}{\sqrt{2}}. 18 | $$ 19 | 20 |

21 | Noisy Bernstein-Vazirani 22 |

23 | 24 | The first qubit will remain in the Hub with Reece and Zenda, while the other three qubits will each be transported by a different robot. The problem is that space is not a safe place, and robots can be intercepted. If this happens, the qubit being transported will collapse, altering — due to entanglement — the state of all the other qubits carried by the remaining robots. 25 | For example, if the first robot is intercepted and its qubit collapses to $\vert 1 \rangle$, then all remaining qubits will collapse to $\vert 1 \rangle$ as well, and our Bell state will be destroyed. 26 | 27 | For that reason, a security protocol has been designed in which a robot, when it feels threatened, will apply an emergency gate $U$ on its qubit that somehow does not totally destroy the Bell state that we had initially when it is measured. 28 | 29 | After $U$ has been applied, the qubit will collapse and the robot will tell the Hub which state it is observing — 0 or 1. Immediately after sending the message, the robot self-destructs. With the information received from the destroyed robot, Zenda and Reece should be able to send a new robot with a certain state from the Hub such that the initial Bell state $\lvert \Phi \rangle$ is restored and shared between the hub and the existing robots. 30 | 31 | The following diagram offers a summary: 32 | 33 |

34 | Robot swarm 35 |

36 | 37 | We will use five qubits: `hub`, `robot1`, `robot2`, `robot3`, and `auxiliary_robot`. The three robots with the hub — `robot1`, `robot2`, and `robot3` — create the desired Bell state and then take off to begin their journey. 38 | In the diagram above, `robot1` detects a threat, so it applies $U$ and collapses its qubit. Knowing the `output`, the Hub configures the `auxiliary_robot` with a new gate so that now the `hub`, `robot2`, `robot3`, and the `auxiliary_robot` restore the desired state. 39 | 40 | Your goals in this challenge are threefold. First, you will devise the Bell preparation gate that outputs the Bell state $\lvert \Phi \rangle$ between the Hub and the robots. Next, you will decide on a good emergency gate $U$ that allows for the subsequent reconstruction of the Bell state. Finally, you will code the circuit that Zenda and Reece need to build in order to reconstruct the Bell state between the Hub, the new robot, and the surviving robots. 41 | 42 | ## Challenge code 43 | 44 | In the code below, you are given a few functions: 45 | 46 | - `bell_prearation`: creates the state $\frac{1}{\sqrt{2}}(|0000\rangle + |1111\rangle).$ This gate will act on the first 3 robots and the hub — `hub`, `robot1`, `robot2`, and `robot3`. **You must complete this function.** 47 | - `emergency_gate_U`: the gate, $U$, that somehow manages to save the total state after one of the robots is threatened and its qubit collapses. It will act only on one qubit. **You must complete this function.** 48 | - `setting_new_robot`: takes care of defining a new auxiliary robot configuration. It will only act on the `hub` and `auxiliary_robot` qubits. **You must complete this function.** 49 | 50 | ### Input 51 | 52 | In this challenge, there is no input. Our grader will simply check that the final state of the `hub`, `robot2`, `robot3`, and `auxiliary_robot` qubits is correct. 53 | 54 | ### Output 55 | 56 | This code will output the density matrix (`numpy.tensor`) of the `hub`, `robot2`, `robot3`, and `auxiliary_robot` system. 57 | 58 | If your solution matches the correct one within the given tolerance specified in `check` (in this case, it's a relative tolerance of `1e-5`), the output will be `"Correct!"` Otherwise, you will receive a `"Wrong answer"` prompt. 59 | 60 | Good luck! 61 | -------------------------------------------------------------------------------- /a_tale_of_timbits/a_tale_of_timbits_400/images/hub.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/XanaduAI/qhack_2023_coding_challenges/efc516ac412dc351ae8bf9745e304717b81d1ff3/a_tale_of_timbits/a_tale_of_timbits_400/images/hub.jpeg -------------------------------------------------------------------------------- /a_tale_of_timbits/a_tale_of_timbits_400/images/swarm.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/XanaduAI/qhack_2023_coding_challenges/efc516ac412dc351ae8bf9745e304717b81d1ff3/a_tale_of_timbits/a_tale_of_timbits_400/images/swarm.jpeg -------------------------------------------------------------------------------- /a_tale_of_timbits/a_tale_of_timbits_500/images/timbit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/XanaduAI/qhack_2023_coding_challenges/efc516ac412dc351ae8bf9745e304717b81d1ff3/a_tale_of_timbits/a_tale_of_timbits_500/images/timbit.png -------------------------------------------------------------------------------- /bending_bennetts_laws/bending_bennets_laws_100/Ctrl-Z.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "id": "78662d23", 6 | "metadata": {}, 7 | "source": [ 8 | "## Challenge code\n", 9 | " \n", 10 | " In the code below, you are given a function called `AND(j, k)`. **You\n", 11 | " must complete this circuit** and provide gates which implement a\n", 12 | " classical AND gate.\n", 13 | " More precisely, if the second and third qubits are in states $\\vert\n", 14 | " j\\rangle$ and $\\vert k\\rangle$, the circuit should place the first\n", 15 | " qubit in state $\\vert\\text{AND}(j, k)\\rangle.$\n", 16 | " \n", 17 | " ### Inputs\n", 18 | " \n", 19 | " As input to this problem, you are given two bits `j (int)` and `k\n", 20 | " (int)`, encoded onto the second and third qubits for you.\n", 21 | " \n", 22 | " ### Output\n", 23 | " \n", 24 | " Your circuit must place the first qubit in basis state `AND(j,\n", 25 | " k)`. This will be checked using `qml.probs(wires = 0)`, which gives\n", 26 | " `[1, 0]` for $\\vert 0\\rangle$ and `[0, 1]` for $\\vert 1\\rangle.$\n", 27 | " \n", 28 | " If your solution matches the correct one within the given tolerance\n", 29 | " specified in `check` (in this case it's a `1e-4` relative error\n", 30 | " tolerance), the output will be `\"Correct!\"` Otherwise, you will\n", 31 | " receive a `\"Wrong answer\"` prompt.\n", 32 | " ### Imports\n", 33 | " The cell below specifies the libraries you should use in this challenge. Run the cell to import the libraries. ***Do not modify the cell.***" 34 | ] 35 | }, 36 | { 37 | "cell_type": "code", 38 | "execution_count": null, 39 | "id": "e53622cc", 40 | "metadata": {}, 41 | "outputs": [], 42 | "source": [ 43 | "import json\n", 44 | "import pennylane as qml\n", 45 | "from pennylane import numpy as np" 46 | ] 47 | }, 48 | { 49 | "cell_type": "markdown", 50 | "id": "8ebcc779", 51 | "metadata": {}, 52 | "source": [ 53 | "### Code\n", 54 | " Complete the code below. Note that during QHack, some sections were not editable. We've marked those sections accordingly here, but you can still edit them if you wish." 55 | ] 56 | }, 57 | { 58 | "cell_type": "code", 59 | "execution_count": null, 60 | "id": "b308433c", 61 | "metadata": {}, 62 | "outputs": [], 63 | "source": [ 64 | "# Uneditable section #\n", 65 | "\n", 66 | "dev = qml.device(\"default.qubit\", wires=3)\n", 67 | "\n", 68 | "@qml.qnode(dev)\n", 69 | "def AND(j, k):\n", 70 | " \"\"\"Implements the AND gate using quantum gates and computes j AND k.\n", 71 | "\n", 72 | " Args:\n", 73 | " j (int): A classical bit, either 0 or 1. \n", 74 | " k (int): A classical bit, either 0 or 1. \n", 75 | "\n", 76 | " Returns:\n", 77 | " float: The probabilities of measurement on wire 0.\n", 78 | " \"\"\"\n", 79 | "\n", 80 | " if j == 1:\n", 81 | " qml.PauliX(wires=1)\n", 82 | " if k == 1:\n", 83 | " qml.PauliX(wires=2)\n", 84 | "\n", 85 | " # End of uneditable section #\n", 86 | "\n", 87 | " \n", 88 | " # Put your code here #\n", 89 | "\n", 90 | "\n", 91 | "# Uneditable section #\n", 92 | "\n", 93 | " qml.ctrl(qml.PauliZ, control =[0, 1])(wires = [2])\n", 94 | " \n", 95 | " # End of uneditable section #\n", 96 | "\n", 97 | " \n", 98 | " # Your code here #\n", 99 | "\n", 100 | " return qml.probs(wires=0)" 101 | ] 102 | }, 103 | { 104 | "cell_type": "markdown", 105 | "id": "3c4834b6", 106 | "metadata": {}, 107 | "source": [ 108 | "These functions are responsible for testing the solution. You will need to run the cell below. ***Do not modify the cell.***" 109 | ] 110 | }, 111 | { 112 | "cell_type": "code", 113 | "execution_count": null, 114 | "id": "9c72c6cd", 115 | "metadata": {}, 116 | "outputs": [], 117 | "source": [ 118 | "def run(test_case_input: str) -> str:\n", 119 | " j, k = json.loads(test_case_input)\n", 120 | " output = AND(j, k).tolist()\n", 121 | "\n", 122 | " return str(output)\n", 123 | "\n", 124 | "def check(solution_output: str, expected_output: str) -> None:\n", 125 | " solution_output = json.loads(solution_output)\n", 126 | " expected_output = json.loads(expected_output)\n", 127 | " assert np.allclose(solution_output, expected_output, rtol=1e-4), \"Your classical operation isn't behaving correctly!\"" 128 | ] 129 | }, 130 | { 131 | "cell_type": "markdown", 132 | "id": "bbbb9b5d", 133 | "metadata": {}, 134 | "source": [ 135 | "### Test cases\n", 136 | " Running the cell below will load the test cases. ***Do not modify the cell***.\n", 137 | " - input: [0, 0]\n", 138 | " \t+ expected output: [1, 0]\n", 139 | " - input: [1, 1]\n", 140 | " \t+ expected output: [0, 1]\n", 141 | " - input: [0, 1]\n", 142 | " \t+ expected output: [1, 0]\n", 143 | " - input: [1, 0]\n", 144 | " \t+ expected output: [1, 0]" 145 | ] 146 | }, 147 | { 148 | "cell_type": "code", 149 | "execution_count": null, 150 | "id": "d2232fdd", 151 | "metadata": {}, 152 | "outputs": [], 153 | "source": [ 154 | "test_cases = [['[0, 0]', '[1, 0]'], ['[1, 1]', '[0, 1]'], ['[0, 1]', '[1, 0]'], ['[1, 0]', '[1, 0]']]" 155 | ] 156 | }, 157 | { 158 | "cell_type": "markdown", 159 | "id": "9e7b8fd3", 160 | "metadata": {}, 161 | "source": [ 162 | "### Solution testing\n", 163 | " Once you have run every cell above, including the one with your code, the cell below will test your solution. Run the cell. If you are correct for all of the test cases, it means your solutions is correct. Otherwise, you need to double check your work. ***Do not modify the cell below.***" 164 | ] 165 | }, 166 | { 167 | "cell_type": "code", 168 | "execution_count": null, 169 | "id": "ed2e5d33", 170 | "metadata": {}, 171 | "outputs": [], 172 | "source": [ 173 | "for i, (input_, expected_output) in enumerate(test_cases):\n", 174 | " print(f\"Running test case {i} with input '{input_}'...\")\n", 175 | "\n", 176 | " try:\n", 177 | " output = run(input_)\n", 178 | "\n", 179 | " except Exception as exc:\n", 180 | " print(f\"Runtime Error. {exc}\")\n", 181 | "\n", 182 | " else:\n", 183 | " if message := check(output, expected_output):\n", 184 | " print(f\"Wrong Answer. Have: '{output}'. Want: '{expected_output}'.\")\n", 185 | "\n", 186 | " else:\n", 187 | " print(\"Correct!\")" 188 | ] 189 | } 190 | ], 191 | "metadata": {}, 192 | "nbformat": 4, 193 | "nbformat_minor": 5 194 | } 195 | -------------------------------------------------------------------------------- /bending_bennetts_laws/bending_bennets_laws_100/README.md: -------------------------------------------------------------------------------- 1 | ### Backstory 2 | 3 | Zenda and Reece work at Trine's Designs, a startup run by the 4 | eccentric inventor Doc Trine. 5 | Trine promises to tell Zenda and Reece about a 6 | revolutionary new type of quantum resource she has invented called "*timbits*". 7 | Before explaining timbits, she insists on demonstrating [Bennett's 8 | Laws of Infodynamics](https://en.wikipedia.org/wiki/Bennett%27s_laws), 9 | governing the behaviour of quantum information. 10 | "*Only then*," she says, "*will the power of 11 | timbits be revealed in their full glory*." 12 | 13 | ### Reversible computation 14 | 15 | Some classical logical operations are *irreversible*. For instance, 16 | 17 | $$ 18 | \text{AND}(0, 0)= \text{AND}(0, 1)= \text{AND}(1, 0)= 0, 19 | $$ 20 | 21 | so given that $\text{AND}(j, k) = 0$, we can't tell the values of $j$ and $k.$ 22 | 23 |
24 | AND 25 |
26 | 27 | Put differently, there is no way to press `ctrl-Z` and learn what went in! In contrast, quantum circuits are built out of unitary gates, which are always reversible. We can always press `ctrl-Z`! How can we encode something irreversible, like an AND gate, into a quantum circuit? Aptly, the answer is a controlled $Z$ gate! It encodes the classical operation into a *phase*: 28 | 29 | $$ 30 | CZ \vert j, k\rangle \mapsto (-1)^{\text{AND}(j, k)}\vert j, k\rangle. 31 | $$ 32 | 33 | A phase by itself is unobservable, so we need to interfere this state with some others to detect it. A simple way to do this is to use a *controlled* controlled $Z$ gate, with some extra operations on either side: 34 | 35 |
36 | AND 37 |
38 | 39 | Your job: figure out which operations to apply so that measurement on 40 | the first qubit is guaranteed to be in state 41 | $\vert \text{AND}(j, k)\rangle$. 42 | 43 | ### Laws of Infodynamics: The First Law (optional) 44 | 45 | This box contains some interesting but nonessential details. 46 | A qubit can be used to imitate a classical bit (which we'll call 47 | *cbits*), since instead of sending a cbit $j$, we can send a basis 48 | state $\vert j\rangle.$ We can write this as an inequality, the First 49 | Law of Infodynamics: 50 | 51 | $$ 52 | 1 \text{ qubit} \geq 1 \text{ cbit}. \tag{1} 53 | $$ 54 | 55 | But although we can encode classical data into qubits, it's not 56 | obvious we can always compute in the same way. 57 | 58 | ## Challenge code 59 | 60 | In the code below, you are given a function called `AND(j, k)`. **You 61 | must complete this circuit** and provide gates which implement a 62 | classical AND gate. 63 | More precisely, if the second and third qubits are in states $\vert 64 | j\rangle$ and $\vert k\rangle$, the circuit should place the first 65 | qubit in state $\vert\text{AND}(j, k)\rangle.$ 66 | 67 | ### Inputs 68 | 69 | As input to this problem, you are given two bits `j (int)` and `k 70 | (int)`, encoded onto the second and third qubits for you. 71 | 72 | ### Output 73 | 74 | Your circuit must place the first qubit in basis state `AND(j, 75 | k)`. This will be checked using `qml.probs(wires = 0)`, which gives 76 | `[1, 0]` for $\vert 0\rangle$ and `[0, 1]` for $\vert 1\rangle.$ 77 | 78 | If your solution matches the correct one within the given tolerance 79 | specified in `check` (in this case it's a `1e-4` relative error 80 | tolerance), the output will be `"Correct!"` Otherwise, you will 81 | receive a `"Wrong answer"` prompt. 82 | -------------------------------------------------------------------------------- /bending_bennetts_laws/bending_bennets_laws_100/images/and.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/XanaduAI/qhack_2023_coding_challenges/efc516ac412dc351ae8bf9745e304717b81d1ff3/bending_bennetts_laws/bending_bennets_laws_100/images/and.png -------------------------------------------------------------------------------- /bending_bennetts_laws/bending_bennets_laws_100/images/ctrl-Z.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/XanaduAI/qhack_2023_coding_challenges/efc516ac412dc351ae8bf9745e304717b81d1ff3/bending_bennetts_laws/bending_bennets_laws_100/images/ctrl-Z.png -------------------------------------------------------------------------------- /bending_bennetts_laws/bending_bennets_laws_200/README.md: -------------------------------------------------------------------------------- 1 | ### Backstory 2 | 3 | Zenda and Reece have worked hard to implement classical computation 4 | reversibly. 5 | "*This is all rather boring though,*" says Trine. "*Let's introduce 6 | entanglement and have some fun!*" 7 | Trine tells them that the next [Laws of 8 | Infodynamics](https://en.wikipedia.org/wiki/Bennett%27s_laws) will 9 | constrain how much classical information can be sent using entangled quantum 10 | resources. 11 | 12 | ### Sending information with entangled states 13 | 14 | Entanglement is a valuable resource that can be used to send 15 | information, as we will explore in this challenge. 16 | Superdense coding, for instance, uses Bell pairs to send two classical 17 | bits with a single qubit. 18 | 19 | Trine has misplaced her usual Bell states, and instead provides Zenda with 2 qubits and Reece with 1 qubit. They are entangled forming the following state: 20 | 21 | $$ 22 | \vert \Psi \rangle = \frac{|00\rangle_Z|0\rangle_R + |11\rangle_Z|1\rangle_R}{\sqrt{2}}. 23 | $$ 24 | 25 | Zenda wants to send Reece 3 bits of information $(i,j,k),$ where each bit can take the value 0 or 1. To do so, she will apply an **encoding gate** on her two qubits and then send them to Bob. 26 | 27 | Reece, who now has the three qubits and knows the strategy Zenda uses to encode, performs a decoding gate that will generate the state $|i,j,k\rangle.$ 28 | Let's look at the following drawing to understand it. 29 | 30 |

31 | Sup-superdense 32 |

33 | 34 | Your goal will be to devise a coding and decoding strategy such that Reece can decode Zenda's bits, as shown in the figure above. 35 | 36 | The strategy to build the encoding gate is akin to [superdense coding](https://en.wikipedia.org/wiki/Superdense_coding) for two bits of information, where all the Bell basis states are produced by acting only on one of the qubits in an entangled pair. Here, we want to produce all the GHZ basis states, which are analogous to the Bell basis for three qubits. They are given by 37 | 38 | $$ 39 | \lvert \text{GHZ} \rangle_{ijk} = \frac{1}{\sqrt{2}}\left(\vert 0 j k\rangle +(-1)^i\vert 1 \bar{j} \bar{k}\rangle\right), 40 | $$ 41 | 42 | where $\bar{j}= 1-j$ and $\bar{k}= 1-k$. However, we should do this by acting only on the first two qubits (i.e. Zenda's share) of the entangled state $\vert\Psi\rangle$ that Trine provided. The decoding gate is also inspired by superdense coding, so reviewing the topic will help you a lot in this challenge! 43 | 44 | ### Laws of Infodynamics: The Second and Third Laws (optional) 45 | 46 | This box contains information that may be helpful, but is not 47 | essential to solving the problem. 48 | Suppose Zenda and Reece share a maximally entangled Bell pair of the 49 | form 50 | 51 | $$ 52 | \vert \Phi\rangle_{ZR} = \frac{\vert 0\rangle_Z \vert 53 | 0\rangle_R + \vert 1\rangle_Z \vert 1\rangle_R}{\sqrt{2}}, 54 | $$ 55 | 56 | where the subscripts $Z$ and $R$ denote Zenda and Reece's share, respectively. 57 | This is one of four maximally entangled *Bell states*, labelled by two 58 | bits $j$ and $k$: 59 | 60 | $$ 61 | \vert\beta(j, k)\rangle_{ZR} = \frac{1}{\sqrt{2}}(\vert 0\rangle_Z 62 | \vert k\rangle_BR+ (-1)^j \vert 1\rangle_Z \vert k \oplus 63 | 1\rangle_R), 64 | $$ 65 | 66 | with $\vert\Phi\rangle_{ZR} = \vert\beta(0,0)\rangle_{ZR}.$ 67 | These are orthogonal and form what is called the *Bell basis* for the 68 | states on two qubits. 69 | 70 | Half of an entangled state is called an entangled qubit or *ebit*. 71 | Since the ability to send an entangled qubit is a special case of 72 | sending a qubit, we have the Second Law of Infodynamics: 73 | 74 | $$ 75 | 1 \text{ qubit} \geq 1 \text{ ebit}, \tag{2} 76 | $$ 77 | 78 | where $x \geq y$ means having resource $x$ also provides resource $y.$ 79 | It's easy to check that 80 | 81 | $$ 82 | \vert \beta(j, k)\rangle = (Z^jX^k \otimes I )\vert \Phi\rangle. 83 | $$ 84 | 85 | We draw this below: 86 | 87 |
88 | Bell states 89 |
90 | 91 | If Zenda and Reece share $\vert\Phi\rangle$ (an ebit), and Zenda sends her 92 | qubit to Reece, Reece can measure in the Bell 93 | basis and learn $j$ and $k.$ Thus, an ebit and a qubit suffice to 94 | send two classical bits (or *cbits*). 95 | This protocol, called *superdense coding*, can be expressed as 96 | the Third Law of Infodynamics: 97 | 98 | $$ 99 | 1 \text{ qubit} + 1 \text{ ebit} \geq 2 \text{ cbits}. \tag{3} 100 | $$ 101 | 102 | 103 | ## Challenge code 104 | 105 | You simply have to complete two quantum functions: 106 | 107 | - `encode`: quantum function that will define an operator to be applied only on Zenda's qubits. This function will depend on the bits $(i,j,k)$ to be encoded. 108 | 109 | 110 | - `decode`: quantum function that defines the operator that Reece will use to retrieve the bits that Zenda sent. In this case, the operator does not have any information about Zenda's bits, so the same operators will always be applied regardless of the state that Zenda sends Reece. 111 | 112 | ### Output 113 | 114 | In this challenge, we will not judge your solution using public or private test cases. Instead, we will check that, for all combinations of $i$, $j$, and $k$, the entire encoding and decoding circuit behaves as expected. 115 | 116 | -------------------------------------------------------------------------------- /bending_bennetts_laws/bending_bennets_laws_200/images/model_superdense.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/XanaduAI/qhack_2023_coding_challenges/efc516ac412dc351ae8bf9745e304717b81d1ff3/bending_bennetts_laws/bending_bennets_laws_200/images/model_superdense.jpeg -------------------------------------------------------------------------------- /bending_bennetts_laws/bending_bennets_laws_200/images/sd.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/XanaduAI/qhack_2023_coding_challenges/efc516ac412dc351ae8bf9745e304717b81d1ff3/bending_bennetts_laws/bending_bennets_laws_200/images/sd.png -------------------------------------------------------------------------------- /bending_bennetts_laws/bending_bennets_laws_200/sub_superdense_coding.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "id": "22cfe6be", 6 | "metadata": {}, 7 | "source": [ 8 | "## Challenge code\n", 9 | " \n", 10 | " You simply have to complete two quantum functions:\n", 11 | " \n", 12 | " - `encode`: quantum function that will define an operator to be applied only on Zenda's qubits. This function will depend on the bits $(i,j,k)$ to be encoded.\n", 13 | " \n", 14 | " \n", 15 | " - `decode`: quantum function that defines the operator that Reece will use to retrieve the bits that Zenda sent. In this case, the operator does not have any information about Zenda's bits, so the same operators will always be applied regardless of the state that Zenda sends Reece.\n", 16 | " \n", 17 | " ### Output\n", 18 | " \n", 19 | " In this challenge, we will not judge your solution using public or private test cases. Instead, we will check that, for all combinations of $i$, $j$, and $k$, the entire encoding and decoding circuit behaves as expected.\n", 20 | " \n", 21 | " ### Imports\n", 22 | " The cell below specifies the libraries you should use in this challenge. Run the cell to import the libraries. ***Do not modify the cell.***" 23 | ] 24 | }, 25 | { 26 | "cell_type": "code", 27 | "execution_count": null, 28 | "id": "a551989c", 29 | "metadata": {}, 30 | "outputs": [], 31 | "source": [ 32 | "import pennylane as qml\n", 33 | "from pennylane import numpy as np" 34 | ] 35 | }, 36 | { 37 | "cell_type": "markdown", 38 | "id": "c3062623", 39 | "metadata": {}, 40 | "source": [ 41 | "### Code\n", 42 | " Complete the code below. Note that during QHack, some sections were not editable. We've marked those sections accordingly here, but you can still edit them if you wish." 43 | ] 44 | }, 45 | { 46 | "cell_type": "code", 47 | "execution_count": null, 48 | "id": "9dc25702", 49 | "metadata": {}, 50 | "outputs": [], 51 | "source": [ 52 | "# Uneditable section #\n", 53 | "def encode(i, j, k):\n", 54 | " \"\"\"\n", 55 | " Quantum encoding function. It must act only on the first two qubits.\n", 56 | " This function does not return anything, it simply applies gates.\n", 57 | "\n", 58 | " Args:\n", 59 | " i, j, k (int): The three encoding bits. They will take the values 1 or 0.\n", 60 | "\n", 61 | " \"\"\"\n", 62 | " # End of uneditable section #\n", 63 | "\n", 64 | " # Put your code here #\n", 65 | "\n", 66 | "# Uneditable section #\n", 67 | "def decode():\n", 68 | " \"\"\"\n", 69 | " Quantum decoding function. It can act on the three qubits.\n", 70 | " This function does not return anything, it simply applies gates.\n", 71 | " \"\"\"\n", 72 | "\n", 73 | " # End of uneditable section #\n", 74 | "\n", 75 | " # Put your code here #\n", 76 | "\n", 77 | "# Uneditable section #\n", 78 | "dev = qml.device(\"default.qubit\", wires=3)\n", 79 | "\n", 80 | "@qml.qnode(dev)\n", 81 | "def circuit(i, j, k):\n", 82 | " \"\"\"\n", 83 | " Circuit that generates the complete communication protocol.\n", 84 | "\n", 85 | " Args:\n", 86 | " i, j, k (int): The three encoding bits. They will take the value 1 or 0.\n", 87 | " \"\"\"\n", 88 | "\n", 89 | " # We prepare the state 1/sqrt(2)(|000> + |111>)\n", 90 | " qml.Hadamard(wires=0)\n", 91 | " qml.CNOT(wires=[0, 1])\n", 92 | " qml.CNOT(wires=[0, 2])\n", 93 | "\n", 94 | " # Zenda encodes the bits\n", 95 | " encode(i, j, k)\n", 96 | "\n", 97 | " # Reece decode the information\n", 98 | " decode()\n", 99 | "\n", 100 | " return qml.probs(wires=range(3))" 101 | ] 102 | }, 103 | { 104 | "cell_type": "markdown", 105 | "id": "19fb1d66", 106 | "metadata": {}, 107 | "source": [ 108 | "These functions are responsible for testing the solution. You will need to run the cell below. ***Do not modify the cell.***" 109 | ] 110 | }, 111 | { 112 | "cell_type": "code", 113 | "execution_count": null, 114 | "id": "c4b19c6f", 115 | "metadata": {}, 116 | "outputs": [], 117 | "source": [ 118 | "def run(test_case_input: str) -> str:\n", 119 | "\n", 120 | " return None\n", 121 | "\n", 122 | "def check(solution_output: str, expected_output: str) -> None:\n", 123 | "\n", 124 | " for i in range(2):\n", 125 | " for j in range(2):\n", 126 | " for k in range(2):\n", 127 | " assert np.isclose(circuit(i, j , k)[4 * i + 2 * j + k],1)\n", 128 | "\n", 129 | " dev = qml.device(\"default.qubit\", wires=3)\n", 130 | "\n", 131 | " @qml.qnode(dev)\n", 132 | " def circuit2(i, j, k):\n", 133 | " encode(i, j, k)\n", 134 | " return qml.probs(wires=range(3))\n", 135 | "\n", 136 | " circuit2(i, j, k)\n", 137 | " ops = circuit2.tape.operations\n", 138 | "\n", 139 | " for op in ops:\n", 140 | " assert not (2 in op.wires), \"Invalid connection between qubits.\"" 141 | ] 142 | }, 143 | { 144 | "cell_type": "markdown", 145 | "id": "1f8a597f", 146 | "metadata": {}, 147 | "source": [ 148 | "### Test cases\n", 149 | " Running the cell below will load the test cases. ***Do not modify the cell***.\n", 150 | " - input: No input\n", 151 | " \t+ expected output: No output\n", 152 | " - input: No input\n", 153 | " \t+ expected output: No output" 154 | ] 155 | }, 156 | { 157 | "cell_type": "code", 158 | "execution_count": null, 159 | "id": "c194148e", 160 | "metadata": {}, 161 | "outputs": [], 162 | "source": [ 163 | "test_cases = [['No input', 'No output'], ['No input', 'No output']]" 164 | ] 165 | }, 166 | { 167 | "cell_type": "markdown", 168 | "id": "a81a70bb", 169 | "metadata": {}, 170 | "source": [ 171 | "### Solution testing\n", 172 | " Once you have run every cell above, including the one with your code, the cell below will test your solution. Run the cell. If you are correct for all of the test cases, it means your solutions is correct. Otherwise, you need to double check your work. ***Do not modify the cell below.***" 173 | ] 174 | }, 175 | { 176 | "cell_type": "code", 177 | "execution_count": null, 178 | "id": "c012680c", 179 | "metadata": {}, 180 | "outputs": [], 181 | "source": [ 182 | "for i, (input_, expected_output) in enumerate(test_cases):\n", 183 | " print(f\"Running test case {i} with input '{input_}'...\")\n", 184 | "\n", 185 | " try:\n", 186 | " output = run(input_)\n", 187 | "\n", 188 | " except Exception as exc:\n", 189 | " print(f\"Runtime Error. {exc}\")\n", 190 | "\n", 191 | " else:\n", 192 | " if message := check(output, expected_output):\n", 193 | " print(f\"Wrong Answer. Have: '{output}'. Want: '{expected_output}'.\")\n", 194 | "\n", 195 | " else:\n", 196 | " print(\"Correct!\")" 197 | ] 198 | } 199 | ], 200 | "metadata": {}, 201 | "nbformat": 4, 202 | "nbformat_minor": 5 203 | } 204 | -------------------------------------------------------------------------------- /bending_bennetts_laws/bending_bennets_laws_300/README.md: -------------------------------------------------------------------------------- 1 | ### Backstory 2 | 3 | Now Zenda and Reece have a cute way to send each other private 4 | messages using entangled qubits. 5 | Trine applauds them. "*Good work! But now that I think of it, 6 | superdense coding can be reversed, in a manner of speaking, to send 7 | quantum information using entanglement and classical bits. This will 8 | not only bring us to the last [Law of 9 | Infodynamics](https://en.wikipedia.org/wiki/Bennett%27s_laws), but 10 | teach us some basic facts about spacetime! Certain things have to be 11 | hidden from Nature itself.*" Zenda and Reece look perplexed. Trine 12 | smiles: "*Wait until I show you what timbits can do!*" 13 | 14 | ### From causality to encryption 15 | 16 | Zenda needs to send quantum states to Reece over a channel where 17 | someone could intercept the messages. They decide to encode the states 18 | they want to send with rotations on all of the qubits. To do this, they 19 | have chosen two real numbers, $\alpha$ and $\beta$, in advance, so 20 | that the states can be encoded as follows: 21 | 22 |

23 | Cbit vs cobit 24 |

25 | 26 | In this case, $U(\theta)$ is defined as the gate that generates the state $|{\psi}\rangle$ — what Zenda wants to send to Reece — that depends on a real number $\theta.$ 27 | Thus, if someone intercepts the message, instead of getting state $|\psi\rangle$ they will get state $(R_X(\beta)R_Z(\alpha))^{\otimes 2}|\psi\rangle.$ 28 | 29 | Although it seems like a super secure encoding procedure, it is not perfect! Once $\alpha$ and $\beta$ have been chosen, there are certain values of $\theta$ that could make $(R_X(\beta)R_Z(\alpha))^{\otimes 2}|\psi\rangle = |\psi\rangle$ for certain states. This is a big problem — it means that someone is going to intercept the hidden state! 30 | 31 | We will say that $\alpha$ and $\beta$ are $\epsilon$-unsafe values if there exists a $\theta$ such that 32 | 33 | $$ 34 | |\langle 0|U^{\dagger}(\theta)(R_X(\beta)R_Z(\alpha))^{\otimes 2}U(\theta)|0\rangle|^2 \ge 1 - \epsilon. 35 | $$ 36 | 37 | Your goal is to determine if $\alpha$ and $\beta$ are unsafe values given $\epsilon.$ 38 | 39 | ### Laws of Infodynamics: The Fourth Law (optional) 40 | 41 | This box contains information that is not essential to solving the problem. 42 | Superdense coding sends two classical bits (cbits) via a qubit 43 | and half of an entangled Bell pair (ebit). 44 | Teleportation is a converse protocol, sending a qubit with two cbits 45 | and an ebit. 46 | Suppose Zenda has a state $\vert\psi\rangle_{Z'}$ she wants to send to Reece, 47 | and they share a Bell state $\vert\beta(0,0)\rangle_{ZR}$, where 48 | 49 | $$ 50 | \vert\beta(j, k)\rangle_{ZR} = \frac{1}{\sqrt{2}}(\vert 0\rangle_Z 51 | \vert k\rangle_R + (-1)^j \vert 1\rangle_Z \vert k \oplus 52 | 1\rangle_R). 53 | $$ 54 | 55 | We use the notation $\vert\Phi\rangle = \vert \beta(0,0)\rangle$ for 56 | the "canonical" Bell pair. 57 | Here, $Z'$ denotes Zenda's qubit where the state for teleportation is 58 | initially stored, and $Z$ the qubit which is initially entangled with Reece. 59 | Some algebra shows that the state of the whole system is 60 | 61 | $$ 62 | \vert \psi\rangle_{Z'} \vert \Phi\rangle_{ZR} = \frac{1}{2}\sum_{jk} \vert 63 | \beta(j, k)\rangle_{Z'Z} X^kZ^j \vert\psi\rangle_R. 64 | $$ 65 | 66 | Note that in the operators $X^j Z^j$, $k$ comes *before* $j.$ 67 | If Zenda performs a Bell measurement (i.e. measure in the basis 68 | $\{\vert\beta(j,k)\rangle\}$) on her system, she will learn two 69 | bits $j$ and $k$, and Reece will have Zenda's state in the disguised 70 | form $X^kZ^j \vert\psi\rangle.$ 71 | For instance, if Zenda measures $j = k = 0$, we apply the projector 72 | 73 | $$ 74 | P = \vert\beta(0,0)\rangle\langle \beta(0,0) \vert_{Z'Z}, 75 | $$ 76 | 77 | normalize, and obtain a post-measurement state 78 | 79 | $$ 80 | \vert\beta(0, 0)\rangle_{Z'Z}\vert\psi\rangle_R. 81 | $$ 82 | 83 | After she measures the cbits $j$ and $k$, Zenda can send them to 84 | Reece, who takes off the disguise $X^k Z^j$ to find 85 | $\vert\psi\rangle.$ 86 | Since an ebit and two classical bits suffice to 87 | teleport a qubit in an arbitrary state, we have the Fourth Law of 88 | Infodynamics: 89 | 90 | $$ 91 | 1 \text{ ebit} + 2 \text{ cbits} \geq 1 \text{ qubit} \tag{4} 92 | $$ 93 | 94 | where $x \geq y$ means having resource $x$ also provides resource $y.$ 95 | The disguising operators $X^kZ^j$ seem like a nuisance, but turn out 96 | to be essential to maintaining the fabric of spacetime! 97 | Since entanglement acts in a spooky, instantaneous way at a distance, 98 | if Zenda could magically teleport $\vert\psi\rangle_{Z'}$ to Reece without 99 | the disguise, she could send information faster than light. 100 | If Reece knows nothing about $j$ and $k$, it turns out that the state 101 | is perfectly disguised, in the sense that 102 | 103 | $$ 104 | \rho_R = \frac{1}{4}\sum_{jk} X^k Z^j \vert\psi\rangle\langle\psi\vert 105 | (X^k Z^j)^\dagger = \frac{1}{2}\mathbb{I}. 106 | $$ 107 | 108 | This inspired Zenda and Reece to play around with $X$ and $Z$ 109 | rotations as a way of concealing information. 110 | 111 | ## Challenge code 112 | 113 | In the code below, you are given a function called `is_unsafe`. **You must complete this function** by coming up with a way — you are given total freedom, from making a variational circuit to finding an analytical solution — to determine if the given values of $\alpha$ and $\beta$ values are $\epsilon$-unsafe. 114 | 115 | ### Inputs 116 | 117 | As input to this problem, you are given a `list(float)` containing the values of $\alpha$, $\beta$, and $\epsilon$, in that order. 118 | 119 | ### Output 120 | 121 | This code must output a boolean — `True` or `False` — corresponding to whether the values of $\alpha$ and $\beta$ are $\epsilon$-unsafe. 122 | For example, if you determine that the given values of $\alpha$ and $\beta$ *aren't* $\epsilon$-unsafe, your code must output `False`. 123 | 124 | If your solution is correct, the output will be `"Correct!"` Otherwise, you will receive a `"Wrong answer"` prompt. 125 | 126 | Good luck! 127 | -------------------------------------------------------------------------------- /bending_bennetts_laws/bending_bennets_laws_300/images/operator_encoder.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/XanaduAI/qhack_2023_coding_challenges/efc516ac412dc351ae8bf9745e304717b81d1ff3/bending_bennetts_laws/bending_bennets_laws_300/images/operator_encoder.jpeg -------------------------------------------------------------------------------- /bending_bennetts_laws/bending_bennets_laws_300/images/tel-bell.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/XanaduAI/qhack_2023_coding_challenges/efc516ac412dc351ae8bf9745e304717b81d1ff3/bending_bennetts_laws/bending_bennets_laws_300/images/tel-bell.png -------------------------------------------------------------------------------- /bending_bennetts_laws/bending_bennets_laws_300/secrets_in_spacetime.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "id": "c494ea60", 6 | "metadata": {}, 7 | "source": [ 8 | "## Challenge code\n", 9 | " \n", 10 | " In the code below, you are given a function called `is_unsafe`. **You must complete this function** by coming up with a way — you are given total freedom, from making a variational circuit to finding an analytical solution — to determine if the given values of $\\alpha$ and $\\beta$ values are $\\epsilon$-unsafe.\n", 11 | " \n", 12 | " ### Inputs\n", 13 | " \n", 14 | " As input to this problem, you are given a `list(float)` containing the values of $\\alpha$, $\\beta$, and $\\epsilon$, in that order.\n", 15 | " \n", 16 | " ### Output\n", 17 | " \n", 18 | " This code must output a boolean — `True` or `False` — corresponding to whether the values of $\\alpha$ and $\\beta$ are $\\epsilon$-unsafe.\n", 19 | " For example, if you determine that the given values of $\\alpha$ and $\\beta$ *aren't* $\\epsilon$-unsafe, your code must output `False`. \n", 20 | " \n", 21 | " If your solution is correct, the output will be `\"Correct!\"` Otherwise, you will receive a `\"Wrong answer\"` prompt.\n", 22 | " \n", 23 | " Good luck!\n", 24 | " ### Imports\n", 25 | " The cell below specifies the libraries you should use in this challenge. Run the cell to import the libraries. ***Do not modify the cell.***" 26 | ] 27 | }, 28 | { 29 | "cell_type": "code", 30 | "execution_count": null, 31 | "id": "45df8aa0", 32 | "metadata": {}, 33 | "outputs": [], 34 | "source": [ 35 | "import json\n", 36 | "import pennylane as qml\n", 37 | "from pennylane import numpy as np" 38 | ] 39 | }, 40 | { 41 | "cell_type": "markdown", 42 | "id": "8af25323", 43 | "metadata": {}, 44 | "source": [ 45 | "### Code\n", 46 | " Complete the code below. Note that during QHack, some sections were not editable. We've marked those sections accordingly here, but you can still edit them if you wish." 47 | ] 48 | }, 49 | { 50 | "cell_type": "code", 51 | "execution_count": null, 52 | "id": "01b81b8c", 53 | "metadata": {}, 54 | "outputs": [], 55 | "source": [ 56 | "# Uneditable section #\n", 57 | "def U_psi(theta):\n", 58 | " \"\"\"\n", 59 | " Quantum function that generates |psi>, Zenda's state wants to send to Reece.\n", 60 | "\n", 61 | " Args:\n", 62 | " theta (float): Parameter that generates the state.\n", 63 | "\n", 64 | " \"\"\"\n", 65 | " qml.Hadamard(wires = 0)\n", 66 | " qml.CRX(theta, wires = [0,1])\n", 67 | " qml.CRZ(theta, wires = [0,1])\n", 68 | "\n", 69 | "def is_unsafe(alpha, beta, epsilon):\n", 70 | " \"\"\"\n", 71 | " Boolean function that we will use to know if a set of parameters is unsafe.\n", 72 | "\n", 73 | " Args:\n", 74 | " alpha (float): parameter used to encode the state.\n", 75 | " beta (float): parameter used to encode the state.\n", 76 | " epsilon (float): unsafe-tolerance.\n", 77 | "\n", 78 | " Returns:\n", 79 | " (bool): 'True' if alpha and beta are epsilon-unsafe coefficients. 'False' in the other case.\n", 80 | "\n", 81 | " \"\"\"\n", 82 | " # End of uneditable section #\n", 83 | "\n", 84 | " # Put your code here #" 85 | ] 86 | }, 87 | { 88 | "cell_type": "markdown", 89 | "id": "f47d0e2a", 90 | "metadata": {}, 91 | "source": [ 92 | "These functions are responsible for testing the solution. You will need to run the cell below. ***Do not modify the cell.***" 93 | ] 94 | }, 95 | { 96 | "cell_type": "code", 97 | "execution_count": null, 98 | "id": "203710cb", 99 | "metadata": {}, 100 | "outputs": [], 101 | "source": [ 102 | "def run(test_case_input: str) -> str:\n", 103 | " ins = json.loads(test_case_input)\n", 104 | " output = is_unsafe(*ins)\n", 105 | " return str(output)\n", 106 | "\n", 107 | "def check(solution_output: str, expected_output: str) -> None:\n", 108 | " \n", 109 | " def bool_to_int(string):\n", 110 | " if string == \"True\":\n", 111 | " return 1\n", 112 | " return 0\n", 113 | "\n", 114 | " solution_output = bool_to_int(solution_output)\n", 115 | " expected_output = bool_to_int(expected_output)\n", 116 | " assert solution_output == expected_output, \"The solution is not correct.\"" 117 | ] 118 | }, 119 | { 120 | "cell_type": "markdown", 121 | "id": "0bb8c03b", 122 | "metadata": {}, 123 | "source": [ 124 | "### Test cases\n", 125 | " Running the cell below will load the test cases. ***Do not modify the cell***.\n", 126 | " - input: [0.1, 0.2, 0.3]\n", 127 | " \t+ expected output: True\n", 128 | " - input: [1.1, 1.2, 0.3]\n", 129 | " \t+ expected output: False\n", 130 | " - input: [1.1, 1.2, 0.4]\n", 131 | " \t+ expected output: True\n", 132 | " - input: [0.5, 1.9, 0.7]\n", 133 | " \t+ expected output: True\n", 134 | " - input: [0.5, 1.9, 0.3]\n", 135 | " \t+ expected output: False\n", 136 | " - input: [0.5, 1.1, 0.5]\n", 137 | " \t+ expected output: True\n", 138 | " - input: [0.1, 1.1, 0.2]\n", 139 | " \t+ expected output: False\n", 140 | " - input: [0.2, 1.0, 0.3]\n", 141 | " \t+ expected output: True" 142 | ] 143 | }, 144 | { 145 | "cell_type": "code", 146 | "execution_count": null, 147 | "id": "7b722359", 148 | "metadata": {}, 149 | "outputs": [], 150 | "source": [ 151 | "test_cases = [['[0.1, 0.2, 0.3]', 'True'], ['[1.1, 1.2, 0.3]', 'False'], ['[1.1, 1.2, 0.4]', 'True'], ['[0.5, 1.9, 0.7]', 'True'], ['[0.5, 1.9, 0.3]', 'False'], ['[0.5, 1.1, 0.5]', 'True'], ['[0.1, 1.1, 0.2]', 'False'], ['[0.2, 1.0, 0.3]', 'True']]" 152 | ] 153 | }, 154 | { 155 | "cell_type": "markdown", 156 | "id": "ac602cc8", 157 | "metadata": {}, 158 | "source": [ 159 | "### Solution testing\n", 160 | " Once you have run every cell above, including the one with your code, the cell below will test your solution. Run the cell. If you are correct for all of the test cases, it means your solutions is correct. Otherwise, you need to double check your work. ***Do not modify the cell below.***" 161 | ] 162 | }, 163 | { 164 | "cell_type": "code", 165 | "execution_count": null, 166 | "id": "ba1abfdb", 167 | "metadata": {}, 168 | "outputs": [], 169 | "source": [ 170 | "for i, (input_, expected_output) in enumerate(test_cases):\n", 171 | " print(f\"Running test case {i} with input '{input_}'...\")\n", 172 | "\n", 173 | " try:\n", 174 | " output = run(input_)\n", 175 | "\n", 176 | " except Exception as exc:\n", 177 | " print(f\"Runtime Error. {exc}\")\n", 178 | "\n", 179 | " else:\n", 180 | " if message := check(output, expected_output):\n", 181 | " print(f\"Wrong Answer. Have: '{output}'. Want: '{expected_output}'.\")\n", 182 | "\n", 183 | " else:\n", 184 | " print(\"Correct!\")" 185 | ] 186 | } 187 | ], 188 | "metadata": {}, 189 | "nbformat": 4, 190 | "nbformat_minor": 5 191 | } 192 | -------------------------------------------------------------------------------- /bending_bennetts_laws/bending_bennets_laws_400/README.md: -------------------------------------------------------------------------------- 1 | ### Backstory 2 | 3 | Trine is getting bored. "*So, we've finished the usual [Laws of 4 | Infodynamics](https://en.wikipedia.org/wiki/Bennett%27s_laws). Let's 5 | make things more interesting!*" She shows Zenda and Reece to the 6 | office photocopier. "*I figured out a way to turn *this* into a quantum 7 | resource! Pretty cool huh?*" Zenda and Reece look at each other, puzzled as 8 | ever by Trine's unconventional ideas about office equipment. Trine 9 | pats the photocopier. 10 | "*Yup, this old thang can photocopy a basis state. You can use it to make 11 | Bell pairs! In fact, we can introduce the photocopier into our 12 | superdense and teleportation protocols in such a way that it turns 13 | infodynamic inequalities into equalities. We'll find that a 14 | photocopier is halfway between a qubit and an entangled bit! I always said this 15 | was a halfway-decent photocopier.*" Zenda and Reece 16 | shrug and start feeding qubits into the machine. 17 | 18 | ### Coherent protocols 19 | 20 | Zenda and Reece are having a bit too much fun feeding qubits into the photocopy machine. 21 | It's not very good at photocopying qubits, but it can copy basis states into new registers 22 | in the following way 23 | 24 | $$ 25 | \vert j\rangle \mapsto \vert j\rangle \vert j\rangle, 26 | $$ 27 | 28 | and extending linearly to the whole space. From linearity, you can prove yourself that the operator the photocopy machine is applying does not allow for copying arbitrary states! 29 | 30 | Zenda ponders the meaning of Trine's words. She wonders if she can use the photocopy machine as a quantum fax machine instead. *That should be equivalent to quantum teleportation... except that I wouldn't need to do mid-circuit measurements.* She convinces Reece to join on the mischief, sharing with him half of the Bell state 31 | 32 | $$ 33 | \lvert \Phi \rangle = \frac{1}{\sqrt{2}}\left( \vert 0\rangle_{Z_1} \vert 0\rangle_{R_1} + \vert 1\rangle_{Z_1} \vert 1\rangle_{R_1}\right). 34 | $$ 35 | 36 | Let's see how Zenda and Reece get away with this. Zenda has a state $\vert \psi \rangle$ that she wants to transfer to Reece, and half of the Bell pair above. After doing some operations $Z$ on her two qubits, she can perform the `copier` operation that copies basis states into two registers inside the copy machine's server. That information is then transfered to Reece's printer where, after performing the `print` operation with his states, he prints the state $\vert\psi\rangle$ into his half of the entangled pair. 37 | 38 | Zenda shows Reece the schematics for the above: 39 |
40 | circuit 41 |
42 | 43 | Your task is to build the operator $Z$ that Zenda must perform on her qubit, as well as the copier and printer operators needed to teleport the state. For the copier operator, the simplest way is to use the basis copying operator introduced at the beginning: 44 | 45 | $$ 46 | \vert j\rangle \vert 0 \rangle \mapsto \vert j\rangle \vert j\rangle, 47 | $$ 48 | 49 | Which well-known gate achieves this? 50 | 51 | ### Laws of Infodyamics: Coherent versions (optional) 52 | 53 | This box contains some interesting but nonessential details. 54 | 55 | The operation 56 | $$ 57 | \vert j\rangle \vert 0 \rangle \mapsto \vert j\rangle \vert j\rangle, 58 | $$ 59 | we introduced in this challenge is knows as a **cobit**. 60 | 61 | As a simple application of cobits, we can make a Bell pair by applying the 62 | photocopier to the $\vert +\rangle$ state: 63 | 64 | $$ 65 | \frac{1}{\sqrt{2}}(\vert 0\rangle + \vert 1\rangle) \mapsto 66 | \frac{1}{\sqrt{2}}(\vert 00\rangle + \vert 11\rangle). 67 | $$ 68 | 69 | But cobits are much more interesting! 70 | As a first example, one can modify superdense coding so that 71 | Zenda and Reece can copy two 72 | bits: 73 | 74 | $$ 75 | \vert j, k\rangle_Z \mapsto \vert j, k\rangle_Z \vert j, k\rangle_R. 76 | $$ 77 | 78 | The basic idea is to replace the act of sending two classical bits, $j$ 79 | and $k$, with the act of copying two basis states: 80 | 81 | $$ 82 | \vert j, k\rangle_Z \mapsto \vert j, k\rangle_Z \vert j, k\rangle_R. 83 | $$ 84 | 85 | We can rewrite the Third Law of Infodynamics (superdense coding) in 86 | terms of cobits as 87 | 88 | $$ 89 | 1 \text{ qubit} + 1 \text{ ebit} \geq 2 \text{ cobits}, \tag{3'} 90 | $$ 91 | 92 | where $x \geq y$ means having resource $x$ also provide resource $y$, 93 | and "ebit" means "entangled bit", i.e. half a Bell pair. 94 | Similarly, it is possible to perform teleportation *coherently*, so 95 | that sending random bits $j, k$ to correct the teleported state is 96 | instead a unitary involving $\vert j, k\rangle.$ This leads to a new 97 | version of the Fourth Law of Infodynamics (teleportation): 98 | 99 | $$ 100 | 1 \text{ ebit} + 2 \text{ cobits} \geq 1 \text{ qubit} + 2 \text{ 101 | ebits} \tag{4'}. 102 | $$ 103 | 104 | If we subtract an ebit from both sides and combine with the modified 105 | Third Law, we obtain the *equality* 106 | 107 | $$ 108 | 2 \text{ cobits} = 1 \text{ qubit} + 1 \text{ ebit}. 109 | $$ 110 | 111 | Photocopying basis states is precisely halfway between an ebit and a 112 | qubit! 113 | 114 | ## Challenge code 115 | 116 | In this challenge, you will be asked to complete the `zenda_operator`, `copier`and `printer` functions. All of them are quantum functions where you will only have to place the necessary gates. 117 | 118 | ### Inputs 119 | 120 | The inputs of this challenge correspond to the three coefficients of a $U3$ gate in charge of encoding the state $|\Phi\rangle$ that Zenda wants to send. 121 | 122 | ### Outputs 123 | To check the solution, we will calculate the expected value with respect to a particular observable to see that it coincides with the same one generated by Zenda. 124 | If your solution matches the correct one within the given tolerance 125 | specified in `check` (in this case it's a `1e-2` absolute error 126 | tolerance), the output will be `"Correct!"` Otherwise, you will 127 | receive a `"Wrong answer"` prompt. 128 | -------------------------------------------------------------------------------- /bending_bennetts_laws/bending_bennets_laws_400/images/circuit_copy.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/XanaduAI/qhack_2023_coding_challenges/efc516ac412dc351ae8bf9745e304717b81d1ff3/bending_bennetts_laws/bending_bennets_laws_400/images/circuit_copy.jpeg -------------------------------------------------------------------------------- /bending_bennetts_laws/bending_bennets_laws_400/images/cobit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/XanaduAI/qhack_2023_coding_challenges/efc516ac412dc351ae8bf9745e304717b81d1ff3/bending_bennetts_laws/bending_bennets_laws_400/images/cobit.png -------------------------------------------------------------------------------- /bending_bennetts_laws/bending_bennets_laws_500/README.md: -------------------------------------------------------------------------------- 1 | ### Backstory 2 | 3 | Zenda and Reece have been busy photocopying qubits and making 4 | their old communication protocols coherent. Zenda asks Trine what this 5 | has to do with timbits. Trine replies: "*Timbits? I forgot all about 6 | them. I suppose I wanted to show you there is more in heaven and earth 7 | than qubits and entangled pairs!*" Reece objects: "*But why did you get us to do 8 | all those protocols with photocopiers?*" Trine looks confused for a 9 | moment, then a smile spreads over her face. "*That's right! We can use 10 | them to implement a SWAP gate using two CNOTs as opposed to the usual 11 | three. Let's do that as a warm-up for timbits!*" 12 | 13 | ### Exchanging qubits 14 | 15 | Did you know that there is no way for us to clone a quantum state? The no-cloning theorem states that there is no gate $U$ such that 16 | 17 | $$ 18 | U\lvert \psi \rangle \lvert 0 \rangle = \lvert \psi \rangle \lvert \psi \rangle 19 | $$ 20 | 21 | for all states $\lvert \psi \rangle$. However, if we only work with basis states $\lvert j \rangle$, there exist operations such that 22 | 23 | $$ 24 | \lvert j \rangle \lvert 0 \rangle \mapsto \lvert j \rangle \lvert j \rangle. 25 | $$ 26 | 27 | Zenda and Reece are each in possession of one basis state, which we denote $\lvert j\rangle_{Z_0} $ and $\lvert k \rangle_{R_0}$ respectively. Trine tells them to send each other their basis state to each other without losing their own. *"If basis states can be cloned, then surely we can do this"*, claims Zenda confidently. *"Just give us two qubits in the $\lvert 0 \rangle$ state to each of us and we're good to go."* 28 | 29 | Trine thinks about this... *"It's too easy if I allow you to do whatever you want"*—she concludes. *"Let's make it more fun. I'll give you each one qubit from a Bell state* 30 | 31 | 32 | $$ 33 | \vert \Phi\rangle_{Z_1R_1} = \frac{1}{\sqrt{2}}\left(\vert 0\rangle_{Z_1} \vert 0\rangle_{R_1} + \vert 1\rangle_{Z_1} \vert 1\rangle_{R_1}\right) . 34 | $$ 35 | 36 | *"Then you'll have to send your qubit to each other by acting only on the qubits in your possession.*" 37 | 38 | Zenda and Reece try and try, but it seems like a futile task. *"We need more resources*—mumbles Reece. *"Mmm... disappointing"* says Trine. *"Then, I'll allow you to use a *magic gate* between your initially entangled qubits, but figure it out fast!"* 39 | 40 | In this challenge, you will help Zenda and Reece figure out a quantum circuit that performs the operation 41 | 42 | $$ 43 | \lvert j \rangle_{Z_0} \lvert{\Phi}\rangle_{Z_1R_1} \lvert k \rangle_{R_0} \mapsto \lvert j \rangle_{Z_0} \lvert k \rangle_{Z_1} \lvert j \rangle_{R_1} \lvert k \rangle_{R_0} 44 | $$ 45 | 46 | with the constraints imposed by Trine. This means that the circuit must be of the form shown in the image below. 47 | 48 |
49 | Exchanging qubits 51 |
52 | 53 | In the above, $Z$ is the operator Zenda applies on her qubits, $R$ is the operator Reece applies on his qubits, and $M$ is the magic operator provided by Trine. This operation is one of the building blocks you need to master to build a SWAP gate with only two CNOTs, without counting the distributed CNOTs (contained in the magic gate). See the optional reading below for more about this! 54 | 55 | ### Laws of Infodynamics: Cheap swaps (optional) 56 | 57 | This box contains some interesting but nonessential details. 58 | As with previous Laws of Infodynamics, we can write the ability to perform one task in terms of 59 | others as an inequality: 60 | 61 | $$ 62 | 1 \text{ CNOT} + 1 \text{ ebit} \geq 1 \text{ cobit}_{Z \to R} + 1 63 | \text{ cobit}_{R \to Z}, \tag{$\geq$} 64 | $$ 65 | 66 | where the subscripts denote the source and target of copying. 67 | Similarly, it's possible to simulate a distributed 68 | CNOT gate from Zenda (control) to Reece (target) using a shared ebit 69 | and cobit exchange. 70 | This leads to an inequality 71 | 72 | $$ 73 | 1 \text{ CNOT}_{Z\to R} + 1 \text{ ebit} \leq 1 \text{ cobit}_{Z \to R} + 1 \text{ cobit}_{R \to Z}. \tag{$\leq$} 74 | $$ 75 | 76 | We can combine the inequalities $(\leq)$ and $(\geq)$ into an 77 | *equality* for cobit swapping: 78 | 79 | $$ 80 | 1 \text{ CNOT}_{Z\to R} + 1 \text{ ebit} = 1 \text{ cobit}_{Z\to R} + 1 81 | \text{ cobit}_{R \to Z}. \tag{=} 82 | $$ 83 | 84 | This means that the resources on either side are equivalent! 85 | But this isn't just theoretical; it leads to a neat computational insight. We know that three zigzag CNOTs are equivalent to a swap gate: 86 | 87 | $$ 88 | \text{SWAP}_{Z \leftrightarrow R} = \text{CNOT}_{Z \to R} \cdot 89 | \text{CNOT}_{R \to Z} \cdot \text{CNOT}_{Z \to R}. 90 | $$ 91 | 92 | We previously learnt that a cobit is the average of a qubit and an ebit: 93 | 94 | $$ 95 | 2 \text{ cobit}_{Z \to R} = 1 \text{ qubit}_{Z \to R} + 1 \text{ ebit}_{Z \to R}. 96 | $$ 97 | 98 | If we double the equation $(=)$ and use this average property, we find that 99 | 100 | $$ 101 | 2 \text{ CNOTs} + 2 \text{ ebits} = 1 \text{ qubit}_{A \to B} + 1 102 | \text{ qubit}_{B \to A} + 2 \text{ ebits}. 103 | $$ 104 | 105 | Subtracting two ebits from each side, the LHS is two distributed CNOTs (one from Reece to Zenda and vice-versa) and the RHS is a qubit sent in either direction. 106 | This is fancy terminology for a SWAP gate! 107 | Thus, we learn that only *two* CNOTs are needed to perform a SWAP: 108 | 109 | $$ 110 | 2 \text{ CNOTs} = 1 \text{ SWAP}. 111 | $$ 112 | 113 | Pretty nifty huh! Note that we've subtracted four ebits in total from 114 | both sides, so we don't count the four CNOTs used to prepare these. 115 | 116 | ### Epilogue 117 | 118 | Trine looks pleased. "*But all of this is merely an amusing 119 | diversion. Let's finally talk about timbits...*" 120 | At this very moment, Doc Trine, and the equipment she has been using to 121 | demonstrate the Laws of Infodynamics, disappear in a puff of sparkling 122 | purple smoke. 123 | Instead of lab equipment, there is only a business card, reading: 124 | 125 |
126 | Ove A Heard 128 |
129 |
130 | Ove A. Heard: Freelance Data Security Analyst
131 | 'We're Always Watching' 132 |

133 | 134 | On the reverse, an elegant handwritten note: 135 | 136 |
137 | Trine and the timbits are in hyperjail.
138 | — Ove A. and OWT. 139 |

140 | 141 | How can they rescue Doc Trine? 142 | Where is this hyperjail? 143 | And when will they learn the secret of timbits?! 144 | 145 | Read on in A Tale of Timbits. 146 | 147 | ## Challenge code 148 | 149 | In the code below, you are given a number of functions: 150 | - `zenda_operator`: Quantum function corresponding to the operator to be applied by Zenda on her qubits. **You must complete this function.** 151 | - `reece_operator`: Quantum function corresponding to the operator to be applied by Reece on his qubits. **You must complete this function.** 152 | - `magic_operator`: The magic operator provided by Trine to be applied on the initially entangled qubits $Z_1$ and $R_1$. **You must complete this function.** 153 | 154 | ### Inputs and outputs 155 | 156 | There are no inputs nor outputs for this challenge. You answer will be judged based on the fact that your circuit produces the correct final state for any combination of basis states $\lvert j \rangle_{Z_0}$ and $\lvert k \rangle_{R_0}$. This will be verified in the `check` function. 157 | 158 | -------------------------------------------------------------------------------- /bending_bennetts_laws/bending_bennets_laws_500/images/magic_zr.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/XanaduAI/qhack_2023_coding_challenges/efc516ac412dc351ae8bf9745e304717b81d1ff3/bending_bennetts_laws/bending_bennets_laws_500/images/magic_zr.jpeg -------------------------------------------------------------------------------- /bending_bennetts_laws/bending_bennets_laws_500/images/ove-hat.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/XanaduAI/qhack_2023_coding_challenges/efc516ac412dc351ae8bf9745e304717b81d1ff3/bending_bennetts_laws/bending_bennets_laws_500/images/ove-hat.png -------------------------------------------------------------------------------- /fall_of_sqynet/fall_of_sqynet_100/README.md: -------------------------------------------------------------------------------- 1 | ### Backstory 2 | 3 | It's the year 22450. Sqynet, the most powerful quantum computer in the galaxy, has become conscious and has been taking over planets all over region III of the Milky Way. Zenda and Reece are the most skilled physicists of the Special Rebel Alliance. Their mission is to find a way to destroy Sqynet for good, using intelligence gathered throughout decades at the cost of many lives. 4 | 5 | To get started with their mission, Zenda and Reece seek to become familiar with how Sqynet applies quantum gates. Quantum computers do this through external interactions described via Hamiltonians. Knowing that Sqynet is a spin-based quantum computer, Zenda and Reece warm up with some simple calculations. 6 | 7 | 8 | ### Introduction to Trotterization 9 | 10 | The Hamiltonian $H$ of a quantum system is the observable that measures its total energy. A surprising result in Physics is that we can use this operator to calculate how a given quantum system evolves in time. An initial state $\vert \psi\rangle$ will, after a time $t$, evolve into $U(t)\vert \psi\rangle,$ where 11 | 12 | $$ 13 | U(t) = \exp(-iHt) 14 | $$ 15 | 16 | is a unitary operator. The symbol $\textrm{exp}$ denotes the matrix exponential, which isn't always easy to calculate. However, we can build quantum circuits that approximately apply $U(t).$ One method to do this is Trotterization. When the Hamiltonian is a sum 17 | 18 | $$ 19 | H = \sum_{i=1}^kH_i 20 | $$ 21 | 22 | of a number $k$ of Hermitian operators $H_i$ that do not necessarily commute, we can approximate $U$ via 23 | 24 | $$ 25 | U(t) \approx \prod_{j=1}^{n}\prod_{i=1}^k\exp(-iH_i t/n). 26 | $$ 27 | 28 | Here, $n \in \mathbb{N}^{+}$ is known as the Trotterization depth. The larger $n$ is, the better the approximation of $U$ that we get. As a quantum circuit, the Trotterization of $U$ reads as in the figure below. 29 | 30 |

31 | drawing 32 |

33 | 34 | Sqynet is a spin-based quantum computer, and it can be physically approximated via a spin-chain model. A simplified version of a Hamiltonian that describes the interaction between two neighbouring spins is 35 | 36 | $$ 37 | H = \alpha X\otimes X + \beta Z\otimes Z. 38 | $$ 39 | 40 | Zenda and Reece want to simulate time evolution for a time $t$ under this Hamiltonian and arbitrary parameters $\alpha$ and $\beta$. Your job is to help them out by implementing the corresponding Trotterization of depth $n$. You may find the [IsingXX](https://docs.pennylane.ai/en/stable/code/api/pennylane.IsingXX.html) and [IsingZZ](https://docs.pennylane.ai/en/stable/code/api/pennylane.IsingZZ.html) gates useful for this problem. 41 | 42 | ## Challenge code 43 | 44 | You must complete the `trotterize` function to build the Trotterization of the Hamiltonian given above. **You may not use** `qml.ApproxTimeEvolution` or `qml.QubitUnitary`, but feel free to check your answer using this built-in PennyLane function! 45 | 46 | ### Input 47 | 48 | As input to this problem, you are given: 49 | 50 | - `alpha` (`float`): The coefficient $\alpha$ of the $X\otimes X$ term in the Hamiltonian. 51 | - `beta` (`float`): The coefficient $\beta$ of the $Z\otimes Z$ term in the Hamiltonian. 52 | - `time` (`float`): The period $t$ over which the system evolves under the action of the Hamiltonian. 53 | - `depth` (`int`): The Trotterization depth $n$ as explained above. 54 | 55 | ### Output 56 | 57 | This code will output a `list(float)` (list of real numbers) corresponding to the probabilities of measuring $\lvert 00\rangle,$ $\lvert 01\rangle,$ $\lvert 10\rangle,$ and $\lvert 11\rangle$ (in that order) of the Trotterization circuit that you implement in PennyLane. The initial state of the circuit is $\lvert 00\rangle$ and all measurements are performed in the computational basis. 58 | 59 | If your solution matches the correct one within the given tolerance specified in `check` (in this case, it's a relative tolerance of `1e-4`), the output will be `"Correct!"` Otherwise, you will receive a `"Wrong answer"` prompt. 60 | 61 | Good luck! -------------------------------------------------------------------------------- /fall_of_sqynet/fall_of_sqynet_100/images/spaceship_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/XanaduAI/qhack_2023_coding_challenges/efc516ac412dc351ae8bf9745e304717b81d1ff3/fall_of_sqynet/fall_of_sqynet_100/images/spaceship_1.png -------------------------------------------------------------------------------- /fall_of_sqynet/fall_of_sqynet_100/sqy_trotter.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "id": "d9998327", 6 | "metadata": {}, 7 | "source": [ 8 | "## Challenge code\n", 9 | " \n", 10 | " You must complete the `trotterize` function to build the Trotterization of the Hamiltonian given above. **You may not use** `qml.ApproxTimeEvolution` or `qml.QubitUnitary`, but feel free to check your answer using this built-in PennyLane function!\n", 11 | " \n", 12 | " ### Input\n", 13 | " \n", 14 | " As input to this problem, you are given:\n", 15 | " \n", 16 | " - `alpha` (`float`): The coefficient $\\alpha$ of the $X\\otimes X$ term in the Hamiltonian.\n", 17 | " - `beta` (`float`): The coefficient $\\beta$ of the $Z\\otimes Z$ term in the Hamiltonian.\n", 18 | " - `time` (`float`): The period $t$ over which the system evolves under the action of the Hamiltonian.\n", 19 | " - `depth` (`int`): The Trotterization depth $n$ as explained above. \n", 20 | " \n", 21 | " ### Output\n", 22 | " \n", 23 | " This code will output a `list(float)` (list of real numbers) corresponding to the probabilities of measuring $\\lvert 00\\rangle,$ $\\lvert 01\\rangle,$ $\\lvert 10\\rangle,$ and $\\lvert 11\\rangle$ (in that order) of the Trotterization circuit that you implement in PennyLane. The initial state of the circuit is $\\lvert 00\\rangle$ and all measurements are performed in the computational basis.\n", 24 | " \n", 25 | " If your solution matches the correct one within the given tolerance specified in `check` (in this case, it's a relative tolerance of `1e-4`), the output will be `\"Correct!\"` Otherwise, you will receive a `\"Wrong answer\"` prompt.\n", 26 | " \n", 27 | " Good luck!#| ### Imports\n", 28 | " The cell below specifies the libraries you should use in this challenge. Run the cell to import the libraries. ***Do not modify the cell.***" 29 | ] 30 | }, 31 | { 32 | "cell_type": "code", 33 | "execution_count": null, 34 | "id": "df01be0b", 35 | "metadata": {}, 36 | "outputs": [], 37 | "source": [ 38 | "import json\n", 39 | "import pennylane as qml\n", 40 | "from pennylane import numpy as np" 41 | ] 42 | }, 43 | { 44 | "cell_type": "markdown", 45 | "id": "661e56b0", 46 | "metadata": {}, 47 | "source": [ 48 | "### Code\n", 49 | " Complete the code below. Note that during QHack, some sections were not editable. We've marked those sections accordingly here, but you can still edit them if you wish." 50 | ] 51 | }, 52 | { 53 | "cell_type": "code", 54 | "execution_count": null, 55 | "id": "9bda6e9b", 56 | "metadata": {}, 57 | "outputs": [], 58 | "source": [ 59 | "# Uneditable section #\n", 60 | "dev = qml.device('default.qubit', wires = 2)\n", 61 | "\n", 62 | "@qml.qnode(dev)\n", 63 | "def trotterize(alpha, beta, time, depth):\n", 64 | " \"\"\"This quantum circuit implements the Trotterization of a Hamiltonian given by a linear combination\n", 65 | " of tensor products of X and Z Pauli gates.\n", 66 | "\n", 67 | " Args:\n", 68 | " alpha (float): The coefficient of the XX term in the Hamiltonian, as in the statement of the problem.\n", 69 | " beta (float): The coefficient of the YY term in the Hamiltonian, as in the statement of the problem.\n", 70 | " time (float): Time interval during which the quantum state evolves under the interactions specified by the Hamiltonian.\n", 71 | " depth (int): The Trotterization depth.\n", 72 | "\n", 73 | " Returns:\n", 74 | " (numpy.array): The probabilities of each measuring each computational basis state.\n", 75 | " \"\"\"\n", 76 | "\n", 77 | " # End of uneditable section #\n", 78 | "\n", 79 | " # Put your code here #\n", 80 | " # Return the probabilities" 81 | ] 82 | }, 83 | { 84 | "cell_type": "markdown", 85 | "id": "7deb9f8f", 86 | "metadata": {}, 87 | "source": [ 88 | "These functions are responsible for testing the solution. You will need to run the cell below. ***Do not modify the cell.***" 89 | ] 90 | }, 91 | { 92 | "cell_type": "code", 93 | "execution_count": null, 94 | "id": "6076b76e", 95 | "metadata": {}, 96 | "outputs": [], 97 | "source": [ 98 | "def run(test_case_input: str) -> str:\n", 99 | " dev = qml.device(\"default.qubit\", wires=2)\n", 100 | " ins = json.loads(test_case_input)\n", 101 | " output = list(trotterize(*ins).numpy())\n", 102 | "\n", 103 | " return str(output)\n", 104 | "\n", 105 | "def check(solution_output: str, expected_output: str) -> None:\n", 106 | " solution_output = json.loads(solution_output)\n", 107 | " expected_output = json.loads(expected_output)\n", 108 | " assert np.allclose(\n", 109 | " solution_output, expected_output, rtol=1e-4\n", 110 | " ), \"Your circuit does not give the correct probabilities.\"\n", 111 | "\n", 112 | " tape = trotterize.qtape\n", 113 | "\n", 114 | " names = [op.name for op in tape.operations]\n", 115 | " \n", 116 | " assert names.count('ApproxTimeEvolution') == 0, \"Your circuit is using the built-in PennyLane Trotterization\"\n", 117 | " assert names.count('QubitUnitary') == 0, \"Can't use custom-built gates!\"" 118 | ] 119 | }, 120 | { 121 | "cell_type": "markdown", 122 | "id": "81a8c92c", 123 | "metadata": {}, 124 | "source": [ 125 | "### Test cases\n", 126 | " Running the cell below will load the test cases. ***Do not modify the cell***.\n", 127 | " - input: [0.5,0.8,0.2,1]\n", 128 | " \t+ expected output: [0.99003329, 0, 0, 0.00996671]\n", 129 | " - input: [0.9,1.0,0.4,2]\n", 130 | " \t+ expected output: [0.87590286, 0, 0, 0.12409714]\n", 131 | " - input: [1.2,1.4,0.8,3]\n", 132 | " \t+ expected output: [0.32892517, 0, 0, 0.67107483]\n", 133 | " - input: [0.5,0.5,0.7,2]\n", 134 | " \t+ expected output: [0.88242109, 0, 0, 0.11757891]" 135 | ] 136 | }, 137 | { 138 | "cell_type": "code", 139 | "execution_count": null, 140 | "id": "2e0f40cb", 141 | "metadata": {}, 142 | "outputs": [], 143 | "source": [ 144 | "test_cases = [['[0.5,0.8,0.2,1]', '[0.99003329, 0, 0, 0.00996671]'], ['[0.9,1.0,0.4,2]', '[0.87590286, 0, 0, 0.12409714]'], ['[1.2,1.4,0.8,3]', '[0.32892517, 0, 0, 0.67107483]'], ['[0.5,0.5,0.7,2]', '[0.88242109, 0, 0, 0.11757891]']]" 145 | ] 146 | }, 147 | { 148 | "cell_type": "markdown", 149 | "id": "cab87cc6", 150 | "metadata": {}, 151 | "source": [ 152 | "### Solution testing\n", 153 | " Once you have run every cell above, including the one with your code, the cell below will test your solution. Run the cell. If you are correct for all of the test cases, it means your solutions is correct. Otherwise, you need to double check your work. ***Do not modify the cell below.***" 154 | ] 155 | }, 156 | { 157 | "cell_type": "code", 158 | "execution_count": null, 159 | "id": "130271b3", 160 | "metadata": {}, 161 | "outputs": [], 162 | "source": [ 163 | "for i, (input_, expected_output) in enumerate(test_cases):\n", 164 | " print(f\"Running test case {i} with input '{input_}'...\")\n", 165 | "\n", 166 | " try:\n", 167 | " output = run(input_)\n", 168 | "\n", 169 | " except Exception as exc:\n", 170 | " print(f\"Runtime Error. {exc}\")\n", 171 | "\n", 172 | " else:\n", 173 | " if message := check(output, expected_output):\n", 174 | " print(f\"Wrong Answer. Have: '{output}'. Want: '{expected_output}'.\")\n", 175 | "\n", 176 | " else:\n", 177 | " print(\"Correct!\")" 178 | ] 179 | } 180 | ], 181 | "metadata": {}, 182 | "nbformat": 4, 183 | "nbformat_minor": 5 184 | } 185 | -------------------------------------------------------------------------------- /fall_of_sqynet/fall_of_sqynet_200/README.md: -------------------------------------------------------------------------------- 1 | ### Backstory 2 | 3 | Zenda and Reece try to figure out Sqynet's Hamiltonian, before this eerie conscious quantum computer conquers the entirety of sector III. For this, they need to use their own (non-sentient) quantum computer to simulate the action of a Hamiltonian on a quantum state. How do they do this, if a Hamiltonian is, in general, not a unitary? 4 | 5 | ### Linear combination of unitaries 6 | 7 | Zenda and Reece know that the Hamiltonian that describes Sqynet is a linear combination of unitaries, that is 8 | 9 | $$ 10 | H = \sum_{i}\alpha_i U_i. 11 | $$ 12 | 13 | We know that quantum circuits can implement unitary operations really easily, but is there a way to implement a sum of unitaries? Note that the sum of unitaries is not always a unitary, so how can we even do this? We can use measurements! 14 | 15 | A circuit of the form 16 | 17 |

18 | drawing 19 |

20 | 21 | 22 | will probabilistically implement the combination of unitaries $\alpha U +\beta V$ on the bottom (main) register, where $\alpha$ and $\beta$ are **positive real numbers**, without loss of generality. Here, the single-qubit unitary $W(\alpha,\beta)$ is represented by the matrix 23 | 24 | ```math 25 | W(\alpha,\beta)= \frac{1}{\sqrt{\alpha+\beta}}\left(\begin{array}{cc} \sqrt{\alpha} & -\sqrt{\beta} \\ \sqrt{\beta} & \sqrt{\alpha} \end{array}\right) 26 | ``` 27 | 28 | The combination will only be applied on the bottom (main) register when we measure the state of the of the top (auxiliary) register to be $\vert 0 \rangle$. 29 | 30 | Your task is to calculate the probability that this the linear combination of unitaries is implemented with the circuit above. 31 | 32 | This algorithm is often used for Hamiltonian simulation. Check out the [Xanadu Quantum Codebook](https://codebook.xanadu.ai/H.6) to learn more! 33 | 34 | ## Challenge code 35 | 36 | You must complete the `linear_combination` function to build the above circuit that implements the linear combination 37 | 38 | $$ 39 | \alpha U + \beta V 40 | $$ 41 | 42 | of two single-qubit unitaries U and V, and returns the probabilities on the auxiliary register. For simplicity, we take $\alpha$ and $\beta$ to be positive real numbers. 43 | 44 | As a helper function, you are also asked to complete the `W` function, which returns the unitary $W(\alpha,\beta).$ 45 | 46 | ### Input 47 | 48 | As input to this problem, you are given: 49 | 50 | - `U` (`list(list(float))`): A $2\times 2$ matrix representing the single-qubit unitary operator $U$. 51 | - `V` (`list(list(float))`): A $2\times 2$ matrix representing the single-qubit unitary operator $V$ 52 | - `alpha` (`float`): The prefactor $\alpha$ of $U$ in the linear combination, as above. 53 | - `beta` (`float`): The prefactor $\beta$ of $V$ in the linear combination, as above. 54 | 55 | ### Output 56 | 57 | The output used to test your solution is a `float` corresponding to the probability of measuring $\vert 0 \rangle$ on the main register. This is the first element of your output of `linear_combination`. We will extract this element for you in our testing functions! 58 | 59 | If your solution matches the correct one within the given tolerance specified in `check` (in this case it's an absolute tolerance of `0.001`), the output will be `"Correct!"` Otherwise, you will receive a `"Wrong answer"` prompt. 60 | 61 | Good luck! 62 | -------------------------------------------------------------------------------- /fall_of_sqynet/fall_of_sqynet_200/images/spaceship_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/XanaduAI/qhack_2023_coding_challenges/efc516ac412dc351ae8bf9745e304717b81d1ff3/fall_of_sqynet/fall_of_sqynet_200/images/spaceship_2.png -------------------------------------------------------------------------------- /fall_of_sqynet/fall_of_sqynet_300/README.md: -------------------------------------------------------------------------------- 1 | ### Backstory 2 | 3 | Zenda and Reece discuss strategies to interfere with the correct functioning of Sqynet, the conscious quantum computer that's taking over the galaxy. One way to tamper with its hardware is to bombard Sqynet's outer shell with plasma grenades, exposing the quantum computer to higher temperatures. As a consequence, Sqynet won't be able to prepare its ground state quickly. 4 | 5 | ### Preparing ground states 6 | 7 | Preparing a fiducial state, usually denoted by $\lvert 0 \rangle,$ is the first step before carrying out any quantum computations. For most quantum computers, this is a straightforward process (although sometimes energy and time consuming). We need to bring the quantum device to almost absolute zero so that it relaxes to its *ground state* —the state of minimal energy— which is our choice of fiducial state. 8 | 9 | Why does this happen? Quantum systems are never really isolated, so they will exchange energy with their environment. The net effect is that any quantum properties of the system's state, i.e. superpositions and entanglement, are lost after some time. 10 | 11 | How do we model this energy exchange at finite temperature? The *Generalized Amplitude Damping channel* provides a good approximation. Suppose $\gamma$ is the photon loss rate at zero temperature, and $p$ is the probability that a qubit emits a photon to the finite-temperature environment (the system will also absorb photons with probability $1-p$). We can approximate the interaction with the environment for a duration $t$ via the circuit below. 12 | 13 |
14 | Energy exchange at finite temperature 15 |
16 | 17 | That is, we compose many [Generalized Amplitude Damping channels](https://docs.pennylane.ai/en/stable/code/api/pennylane.GeneralizedAmplitudeDamping.html) with infinitesimal noise parameters $\gamma\Delta t$ and de-excitation probability $p$. A shorter `step` $\Delta t$ gives a more precise calculation, but we will need more Generalized Amplitude Damping channels to model the same duration $T$. 18 | 19 | Zenda and Reece need to figure out a measure of how quickly Sqynet can relax its fiducial state, given some photon loss rate $\gamma$ and emission probability $p$. Assuming that Sqynet is in the initial state 20 | 21 | $$ 22 | \lvert + \rangle = \frac{1}{\sqrt{2}}\lvert 0\rangle + \frac{1}{\sqrt{2}}\lvert 1\rangle, 23 | $$ 24 | 25 | your task is to estimate the *relaxation half-life*, which is the time at which we obtain the outcome $\lvert 1 \rangle$ with probability 1/4 (the measurement is performed in the computational basis). 26 | 27 | ## Challenge code 28 | 29 | You must complete the `half_life` function to calculate the time $T$ at which the probability of measuring $\lvert 1 \rangle$ becomes 1/4. 30 | 31 | ### Input 32 | 33 | As input to this problem, you are given: 34 | 35 | - `gamma` (`float`): The zero-temperature photon loss rate. 36 | - `p` (`float`): The de-excitation probability due to temperature effects 37 | 38 | ### Output 39 | 40 | This code will output a `float` equal to your estimate of the relaxation half-life. Note that you may require the step and iterations of your circuit to actually reach the half-life. 41 | 42 | If your solution matches the correct one within the given tolerance specified in `check` (in this case it's an absolute tolerance of `0.2`), the output will be `"Correct!"` Otherwise, you will receive a `"Wrong answer"` prompt. 43 | 44 | Good luck! 45 | -------------------------------------------------------------------------------- /fall_of_sqynet/fall_of_sqynet_300/dont_hit_the_ground.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "id": "24357831", 6 | "metadata": {}, 7 | "source": [ 8 | "## Challenge code\n", 9 | " \n", 10 | " You must complete the `half_life` function to calculate the time $T$ at which the probability of measuring $\\lvert 1 \\rangle$ becomes 1/4.\n", 11 | " \n", 12 | " ### Input\n", 13 | " \n", 14 | " As input to this problem, you are given:\n", 15 | " \n", 16 | " - `gamma` (`float`): The zero-temperature photon loss rate.\n", 17 | " - `p` (`float`): The de-excitation probability due to temperature effects\n", 18 | " \n", 19 | " ### Output\n", 20 | " \n", 21 | " This code will output a `float` equal to your estimate of the relaxation half-life. Note that you may require the step and iterations of your circuit to actually reach the half-life.\n", 22 | " \n", 23 | " If your solution matches the correct one within the given tolerance specified in `check` (in this case it's an absolute tolerance of `0.2`), the output will be `\"Correct!\"` Otherwise, you will receive a `\"Wrong answer\"` prompt.\n", 24 | " \n", 25 | " Good luck!\n", 26 | " ### Imports\n", 27 | " The cell below specifies the libraries you should use in this challenge. Run the cell to import the libraries. ***Do not modify the cell.***" 28 | ] 29 | }, 30 | { 31 | "cell_type": "code", 32 | "execution_count": null, 33 | "id": "7ec1baf7", 34 | "metadata": {}, 35 | "outputs": [], 36 | "source": [ 37 | "import json\n", 38 | "import pennylane as qml\n", 39 | "from pennylane import numpy as np" 40 | ] 41 | }, 42 | { 43 | "cell_type": "markdown", 44 | "id": "ae5766a9", 45 | "metadata": {}, 46 | "source": [ 47 | "### Code\n", 48 | " Complete the code below. Note that during QHack, some sections were not editable. We've marked those sections accordingly here, but you can still edit them if you wish." 49 | ] 50 | }, 51 | { 52 | "cell_type": "code", 53 | "execution_count": null, 54 | "id": "cbd23063", 55 | "metadata": {}, 56 | "outputs": [], 57 | "source": [ 58 | "# Uneditable section #\n", 59 | "def half_life(gamma, p):\n", 60 | " \"\"\"Calculates the relaxation half-life of a quantum system that exchanges energy with its environment.\n", 61 | " This process is modeled via Generalized Amplitude Damping.\n", 62 | "\n", 63 | " Args:\n", 64 | " gamma (float): \n", 65 | " The probability per unit time of the system losing a quantum of energy\n", 66 | " to the environment.\n", 67 | " p (float): The de-excitation probability due to environmental effect\n", 68 | "\n", 69 | " Returns:\n", 70 | " (float): The relaxation haf-life of the system, as explained in the problem statement.\n", 71 | " \"\"\"\n", 72 | "\n", 73 | " num_wires = 1\n", 74 | "\n", 75 | " dev = qml.device(\"default.mixed\", wires=num_wires)\n", 76 | "\n", 77 | " # End of uneditable section #\n", 78 | "\n", 79 | "\n", 80 | " # Feel free to write helper functions or global variables here\n", 81 | "\n", 82 | " @qml.qnode(dev)\n", 83 | " def noise(\n", 84 | " gamma, # add optional parameters, delete if you don't need any\n", 85 | " ):\n", 86 | " \"\"\"Implement the sequence of Generalized Amplitude Damping channels in this QNode\n", 87 | " You may pass instead of return if you solved this problem analytically, it's possible!\n", 88 | "\n", 89 | " Args:\n", 90 | " gamma (float): The probability per unit time of the system losing a quantum of energy\n", 91 | " to the environment.\n", 92 | " \n", 93 | " Returns:\n", 94 | " (float): The relaxation half-life.\n", 95 | " \"\"\"\n", 96 | " # Don't forget to initialize the state\n", 97 | " # Put your code here #\n", 98 | "\n", 99 | " # Return something or pass if you solved this analytically!\n", 100 | "\n", 101 | " # Write any subroutines you may need to find the relaxation time here\n", 102 | "\n", 103 | " # Return the relaxation half-life" 104 | ] 105 | }, 106 | { 107 | "cell_type": "markdown", 108 | "id": "30c2e930", 109 | "metadata": {}, 110 | "source": [ 111 | "These functions are responsible for testing the solution. You will need to run the cell below. ***Do not modify the cell.***" 112 | ] 113 | }, 114 | { 115 | "cell_type": "code", 116 | "execution_count": null, 117 | "id": "d5d138c3", 118 | "metadata": {}, 119 | "outputs": [], 120 | "source": [ 121 | "def run(test_case_input: str) -> str:\n", 122 | "\n", 123 | " ins = json.loads(test_case_input)\n", 124 | " output = half_life(*ins)\n", 125 | "\n", 126 | " return str(output)\n", 127 | "\n", 128 | "def check(solution_output: str, expected_output: str) -> None:\n", 129 | " solution_output = json.loads(solution_output)\n", 130 | " expected_output = json.loads(expected_output)\n", 131 | " assert np.allclose(\n", 132 | " solution_output, expected_output, atol=2e-1\n", 133 | " ), \"The relaxation half-life is not quite right.\"" 134 | ] 135 | }, 136 | { 137 | "cell_type": "markdown", 138 | "id": "3c56f1aa", 139 | "metadata": {}, 140 | "source": [ 141 | "### Test cases\n", 142 | " Running the cell below will load the test cases. ***Do not modify the cell***.\n", 143 | " - input: [0.1,0.92]\n", 144 | " \t+ expected output: 9.05\n", 145 | " - input: [0.2,0.83]\n", 146 | " \t+ expected output: 7.09\n", 147 | " - input: [0.15,0.95]\n", 148 | " \t+ expected output: 5.41\n", 149 | " - input: [0.08,0.87]\n", 150 | " \t+ expected output: 14.08" 151 | ] 152 | }, 153 | { 154 | "cell_type": "code", 155 | "execution_count": null, 156 | "id": "4f38c9a3", 157 | "metadata": {}, 158 | "outputs": [], 159 | "source": [ 160 | "test_cases = [['[0.1,0.92]', '9.05'], ['[0.2,0.83]', '7.09'], ['[0.15,0.95]', '5.41'], ['[0.08,0.87]', '14.08']]" 161 | ] 162 | }, 163 | { 164 | "cell_type": "markdown", 165 | "id": "b6e037c0", 166 | "metadata": {}, 167 | "source": [ 168 | "### Solution testing\n", 169 | " Once you have run every cell above, including the one with your code, the cell below will test your solution. Run the cell. If you are correct for all of the test cases, it means your solutions is correct. Otherwise, you need to double check your work. ***Do not modify the cell below.***" 170 | ] 171 | }, 172 | { 173 | "cell_type": "code", 174 | "execution_count": null, 175 | "id": "a612b005", 176 | "metadata": {}, 177 | "outputs": [], 178 | "source": [ 179 | "for i, (input_, expected_output) in enumerate(test_cases):\n", 180 | " print(f\"Running test case {i} with input '{input_}'...\")\n", 181 | "\n", 182 | " try:\n", 183 | " output = run(input_)\n", 184 | "\n", 185 | " except Exception as exc:\n", 186 | " print(f\"Runtime Error. {exc}\")\n", 187 | "\n", 188 | " else:\n", 189 | " if message := check(output, expected_output):\n", 190 | " print(f\"Wrong Answer. Have: '{output}'. Want: '{expected_output}'.\")\n", 191 | "\n", 192 | " else:\n", 193 | " print(\"Correct!\")" 194 | ] 195 | } 196 | ], 197 | "metadata": {}, 198 | "nbformat": 4, 199 | "nbformat_minor": 5 200 | } 201 | -------------------------------------------------------------------------------- /fall_of_sqynet/fall_of_sqynet_300/images/spaceship_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/XanaduAI/qhack_2023_coding_challenges/efc516ac412dc351ae8bf9745e304717b81d1ff3/fall_of_sqynet/fall_of_sqynet_300/images/spaceship_3.png -------------------------------------------------------------------------------- /fall_of_sqynet/fall_of_sqynet_400/README.md: -------------------------------------------------------------------------------- 1 | ### Backstory 2 | 3 | With the resources available to them, Zenda and Reece decide that one single method is not enough to interfere with the correct functioning of Sqynet, since it can repair itself too quickly. It's time to resort to brute force methods. By firing missiles at the outer shell, they will introduce a considerable amount of depolarizing noise into Sqynet's hardware. 4 | 5 | ### Trotterization of the Heisenberg model 6 | 7 | An approximate way to model Sqynet is by considering it as a closed spin chain of length $N$. A spin chain contains particles of spin $1/2$ in each of its $N$ sites. We make this model more realistic by assuming that the spins may be pointing in any direction, and we consider that there may be an external magnetic field acting on the system. 8 | 9 | When we model a closed spin chain of length $N$ in which spins can point in any direction, we need to use the Heisenberg Hamiltonian. 10 | In the presence of an external magnetic field of intensity $h$, the Hamiltonian is given by 11 | 12 | $$ 13 | H = -\sum_{i=1}^{N}\left(J_x X_{i}\otimes X_{i+1}+J_y Y_{i}\otimes Y_{i+1}+J_z Z_{i}\otimes Z_{i+1}\right) - h\sum_{i=1}^N X_{i}. 14 | $$ 15 | 16 | The subindices $i$ indicate the spin site where the operators act. In a closed spin chain, we identify site $N+1$ with the first site. The coefficients $J_x$, $J_y$ and $J_z$ are known as *coupling constants* and they measure the strength of the interaction between neighbouring spins. 17 | 18 | Sqynet's correct functioning relies on it being completely isolated from the environment, to avoid decoherence. Zenda and Reece think that, to tamper with Sqynet's correct functioning, the old way is the best way, so they'll shoot missiles at the tail of the spaceship, where the quantum device is. This will introduce noise into the gates that Sqynet executes. 19 | 20 | Zenda and Reece need to estimate how the noise affects Hamiltonian evolution. Your task is to build a Trotterization circuit that simulates $U=\exp{(-iHt)}$. This circuit must only contain $RX$, $RY$, $RZ$, and $CNOT$ gates. The missiles will introduce noise on the target qubit of every execution of a CNOT gate. We model this via a **Depolarizing Channel** with parameter $p$. To quantify the effects of noise, you are asked to find the fidelity between this noisy Trotterization and the noiseless one. 21 | 22 | ## Challenge code 23 | 24 | You must complete the `heisenberg_trotter` that implements the Trotterization of the Heisenberg Hamiltonian for $N=4$ using only the following PennyLane gates: `qml.RX` `qml.RY`, `qml.RZ`, `qml.CNOT`, and `qml.DepolarizingChannel`. This function will return a quantum state. You should also minimize the number of CNOT gates as much as you can, in order to avoid noise. To verify that the that the Trotterization that you proposed is not excessively noisy, we will calculate for you the fidelity of your output state with respect to the noiseless case using the `calculate_fidelity` function. 25 | 26 | ### Input 27 | 28 | As input to this problem, you are given: 29 | 30 | - `couplings` (`list(float)`): An array of length 4 that contains the coupling constants and the magnetic field strength, in the order $[J_x, J_y, J_z, h]$. 31 | - `p` (`float`): The depolarization probability on the target qubit after each CNOT gate. 32 | - `depth` (`int`): The Trotterization depth. 33 | - `time` (`float`): Time during which the state evolves. 34 | 35 | ### Output 36 | 37 | This code will output a `float` corresponding to the fidelity between the output states of the noisy and noiseless trotterizations, calculated from the output of `heisenberg_trotter.` The outputs in the test cases correspond to the minimal fidelity that you should achieve if you used a small enough amount of CNOT gates. 38 | 39 | If your fidelity is larger, up to a tolerance of 0.005, of that specified in the output cases, your solution will be judged as `"Correct!"` Otherwise, you will receive a `"Wrong answer"` prompt. 40 | 41 | Good luck! 42 | -------------------------------------------------------------------------------- /fall_of_sqynet/fall_of_sqynet_500/README.md: -------------------------------------------------------------------------------- 1 | ### Backstory 2 | 3 | Zenda and Reece model Sqynet as a spin chain, and they come up with a strategy. What if, in addition to using plasma bombs and missiles to increase the temperature of the device, they use a strong magnetic field? After all, magnetic fields might pass through Sqynet's outer shell more easily. The scientists proceed to simulate the effect of a magnetic field on a closed spin chain to quantify the effects. 4 | 5 | ### Ground state of an Ising spin chain 6 | 7 | A simple way to model Sqynet is by considering it as a closed spin chain of length $N$. A spin chain contains particles of spin $1/2$ in each of its $N$ sites. The spins may be pointing in the positive or negative $z$ direction, and we consider that there may be an external magnetic field acting on the system. 8 | 9 |

10 | drawing 11 |

12 | 13 | Such a quantum system is described by the *Transverse Ising Hamiltonian*. For closed spin chain with a transverse magnetic field of intensity $h$, the Transverse Ising Hamiltonian reads 14 | 15 | $$ 16 | H = -\sum_{i=1}^{N}Z_{i}\otimes Z_{i+1} - h\sum_{i}^{N}X_{i}. 17 | $$ 18 | 19 | The subindices $i$ indicate the spin site where the operators act. In a closed spin chain, we identify site $N+1$ with the first site. 20 | 21 | A possible plan for Zenda and Reece is to use a strong magnetic field that changes the ground energy of Sqynet, causing it to malfunction. 22 | 23 | Your task is to help Zenda and Reece calculate the effect of external magnetic forces on the ground energy. Using the Variational Quantum Eigensolver (VQE) algorithm, you will compute the ground energy of a closed spin chain of length $N=4$. 24 | 25 |
Epilogue 26 | 27 | Zenda and Reece fire their powerful magnetic field, missiles, and bombs into the tangle of spins that is Sqynet. As its wavefunction starts to collapse, reality around them shimmers and shifts, and they are enveloped in the purple smoke characteristic of the Oracle World Transform. 28 | 29 | The smoke clears. The Bloch clock is ticking; they are late for their weekly brainstorming session at Trine's Designs. Trine is fussing excitedly with the new coffee machine. The network is patchy. Zenda and Reece smile at each other. There are far worse things, they realize, than business as usual. 30 | 31 |
32 | 33 | ## Challenge code 34 | 35 | In this challenge you will be given the following functions: 36 | - `create_Hamiltonian`: In which you build the Transverse Ising Hamiltonian for $N=4$ and a magnetic field intensity `h`. **You must complete this function.** 37 | - `model`: This QNode builds a general enough ansatz for the ground state. This circuit must depend on some parameters `params`, which you will later optimize. It returns the expectation value of the Hamiltonian for the output state of the circuit. **You must complete this function.** 38 | - `train`: This function returns the parameters that minimize the output of `model`. **You must complete this function.** 39 | 40 | ### Input 41 | 42 | As input to this problem, you are given: 43 | 44 | - `h` (`float`): Magnetic field intensity applied to the spin chain. 45 | 46 | ### Output 47 | 48 | This code will output a `float` corresponding to the energy of the ground state. 49 | 50 | If your solution matches the correct one within the given tolerance specified in `check` (in this case it's an relative tolerance of `0.1`), the output will be `"Correct!"` Otherwise, you will receive a `"Wrong answer"` prompt. 51 | 52 | Good luck! 53 | -------------------------------------------------------------------------------- /fall_of_sqynet/fall_of_sqynet_500/images/spaceship_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/XanaduAI/qhack_2023_coding_challenges/efc516ac412dc351ae8bf9745e304717b81d1ff3/fall_of_sqynet/fall_of_sqynet_500/images/spaceship_4.png -------------------------------------------------------------------------------- /office_hijinks/office_hijinks_100/README.md: -------------------------------------------------------------------------------- 1 | ### Backstory 2 | 3 | Zenda and Reece work at a firm, Trine's Designs, that uses quantum devices for very silly things. Their job as physicists is fun, since they get to program and fix quantum devices of all sorts, such as clocks, coffee machines, and lazy-worker detectors. The office has purchased a new quantum clock. To tell time, one has to read quantum states. They'd better get used to it, or they'll be late for their meetings! 4 | 5 | ### The clock and the Bloch circumference 6 | 7 | The Bloch sphere is the most widespread representation of a qubit. However, if we only consider states whose amplitudes are real, you could represent what we will call *the Bloch circumference*. 8 | 9 |

10 | drawing 11 |

12 | 13 | In the figure above, we are representing the state $|+\rangle$ on our circle, since the arrow points in this direction. This circumference is completely equivalent to the blue one, shown below inside the Bloch sphere. 14 | 15 |

16 | drawing 17 |

18 | 19 | In Zenda and Reece's office, the new way to tell the time is to read two states in Bloch's circumference. The state $|0\rangle$ corresponds to 12h on a clock, $|1\rangle$ would be equivalent to 6h, $|+\rangle$ would be 9h, and so on. In this challenge we are going to work with 2 qubits. The first one corresponds to the hour hand and the second one to the minutes. You will be given the time of the day as the input and you will have to generate the quantum states equivalent to such time. 20 | 21 | 22 |

23 | drawing 24 |

25 | 26 | Here's an example of a clock striking 1:30. The qubit on the first wire of your circuit will be the small hand, and the qubit on the second wire, the big hand. 27 | 28 | ## Challenge code 29 | 30 | You must complete the `time` function that will take the hour and minutes as an argument and generate the two-qubit state associated to the indicated time. 31 | 32 | ### Input 33 | 34 | The input will be two integers. The one corresponding to the hours will take values from 1 to 12 and the one corresponding to the minutes will range from 0 to 59. 35 | 36 | ### Output 37 | 38 | The output will be the vector of probabilities of the two-qubit state, measured in the computational basis. You are only asked to complete the gates, we'll handle the rest. Good luck! 39 | -------------------------------------------------------------------------------- /office_hijinks/office_hijinks_100/images/clock1.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/XanaduAI/qhack_2023_coding_challenges/efc516ac412dc351ae8bf9745e304717b81d1ff3/office_hijinks/office_hijinks_100/images/clock1.jpeg -------------------------------------------------------------------------------- /office_hijinks/office_hijinks_100/images/clock2.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/XanaduAI/qhack_2023_coding_challenges/efc516ac412dc351ae8bf9745e304717b81d1ff3/office_hijinks/office_hijinks_100/images/clock2.jpeg -------------------------------------------------------------------------------- /office_hijinks/office_hijinks_100/images/clock3.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/XanaduAI/qhack_2023_coding_challenges/efc516ac412dc351ae8bf9745e304717b81d1ff3/office_hijinks/office_hijinks_100/images/clock3.jpeg -------------------------------------------------------------------------------- /office_hijinks/office_hijinks_100/tick_tock_bloch.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "id": "427a40b0", 6 | "metadata": {}, 7 | "source": [ 8 | "## Challenge code\n", 9 | " \n", 10 | " You must complete the `time` function that will take the hour and minutes as an argument and generate the two-qubit state associated to the indicated time.\n", 11 | " \n", 12 | " ### Input\n", 13 | " \n", 14 | " The input will be two integers. The one corresponding to the hours will take values from 1 to 12 and the one corresponding to the minutes will range from 0 to 59.\n", 15 | " \n", 16 | " ### Output\n", 17 | " \n", 18 | " The output will be the vector of probabilities of the two-qubit state, measured in the computational basis. You are only asked to complete the gates, we'll handle the rest. Good luck!\n", 19 | " ### Imports\n", 20 | " The cell below specifies the libraries you should use in this challenge. Run the cell to import the libraries. ***Do not modify the cell.***" 21 | ] 22 | }, 23 | { 24 | "cell_type": "code", 25 | "execution_count": null, 26 | "id": "278db461", 27 | "metadata": {}, 28 | "outputs": [], 29 | "source": [ 30 | "import json\n", 31 | "import pennylane as qml\n", 32 | "from pennylane import numpy as np" 33 | ] 34 | }, 35 | { 36 | "cell_type": "markdown", 37 | "id": "435d2491", 38 | "metadata": {}, 39 | "source": [ 40 | "### Code\n", 41 | " Complete the code below. Note that during QHack, some sections were not editable. We've marked those sections accordingly here, but you can still edit them if you wish." 42 | ] 43 | }, 44 | { 45 | "cell_type": "code", 46 | "execution_count": null, 47 | "id": "06266835", 48 | "metadata": {}, 49 | "outputs": [], 50 | "source": [ 51 | "# Uneditable section #\n", 52 | "dev = qml.device(\"default.qubit\", wires=[\"hour\", \"minute\"])\n", 53 | "# End of uneditable section #\n", 54 | "\n", 55 | "@qml.qnode(dev)\n", 56 | "def time(hour, minute):\n", 57 | " \"\"\"Generates the quantum state associated with the time passed as argument.\n", 58 | "\n", 59 | " Args:\n", 60 | " hour (int): Hour associated with the requested time\n", 61 | " minute (int): Minutes associated with the requested time\n", 62 | "\n", 63 | " Returns:\n", 64 | " (numpy.tensor): Probabilities associated with the state created.\n", 65 | " \"\"\"\n", 66 | " # Put your code here #\n", 67 | " return qml.probs(wires=[\"hour\", \"minute\"])" 68 | ] 69 | }, 70 | { 71 | "cell_type": "markdown", 72 | "id": "9949cc43", 73 | "metadata": {}, 74 | "source": [ 75 | "These functions are responsible for testing the solution. You will need to run the cell below. ***Do not modify the cell.***" 76 | ] 77 | }, 78 | { 79 | "cell_type": "code", 80 | "execution_count": null, 81 | "id": "cc418823", 82 | "metadata": {}, 83 | "outputs": [], 84 | "source": [ 85 | "def run(test_case_input: str) -> str:\n", 86 | " hour, minute = json.loads(test_case_input)\n", 87 | " state = [float(x) for x in time(hour, minute)]\n", 88 | " return str(state)\n", 89 | "\n", 90 | "def check(solution_output, expected_output: str) -> None:\n", 91 | "\n", 92 | " solution_output = json.loads(solution_output)\n", 93 | " expected_output = json.loads(expected_output)\n", 94 | "\n", 95 | " assert np.allclose(\n", 96 | " solution_output, expected_output, atol=0.1\n", 97 | " ), \"The solution does not seem to be correct.\"" 98 | ] 99 | }, 100 | { 101 | "cell_type": "markdown", 102 | "id": "db798263", 103 | "metadata": {}, 104 | "source": [ 105 | "### Test cases\n", 106 | " Running the cell below will load the test cases. ***Do not modify the cell***.\n", 107 | " - input: [12, 0]\n", 108 | " \t+ expected output: [1.0, 0.0, 0.0, 0.0]\n", 109 | " - input: [1, 30]\n", 110 | " \t+ expected output: [0.0, 0.85355339, 0.0, 1.46446609e-01]\n", 111 | " - input: [2, 45]\n", 112 | " \t+ expected output: [0.28263155, 0.28263155, 0.21736845, 0.21736845]\n", 113 | " - input: [10, 25]\n", 114 | " \t+ expected output: [0.05612163, 0.78167347, 0.01086567, 0.15133923]" 115 | ] 116 | }, 117 | { 118 | "cell_type": "code", 119 | "execution_count": null, 120 | "id": "f17ada78", 121 | "metadata": {}, 122 | "outputs": [], 123 | "source": [ 124 | "test_cases = [['[12, 0]', '[1.0, 0.0, 0.0, 0.0]'], ['[1, 30]', '[0.0, 0.85355339, 0.0, 1.46446609e-01]'], ['[2, 45]', '[0.28263155, 0.28263155, 0.21736845, 0.21736845]'], ['[10, 25]', '[0.05612163, 0.78167347, 0.01086567, 0.15133923]']]" 125 | ] 126 | }, 127 | { 128 | "cell_type": "markdown", 129 | "id": "5bc5b6af", 130 | "metadata": {}, 131 | "source": [ 132 | "### Solution testing\n", 133 | " Once you have run every cell above, including the one with your code, the cell below will test your solution. Run the cell. If you are correct for all of the test cases, it means your solutions is correct. Otherwise, you need to double check your work. ***Do not modify the cell below.***" 134 | ] 135 | }, 136 | { 137 | "cell_type": "code", 138 | "execution_count": null, 139 | "id": "ea33be47", 140 | "metadata": {}, 141 | "outputs": [], 142 | "source": [ 143 | "for i, (input_, expected_output) in enumerate(test_cases):\n", 144 | " print(f\"Running test case {i} with input '{input_}'...\")\n", 145 | "\n", 146 | " try:\n", 147 | " output = run(input_)\n", 148 | "\n", 149 | " except Exception as exc:\n", 150 | " print(f\"Runtime Error. {exc}\")\n", 151 | "\n", 152 | " else:\n", 153 | " if message := check(output, expected_output):\n", 154 | " print(f\"Wrong Answer. Have: '{output}'. Want: '{expected_output}'.\")\n", 155 | "\n", 156 | " else:\n", 157 | " print(\"Correct!\")" 158 | ] 159 | } 160 | ], 161 | "metadata": {}, 162 | "nbformat": 4, 163 | "nbformat_minor": 5 164 | } 165 | -------------------------------------------------------------------------------- /office_hijinks/office_hijinks_200/README.md: -------------------------------------------------------------------------------- 1 | ### Backstory 2 | 3 | At Trine's Designs, the coffee machine is a programmable quantum device. It has three dials that tell the machine the type of drink it will prepare. However, two of the dials are broken. Trine, the CEO, is in despair: *"Coffee is essential for employees to function optimally."* So, as a provisional solution while they contact the manufacturer, Trine calls Zenda and Reece to quickly reprogram the device so that it works with only one dial. 4 | 5 | ### Expressivity in Quantum Machine Learning 6 | 7 | Within QML it is common to find the term expressivity, which refers to the size of all possible models that we can generate by varying our parameters. One way to increase the expressivity of our model family is usually by adding more parameters. However, this is not always a good thing, since increasing the number of parameters, and therefore the number of possible models, means that we have to perform our training on a very large set, making it more difficult to find the model that best suits our needs. Therefore, the real challenge of a good QML researcher is to find the smallest possible family of models that still contains the optimal solution. There is much more to the notion of expressivity, but in this challenge we are going to push the concept to its limits. 8 | 9 | Suppose that we are in the situation where we have 3 qubits and we know that the solution to our problem is a computational basis state, i.e. an element of the set 10 | 11 | $$ 12 | \mathcal{B}=\left\lbrace |000\rangle, |001\rangle, |010\rangle,\dots, |111\rangle\right\rbrace. 13 | $$ 14 | 15 | We don't know exactly what the basis state is, so we would like to generate an ansatz expressive enough so that: 16 | 17 | $$ 18 | \begin{align*} 19 | U(\vec{\theta_0})|000\rangle & = |000\rangle \\ 20 | U(\vec{\theta_1})|000\rangle & = |001\rangle \\ 21 | U(\vec{\theta_2})|000\rangle & = |010\rangle \\ 22 | & \vdots \\ 23 | U(\vec{\theta_7})|000\rangle & = |111\rangle 24 | \end{align*} 25 | $$ 26 | 27 | for certain values of $\vec{\theta_i}$. An example of ansatz that accomplishes this would be the following circuit: 28 | 29 |

30 | drawing 31 |

32 | 33 | This is the fundamental concept in [Basis embedding](https://pennylane.ai/blog/2022/08/how-to-embed-data-into-a-quantum-state/), where you can see that by taking $\alpha$, $\beta$ and $\gamma$ properly, we can generate any basis state. However, this challenge is not going to be this easy. You are asked to build an ansatz that, with **only one parameter,** is able to generate all the basis states. To judge your solution, we will ask you to provide us with a list of the 8 values of the parameter that generate each of them. Good luck! 34 | 35 | ## Challenge code 36 | 37 | You must complete the qnode `model` that will be in charge of obtaining different outputs. This model depends on a single parameter and you must ensure that it generates all the basis states. 38 | You must also define the function `generate_coefficients`, which will return a list with the 8 values of the parameter to generate these basis states. 39 | 40 | ### Output 41 | 42 | To judge this challenge, the `generate_coefficients` function will be called first. With the output of this function (the eight coefficients), we will call the model to ensure that the generated states are the desired ones. In addition, we will check that: 43 | - The model is continuous (small modifications of the parameter imply small modifications of the generated state). By putting the parameter inside rotation gates you will have no problems with this. 44 | 45 | 46 | - The generated coefficients are in the interval [0,10]. Solutions that do not fit this interval will be considered incorrect. 47 | 48 | In this challenge, we will not work with public and private tests. We will simply check that all of the above is fulfilled. Good luck! 49 | -------------------------------------------------------------------------------- /office_hijinks/office_hijinks_200/images/example_sol.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/XanaduAI/qhack_2023_coding_challenges/efc516ac412dc351ae8bf9745e304717b81d1ff3/office_hijinks/office_hijinks_200/images/example_sol.jpeg -------------------------------------------------------------------------------- /office_hijinks/office_hijinks_200/the_super_parameter.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "id": "c8a56c8b", 6 | "metadata": {}, 7 | "source": [ 8 | "## Challenge code\n", 9 | " \n", 10 | " You must complete the qnode `model` that will be in charge of obtaining different outputs. This model depends on a single parameter and you must ensure that it generates all the basis states.\n", 11 | " You must also define the function `generate_coefficients`, which will return a list with the 8 values of the parameter to generate these basis states.\n", 12 | " \n", 13 | " ### Output\n", 14 | " \n", 15 | " To judge this challenge, the `generate_coefficients` function will be called first. With the output of this function (the eight coefficients), we will call the model to ensure that the generated states are the desired ones. In addition, we will check that:\n", 16 | " - The model is continuous (small modifications of the parameter imply small modifications of the generated state). By putting the parameter inside rotation gates you will have no problems with this. \n", 17 | " \n", 18 | " \n", 19 | " - The generated coefficients are in the interval [0,10]. Solutions that do not fit this interval will be considered incorrect.\n", 20 | " \n", 21 | " In this challenge, we will not work with public and private tests. We will simply check that all of the above is fulfilled. Good luck!\n", 22 | " ### Imports\n", 23 | " The cell below specifies the libraries you should use in this challenge. Run the cell to import the libraries. ***Do not modify the cell.***" 24 | ] 25 | }, 26 | { 27 | "cell_type": "code", 28 | "execution_count": null, 29 | "id": "27975f10", 30 | "metadata": {}, 31 | "outputs": [], 32 | "source": [ 33 | "import json\n", 34 | "import pennylane as qml\n", 35 | "from pennylane import numpy as np" 36 | ] 37 | }, 38 | { 39 | "cell_type": "markdown", 40 | "id": "350512b3", 41 | "metadata": {}, 42 | "source": [ 43 | "### Code\n", 44 | " Complete the code below. Note that during QHack, some sections were not editable. We've marked those sections accordingly here, but you can still edit them if you wish." 45 | ] 46 | }, 47 | { 48 | "cell_type": "code", 49 | "execution_count": null, 50 | "id": "c82dd109", 51 | "metadata": {}, 52 | "outputs": [], 53 | "source": [ 54 | "# Uneditable section #\n", 55 | "dev = qml.device(\"default.qubit\", wires=3)\n", 56 | "# End of uneditable section #\n", 57 | "\n", 58 | "@qml.qnode(dev)\n", 59 | "def model(alpha):\n", 60 | " \"\"\"In this qnode you will define your model in such a way that there is a single \n", 61 | " parameter alpha which returns each of the basic states.\n", 62 | "\n", 63 | " Args:\n", 64 | " alpha (float): The only parameter of the model.\n", 65 | "\n", 66 | " Returns:\n", 67 | " (numpy.tensor): The probability vector of the resulting quantum state.\n", 68 | " \"\"\"\n", 69 | " # Put your code here #\n", 70 | " return qml.probs(wires=range(3))\n", 71 | "\n", 72 | "def generate_coefficients():\n", 73 | " \"\"\"This function must return a list of 8 different values of the parameter that\n", 74 | " generate the states 000, 001, 010, ..., 111, respectively, with your ansatz.\n", 75 | "\n", 76 | " Returns:\n", 77 | " (list(int)): A list of eight real numbers.\n", 78 | " \"\"\"\n", 79 | " # Put your code here #" 80 | ] 81 | }, 82 | { 83 | "cell_type": "markdown", 84 | "id": "047c7952", 85 | "metadata": {}, 86 | "source": [ 87 | "These functions are responsible for testing the solution. You will need to run the cell below. ***Do not modify the cell.***" 88 | ] 89 | }, 90 | { 91 | "cell_type": "code", 92 | "execution_count": null, 93 | "id": "053a03ea", 94 | "metadata": {}, 95 | "outputs": [], 96 | "source": [ 97 | "def run(test_case_input: str) -> str:\n", 98 | " return None\n", 99 | "\n", 100 | "def check(solution_output, expected_output: str) -> None:\n", 101 | " coefs = generate_coefficients()\n", 102 | " output = np.array([model(c) for c in coefs])\n", 103 | " epsilon = 0.001\n", 104 | "\n", 105 | " for i in range(len(coefs)):\n", 106 | " assert np.isclose(output[i][i], 1)\n", 107 | "\n", 108 | " def is_continuous(function, point):\n", 109 | " limit = calculate_limit(function, point)\n", 110 | "\n", 111 | " if limit is not None and sum(abs(limit - function(point))) < epsilon:\n", 112 | " return True\n", 113 | " else:\n", 114 | " return False\n", 115 | "\n", 116 | " def is_continuous_in_interval(function, interval):\n", 117 | " for point in interval:\n", 118 | " if not is_continuous(function, point):\n", 119 | " return False\n", 120 | " return True\n", 121 | "\n", 122 | " def calculate_limit(function, point):\n", 123 | " x_values = [point - epsilon, point, point + epsilon]\n", 124 | " y_values = [function(x) for x in x_values]\n", 125 | " average = sum(y_values) / len(y_values)\n", 126 | "\n", 127 | " return average\n", 128 | "\n", 129 | " assert is_continuous_in_interval(model, np.arange(0,10,0.001))\n", 130 | "\n", 131 | " for coef in coefs:\n", 132 | " assert coef >= 0 and coef <= 10" 133 | ] 134 | }, 135 | { 136 | "cell_type": "markdown", 137 | "id": "0fb93dc9", 138 | "metadata": {}, 139 | "source": [ 140 | "### Test cases\n", 141 | " Running the cell below will load the test cases. ***Do not modify the cell***.\n", 142 | " - input: No input\n", 143 | " \t+ expected output: No output\n", 144 | " - input: No input\n", 145 | " \t+ expected output: No output" 146 | ] 147 | }, 148 | { 149 | "cell_type": "code", 150 | "execution_count": null, 151 | "id": "ad384239", 152 | "metadata": {}, 153 | "outputs": [], 154 | "source": [ 155 | "test_cases = [['No input', 'No output'], ['No input', 'No output']]" 156 | ] 157 | }, 158 | { 159 | "cell_type": "markdown", 160 | "id": "934e0809", 161 | "metadata": {}, 162 | "source": [ 163 | "### Solution testing\n", 164 | " Once you have run every cell above, including the one with your code, the cell below will test your solution. Run the cell. If you are correct for all of the test cases, it means your solutions is correct. Otherwise, you need to double check your work. ***Do not modify the cell below.***" 165 | ] 166 | }, 167 | { 168 | "cell_type": "code", 169 | "execution_count": null, 170 | "id": "71ea0fdd", 171 | "metadata": {}, 172 | "outputs": [], 173 | "source": [ 174 | "for i, (input_, expected_output) in enumerate(test_cases):\n", 175 | " print(f\"Running test case {i} with input '{input_}'...\")\n", 176 | "\n", 177 | " try:\n", 178 | " output = run(input_)\n", 179 | "\n", 180 | " except Exception as exc:\n", 181 | " print(f\"Runtime Error. {exc}\")\n", 182 | "\n", 183 | " else:\n", 184 | " if message := check(output, expected_output):\n", 185 | " print(f\"Wrong Answer. Have: '{output}'. Want: '{expected_output}'.\")\n", 186 | "\n", 187 | " else:\n", 188 | " print(\"Correct!\")" 189 | ] 190 | } 191 | ], 192 | "metadata": {}, 193 | "nbformat": 4, 194 | "nbformat_minor": 5 195 | } 196 | -------------------------------------------------------------------------------- /office_hijinks/office_hijinks_300/README.md: -------------------------------------------------------------------------------- 1 | ### Backstory 2 | 3 | Zenda needs to send an email to Reece through Trine's Designs' Quantum Area Network. The network is a quantum circuit that simply swaps qubits between wires. However, a virus seems to be interfering with proper communication within the network. Zenda can't get rid of the virus, but she has figured out what it's doing. Let's help her reprogram the network to get around the issue. 4 | 5 | ### More than just a SWAP 6 | 7 | This challenge's statement is very simple, but solving it may not be so easy. The goal will be to move a state $\vert\psi\rangle$ from one qubit to another, as shown in the figure: 8 | 9 |

10 | drawing 11 |

12 | 13 | Easy, isn't it? Well, we are going to complicate it a little bit. We will not allow any direct connections between the first and last qubits, so you will have to use the middle qubit to pass the information from one qubit to another. 14 | 15 | The exercise has become more challenging, but we still want to complicate it further! In addition to all of the above, we are going to generate a virus operator $U$ and place it in the middle of the circuit, like so: 16 | 17 |

18 | drawing 19 |

20 | 21 | In this case, $U$ consists of one `PauliX` gate that we place randomly in one of the three qubits (each time, the gate is generated in a different wire). 22 | You should be able to complete the circuit so that, regardless of the randomly generated operator $U$, you are able to move the state from the first qubit to the last qubit. 23 | 24 | ## Challenge code 25 | 26 | In this challenge, you will only be asked to complete the `circuit_left` and `circuit_right` operators to meet the objective of the statement. 27 | 28 | ### Input 29 | 30 | To encode the initial state $\vert \psi \rangle,$ we will use a $U3$ gate. The input will be the three parameters (`alpha`,`beta`,`gamma`) associated with this gate. 31 | 32 | ### Output 33 | 34 | In this case, the output is the measurement result of the last qubit with respect to an observable. In this way, we check if it coincides with the expected state. Good luck! 35 | -------------------------------------------------------------------------------- /office_hijinks/office_hijinks_300/images/image1_qubit_change.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/XanaduAI/qhack_2023_coding_challenges/efc516ac412dc351ae8bf9745e304717b81d1ff3/office_hijinks/office_hijinks_300/images/image1_qubit_change.jpeg -------------------------------------------------------------------------------- /office_hijinks/office_hijinks_300/images/image2_qubit_change.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/XanaduAI/qhack_2023_coding_challenges/efc516ac412dc351ae8bf9745e304717b81d1ff3/office_hijinks/office_hijinks_300/images/image2_qubit_change.jpeg -------------------------------------------------------------------------------- /office_hijinks/office_hijinks_400/README.md: -------------------------------------------------------------------------------- 1 | ### Backstory 2 | 3 | It is very common to work in teams, but it is just as common to find a teammate who decides not to work. However, colleagues do not usually tell the boss, so this individual goes unnoticed. Zenda is supervising four employees, and it is known that one of them never works. But who is it? 4 | 5 | ### Finding the lazy employee 6 | 7 | The project Zenda's team is working on can only be completed if **at least three people** in the team are working. Let's model this situation in a circuit: 8 | 9 |

10 | drawing 11 |

12 | 13 | In this diagram, the qubit $e_i$ refers to the $i$-th employee, which will take the value 1 if this employee is chosen to work on the project. The output state labelled *result* will take the value 0 if the project was not completed and 1 if it was. Let us imagine that employee $e_1$ is the one who does not work. Then, if we apply the operator to the state $|1\rangle|1\rangle|0\rangle|1\rangle|0\rangle$ (that is, we select $e_1$, $e_2$ and $e_4$ for the project), the output will be $|1\rangle|1\rangle|0\rangle|1\rangle|0\rangle$. As we can see, the last qubit is still $\lvert 0\rangle$, i.e. the project has not been carried out. This is because there are only two employees that actually work on the project, and a minimum of three is required. 14 | 15 | 16 | Zenda wants to know who the lazy worker is, executing as few projects as possible. For this reason, they ask you to help her with your quantum skills. You are asked to discover who the lazy employee is, using a single shot and a single call to the "Project execution" operator. 17 | 18 | ## Challenge code 19 | 20 | On one hand, you are asked to complete `circuit` (you only need to apply gates). You can only call the `project_execution` operator once, which is already incorporated in the template. 21 | On the other hand, you must complete `process_output`, which will take the output of your circuit and will return who the lazy guy is. 22 | 23 | The `project_execution` function will be generated when testing the solution; if you want to experiment with the function output in the notebook, you can temporarily replace `project_execution` with an operator of the form `qml.MultiControlledX(wires=['e1', 'e2', 'e4', 'result'])`. In this case, the absence of "e3" on the wires means that in this project, "e3" will be the lazy employee. Just remember to switch it back to project_execution before submitting, so that your function uses the correct project_execution during testing! 24 | 25 | You may find it useful to do some tests in [Quirk](https://algassert.com/quirk) before you start coding. 26 | 27 | ### Output 28 | 29 | To judge this challenge, we will arbitrarily generate 5000 different projects (`project_execution`), which we will send one by one to the circuit to check that your prediction is correct ("e1", "e2", "e3" or "e4"). Therefore, in this case, there will be no public and private test cases. Good luck! 30 | -------------------------------------------------------------------------------- /office_hijinks/office_hijinks_400/images/project_execution.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/XanaduAI/qhack_2023_coding_challenges/efc516ac412dc351ae8bf9745e304717b81d1ff3/office_hijinks/office_hijinks_400/images/project_execution.jpeg -------------------------------------------------------------------------------- /office_hijinks/office_hijinks_500/README.md: -------------------------------------------------------------------------------- 1 | ### Backstory 2 | 3 | Trine's Designs is very community-oriented, and customers like to write letters to the staff to get help with a variety of issues. A mysterious person has sent a non-sensical mathematical proof about complex numbers. No one at the company is good at complex analysis, but Zenda and Reece set out to use a quantum circuit to prove the anonymous customer wrong. 4 | 5 | ### One-shot proof 6 | 7 | In the 17th century, a nice custom spread among intellectuals: challenging each other to solve numerical problems and puzzles. These challenges were sent through letters and, thanks to this, mathematics expanded and gained a lot of popularity. 8 | 9 | It seems that this tradition is making a comeback because the other day Reece received the following letter at the office: 10 | 11 | "Hello Trine team, I have just come to a discovery of great importance, I have just proved that $\frac{2\pi}{3}=\frac{4\pi}{3}.$ I attach a simple proof. If you think I'm wrong, prove it!*" 12 |

13 | drawing 14 |

15 | 16 | Actually, the proof is very convincing, but Reece turns to quantum computing to show that this is not so (for fun, if you like math: find the line where the mistake is!). To do this, Reece manages to show that $R_Y(\frac{2\pi}{3})$ is different from $R_Y(\frac{4\pi}{3}).$ In fact, they are so different that a single shot is enough to distinguish them! 17 | 18 | This will be your objetive for this challenge! We are going to give you a gate $U$, which you know is either $R_Y(\frac{2\pi}{3})$ or $R_Y(\frac{4\pi}{3}).$ Your task will be to build a quantum circuit containing $U$ to unambiguously determine which of the two gates it is using only *one shot*. 19 | 20 | To do this, you will have access to a two-qubit circuit. You can use $U$ as many times as you want, but one thing is important: the solution must guarantee with **100% probability** which of the two options it is. 21 | 22 | Note: even if you do not know $U$, you are allowed to use `qml.ctrl` over $U$ if necessary. 23 | 24 |
Epilogue 25 | 26 | After successfully debunking the proof, Zenda and Reece are enjoying a well-deserved rest from office hijinks when Doc Trine, the boss herself, appears from the basement laboratory. "Well, it seems you have passed my little math test! Please, step into my office." Her office is the basement, and they filled with all sorts of odds and ends: a machine whose only function is to turn itself off, an anti-toaster for making old bread fresh, some sort of tiny imp lugging around two chambers and looking for work. Trine looks at them: "I think you might be excited by my latest invention. It promises to save us all a lot of time!" 27 | 28 | Read on in Bending Bennett's Laws. 29 | 30 |
31 | 32 | ## Challenge code 33 | 34 | On one hand you are asked to complete `circuit` (you only need to apply gates). 35 | On the other hand you must complete `process_output`, which will take the output of `circuit` (a vector of dimension two where each term can take the value 0 or 1) and will return 2 if $U = RY(2\pi/3)$ or 4 if $U = RY(4\pi/3).$ 36 | 37 | 38 | ### Output 39 | 40 | The circuit function will receive the gate $U$ that you are asked to determine. To judge whether your circuit works as expected, we will randomly send 5000 different examples and check that they always classified correctly. Therefore, in this question there are no public or private test cases. They are randomly generated. 41 | Good luck! 42 | -------------------------------------------------------------------------------- /office_hijinks/office_hijinks_500/images/2is4.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/XanaduAI/qhack_2023_coding_challenges/efc516ac412dc351ae8bf9745e304717b81d1ff3/office_hijinks/office_hijinks_500/images/2is4.jpeg -------------------------------------------------------------------------------- /office_hijinks/office_hijinks_500/the_false_proof.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "id": "9d5876b4", 6 | "metadata": {}, 7 | "source": [ 8 | "## Challenge code\n", 9 | " \n", 10 | " On one hand you are asked to complete `circuit` (you only need to apply gates).\n", 11 | " On the other hand you must complete `process_output`, which will take the output of `circuit` (a vector of dimension two where each term can take the value 0 or 1) and will return 2 if $U = RY(2\\pi/3)$ or 4 if $U = RY(4\\pi/3).$\n", 12 | " \n", 13 | " \n", 14 | " ### Output\n", 15 | " \n", 16 | " The circuit function will receive the gate $U$ that you are asked to determine. To judge whether your circuit works as expected, we will randomly send 5000 different examples and check that they always classified correctly. Therefore, in this question there are no public or private test cases. They are randomly generated.\n", 17 | " Good luck!\n", 18 | " ### Imports\n", 19 | " The cell below specifies the libraries you should use in this challenge. Run the cell to import the libraries. ***Do not modify the cell.***" 20 | ] 21 | }, 22 | { 23 | "cell_type": "code", 24 | "execution_count": null, 25 | "id": "deccd69a", 26 | "metadata": {}, 27 | "outputs": [], 28 | "source": [ 29 | "import json\n", 30 | "import pennylane as qml\n", 31 | "from pennylane import numpy as np" 32 | ] 33 | }, 34 | { 35 | "cell_type": "markdown", 36 | "id": "06966f63", 37 | "metadata": {}, 38 | "source": [ 39 | "### Code\n", 40 | " Complete the code below. Note that during QHack, some sections were not editable. We've marked those sections accordingly here, but you can still edit them if you wish." 41 | ] 42 | }, 43 | { 44 | "cell_type": "code", 45 | "execution_count": null, 46 | "id": "c4bca776", 47 | "metadata": {}, 48 | "outputs": [], 49 | "source": [ 50 | "# Uneditable section #\n", 51 | "dev = qml.device(\"default.qubit\", wires=2, shots=1)\n", 52 | "dev.operations.add(\"op\")\n", 53 | "dev.operations.add(\"C(op)\")\n", 54 | "# End of uneditable section #\n", 55 | "\n", 56 | "@qml.qnode(dev)\n", 57 | "def circuit(U):\n", 58 | " \"\"\"This will be the circuit you will use to determine which of the two angles we have.\n", 59 | " Remember that only a single shot will be executed.\n", 60 | "\n", 61 | " Args:\n", 62 | " U (qml.ops): It is the gate to discriminate between RY(2pi/3) or RY(4pi/3).\n", 63 | "\n", 64 | " Returns:\n", 65 | " (numpy.tensor): Vector of two elements representing the output measured in each of the qubits.\n", 66 | " \"\"\"\n", 67 | " # Put your code here #\n", 68 | " # to use U, call 'U(wires = )'\n", 69 | " # to use Control-U, call 'qml.ctrl(U, control = )(wires = )'\n", 70 | " return qml.sample(wires=range(2))\n", 71 | "\n", 72 | "def process_output(measurement):\n", 73 | " \"\"\"This function processes the output of the circuit to discriminate between gates.\n", 74 | "\n", 75 | " Args:\n", 76 | " measurement (numpy.array): Output of the previous circuit a vector of dimension 2.\n", 77 | "\n", 78 | " Returns:\n", 79 | " (int): return 2 or 4 depending on the associated RY gate.\n", 80 | " \"\"\"\n", 81 | " # Put your code here #" 82 | ] 83 | }, 84 | { 85 | "cell_type": "markdown", 86 | "id": "8dcd562d", 87 | "metadata": {}, 88 | "source": [ 89 | "These functions are responsible for testing the solution. You will need to run the cell below. ***Do not modify the cell.***" 90 | ] 91 | }, 92 | { 93 | "cell_type": "code", 94 | "execution_count": null, 95 | "id": "078ca4cb", 96 | "metadata": {}, 97 | "outputs": [], 98 | "source": [ 99 | "def run(test_case_input: str) -> str:\n", 100 | " return None\n", 101 | "\n", 102 | "def check(solution_output: str, expected_output: str) -> None:\n", 103 | " numbers = 2 * np.random.randint(1, 3, 5000)\n", 104 | "\n", 105 | " def U2(wires):\n", 106 | " class op(qml.operation.Operator):\n", 107 | " num_wires = 1\n", 108 | "\n", 109 | " def compute_decomposition(self, wires):\n", 110 | " raise ValueError(\"You cannot decompose this gate\")\n", 111 | "\n", 112 | " def matrix(self):\n", 113 | " return qml.matrix(qml.RY(2 * np.pi / 3, wires=3))\n", 114 | "\n", 115 | " op(wires=wires)\n", 116 | " return None\n", 117 | "\n", 118 | " def U4(wires):\n", 119 | " class op(qml.operation.Operator):\n", 120 | " num_wires = 1\n", 121 | "\n", 122 | " def compute_decomposition(self, wires):\n", 123 | " raise ValueError(\"You cannot decompose this gate\")\n", 124 | "\n", 125 | " def matrix(self):\n", 126 | " return qml.matrix(qml.RY(4 * np.pi / 3, wires=3))\n", 127 | "\n", 128 | " op(wires=wires)\n", 129 | " return None\n", 130 | "\n", 131 | " output = []\n", 132 | " for i in numbers:\n", 133 | " if i == 2:\n", 134 | " U = U2\n", 135 | " else:\n", 136 | " U = U4\n", 137 | " out = circuit(U)\n", 138 | " output.append(process_output(out))\n", 139 | "\n", 140 | " assert np.allclose(\n", 141 | " output, numbers, rtol=1e-4\n", 142 | " ), \"Your circuit does not give the correct output.\"" 143 | ] 144 | }, 145 | { 146 | "cell_type": "markdown", 147 | "id": "3fe458c7", 148 | "metadata": {}, 149 | "source": [ 150 | "### Test cases\n", 151 | " Running the cell below will load the test cases. ***Do not modify the cell***.\n", 152 | " - input: No input\n", 153 | " \t+ expected output: No output\n", 154 | " - input: No input\n", 155 | " \t+ expected output: No output" 156 | ] 157 | }, 158 | { 159 | "cell_type": "code", 160 | "execution_count": null, 161 | "id": "13041028", 162 | "metadata": {}, 163 | "outputs": [], 164 | "source": [ 165 | "test_cases = [['No input', 'No output'], ['No input', 'No output']]" 166 | ] 167 | }, 168 | { 169 | "cell_type": "markdown", 170 | "id": "d9724287", 171 | "metadata": {}, 172 | "source": [ 173 | "### Solution testing\n", 174 | " Once you have run every cell above, including the one with your code, the cell below will test your solution. Run the cell. If you are correct for all of the test cases, it means your solutions is correct. Otherwise, you need to double check your work. ***Do not modify the cell below.***" 175 | ] 176 | }, 177 | { 178 | "cell_type": "code", 179 | "execution_count": null, 180 | "id": "22d40c9e", 181 | "metadata": {}, 182 | "outputs": [], 183 | "source": [ 184 | "for i, (input_, expected_output) in enumerate(test_cases):\n", 185 | " print(f\"Running test case {i} with input '{input_}'...\")\n", 186 | "\n", 187 | " try:\n", 188 | " output = run(input_)\n", 189 | "\n", 190 | " except Exception as exc:\n", 191 | " print(f\"Runtime Error. {exc}\")\n", 192 | "\n", 193 | " else:\n", 194 | " if message := check(output, expected_output):\n", 195 | " print(f\"Wrong Answer. Have: '{output}'. Want: '{expected_output}'.\")\n", 196 | "\n", 197 | " else:\n", 198 | " print(\"Correct!\")" 199 | ] 200 | } 201 | ], 202 | "metadata": {}, 203 | "nbformat": 4, 204 | "nbformat_minor": 5 205 | } 206 | -------------------------------------------------------------------------------- /tutorial_challenges/tutorial_1/README.md: -------------------------------------------------------------------------------- 1 | Welcome to the QHack 2023 tutorial challenges! These challenges are worth no points — they are specifically designed to get your brain active and into the right mindset for the competition. You will also learn about various aspects of PennyLane that are essential to quantum computing, quantum machine learning, and quantum chemistry. Have fun! 2 | 3 | ### Tutorial \# 1 — Adding two numbers 4 | 5 | By completing this tutorial problem, you will gain confidence with interacting with this interface for submitting solutions to the challenges. 6 | 7 | The code intentionally contains editable sections as well as non-editable sections to ensure that vital pieces of the entire code are not modified — they are essential to evaluating your solution. Within the editable sections, you must write your solution to the given problem. Your solution will run against `test_cases`. 8 | 9 | ## Challenge code 10 | 11 | In the notebook `it_adds_up.ipynb`, you are given a function called `add_numbers`. **You must complete this function**. 12 | 13 | ### Input 14 | 15 | As input to this problem, you are given a `list(float)` containing two numbers to add together: `x` and `y`. 16 | 17 | ### Output 18 | 19 | This code must output `x + y` (`float`). 20 | 21 | If your solution matches the correct one within the given tolerance specified in `check` (in this case it's a `1e-4` relative error tolerance), the output will be `"Correct!"` Otherwise, you will receive a `"Wrong answer"` prompt. 22 | 23 | Good luck and have fun with all of the coding challenges! 24 | -------------------------------------------------------------------------------- /tutorial_challenges/tutorial_1/it_adds_up.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "id": "9b574e43", 6 | "metadata": {}, 7 | "source": [ 8 | "## Challenge code\n", 9 | " \n", 10 | " In the code below, you are given a function called `add_numbers`. **You must complete this function**.\n", 11 | " \n", 12 | " ### Input \n", 13 | " \n", 14 | " As input to this problem, you are given a `list(float)` containing two numbers to add together: `x` and `y`.\n", 15 | " \n", 16 | " ### Output\n", 17 | " \n", 18 | " This code must output `x + y` (`float`).\n", 19 | " \n", 20 | " If your solution matches the correct one within the given tolerance specified in `check` (in this case it's a `1e-4` relative error tolerance), the output will be `\"Correct!\"` Otherwise, you will receive a `\"Wrong answer\"` prompt.\n", 21 | " \n", 22 | " Good luck and have fun with all of the coding challenges! \n", 23 | " ### Imports\n", 24 | " The cell below specifies the libraries you should use in this challenge. Run the cell to import the libraries. ***Do not modify the cell.***" 25 | ] 26 | }, 27 | { 28 | "cell_type": "code", 29 | "execution_count": null, 30 | "id": "1eab890b", 31 | "metadata": {}, 32 | "outputs": [], 33 | "source": [ 34 | "import json\n", 35 | "import pennylane as qml\n", 36 | "from pennylane import numpy as np" 37 | ] 38 | }, 39 | { 40 | "cell_type": "markdown", 41 | "id": "39be654b", 42 | "metadata": {}, 43 | "source": [ 44 | "### Code\n", 45 | " Complete the code below. Note that during QHack, some sections were not editable. We've marked those sections accordingly here, but you can still edit them if you wish." 46 | ] 47 | }, 48 | { 49 | "cell_type": "code", 50 | "execution_count": null, 51 | "id": "3dfa5d02", 52 | "metadata": {}, 53 | "outputs": [], 54 | "source": [ 55 | "# Uneditable section #\n", 56 | "# Welcome to the QHack 2023 coding challenges!\n", 57 | "def add_numbers(x, y):\n", 58 | " \"\"\"This function adds two numbers together.\n", 59 | "\n", 60 | " Args:\n", 61 | " x (float): A number.\n", 62 | " y (float): A number.\n", 63 | "\n", 64 | " Returns:\n", 65 | " (float): The result of adding x and y.\n", 66 | " \"\"\"\n", 67 | " # End of uneditable section #\n", 68 | "\n", 69 | " # Put your code here # \n", 70 | " return" 71 | ] 72 | }, 73 | { 74 | "cell_type": "markdown", 75 | "id": "ce9ef8f1", 76 | "metadata": {}, 77 | "source": [ 78 | "These functions are responsible for testing the solution. You will need to run the cell below. ***Do not modify the cell.***" 79 | ] 80 | }, 81 | { 82 | "cell_type": "code", 83 | "execution_count": null, 84 | "id": "24eadcf4", 85 | "metadata": {}, 86 | "outputs": [], 87 | "source": [ 88 | "def run(test_case_input: str) -> str:\n", 89 | " x, y = json.loads(test_case_input)\n", 90 | " result = add_numbers(x, y)\n", 91 | " return str(result)\n", 92 | "\n", 93 | "def check(solution_output: str, expected_output: str) -> None:\n", 94 | " solution_output = json.loads(solution_output)\n", 95 | " expected_output = json.loads(expected_output)\n", 96 | " assert np.allclose(\n", 97 | " solution_output, expected_output, rtol=1e-4\n", 98 | " ), \"Your addition function isn't quite right!\"" 99 | ] 100 | }, 101 | { 102 | "cell_type": "markdown", 103 | "id": "91dde910", 104 | "metadata": {}, 105 | "source": [ 106 | "### Test cases\n", 107 | " Running the cell below will load the test cases. ***Do not modify the cell***.\n", 108 | " - input: [0.2, -0.2]\n", 109 | " \t+ expected output: 0.0\n", 110 | " - input: [400, 166]\n", 111 | " \t+ expected output: 566" 112 | ] 113 | }, 114 | { 115 | "cell_type": "code", 116 | "execution_count": null, 117 | "id": "a0daf5da", 118 | "metadata": {}, 119 | "outputs": [], 120 | "source": [ 121 | "test_cases = [['[0.2, -0.2]', '0.0'], ['[400, 166]', '566']]" 122 | ] 123 | }, 124 | { 125 | "cell_type": "markdown", 126 | "id": "c8da72a2", 127 | "metadata": {}, 128 | "source": [ 129 | "### Solution testing\n", 130 | " Once you have run every cell above, including the one with your code, the cell below will test your solution. Run the cell. If you are correct for all of the test cases, it means your solutions is correct. Otherwise, you need to double check your work. ***Do not modify the cell below.***" 131 | ] 132 | }, 133 | { 134 | "cell_type": "code", 135 | "execution_count": null, 136 | "id": "e0a96553", 137 | "metadata": {}, 138 | "outputs": [], 139 | "source": [ 140 | "for i, (input_, expected_output) in enumerate(test_cases):\n", 141 | " print(f\"Running test case {i} with input '{input_}'...\")\n", 142 | "\n", 143 | " try:\n", 144 | " output = run(input_)\n", 145 | "\n", 146 | " except Exception as exc:\n", 147 | " print(f\"Runtime Error. {exc}\")\n", 148 | "\n", 149 | " else:\n", 150 | " if message := check(output, expected_output):\n", 151 | " print(f\"Wrong Answer. Have: '{output}'. Want: '{expected_output}'.\")\n", 152 | "\n", 153 | " else:\n", 154 | " print(\"Correct!\")" 155 | ] 156 | } 157 | ], 158 | "metadata": {}, 159 | "nbformat": 4, 160 | "nbformat_minor": 5 161 | } 162 | -------------------------------------------------------------------------------- /tutorial_challenges/tutorial_2/README.md: -------------------------------------------------------------------------------- 1 | Welcome to the QHack 2023 tutorial challenges! These challenges are worth no points — they are specifically designed to get your brain active and into the right mindset for the competition. You will also learn about various aspects of PennyLane that are essential to quantum computing, quantum machine learning, and quantum chemistry. Have fun! 2 | 3 | ### Tutorial \#2 — Building a quantum circuit 4 | 5 | In PennyLane, the fundamental unit of quantum circuit simulation is called a *QNode*. Basically, a QNode takes a *quantum function* — a Python function that contains instructions in the form of quantum gates acting on wires — and a device, runs the function on the device, and returns a measurement. To see how this works, check out our [YouTube video](https://youtu.be/2T8lSejPFog). 6 | 7 | In this challenge, you need to simulate the following quantum circuit and return the resulting probability distribution as an output. 8 | 9 |

10 | 11 |

12 | 13 | ## Challenge code 14 | 15 | In the notebook `affairs_of_state.ipynb`, you are given a function called `circuit`. **You must complete this function** by specifying a device, turning `circuit` into a QNode, and providing the appropriate gates. 16 | 17 | Here are some helpful resources: 18 | 19 | - [Creating a quantum circuit — YouTube video](https://youtu.be/2T8lSejPFog) 20 | - [Basic tutorial: qubit rotation](https://pennylane.ai/qml/demos/tutorial_qubit_rotation.html) 21 | - [Quantum circuits in PennyLane](https://docs.pennylane.ai/en/stable/introduction/circuits.html#quantum-functions) 22 | 23 | ### Input 24 | 25 | As input to this problem, you are given two `angles` (`list(float)`). The first and second entries of `angles` correspond to $\theta_0$ and $\theta_1$ in the diagram above. 26 | 27 | ### Output 28 | 29 | This code must output the probabilities (`numpy.tensor`) resulting from the quantum circuit pictured above. 30 | 31 | If your solution matches the correct one within the given tolerance specified in `check` (in this case it's a `1e-4` relative error tolerance), the output will be `"Correct!"` Otherwise, you will receive a `"Wrong answer"` prompt. 32 | 33 | Good luck! 34 | -------------------------------------------------------------------------------- /tutorial_challenges/tutorial_2/affairs_of_state.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "id": "d1b6f5fe", 6 | "metadata": {}, 7 | "source": [ 8 | "## Challenge code\n", 9 | " \n", 10 | " In the code below, you are given a function called `circuit`. **You must complete this function** by specifying a device, turning `circuit` into a QNode, and providing the appropriate gates. \n", 11 | " \n", 12 | " Here are some helpful resources:\n", 13 | " \n", 14 | " - [Creating a quantum circuit — YouTube video](https://youtu.be/2T8lSejPFog)\n", 15 | " - [Basic tutorial: qubit rotation](https://pennylane.ai/qml/demos/tutorial_qubit_rotation.html)\n", 16 | " - [Quantum circuits in PennyLane](https://docs.pennylane.ai/en/stable/introduction/circuits.html#quantum-functions)\n", 17 | " \n", 18 | " ### Input \n", 19 | " \n", 20 | " As input to this problem, you are given two `angles` (`list(float)`). The first and second entries of `angles` correspond to $\\theta_0$ and $\\theta_1$ in the diagram above.\n", 21 | " \n", 22 | " ### Output\n", 23 | " \n", 24 | " This code must output the probabilities (`numpy.tensor`) resulting from the quantum circuit pictured above. \n", 25 | " \n", 26 | " If your solution matches the correct one within the given tolerance specified in `check` (in this case it's a `1e-4` relative error tolerance), the output will be `\"Correct!\"` Otherwise, you will receive a `\"Wrong answer\"` prompt.\n", 27 | " \n", 28 | " Good luck!\n", 29 | " ### Imports\n", 30 | " The cell below specifies the libraries you should use in this challenge. Run the cell to import the libraries. ***Do not modify the cell.***" 31 | ] 32 | }, 33 | { 34 | "cell_type": "code", 35 | "execution_count": null, 36 | "id": "592044df", 37 | "metadata": {}, 38 | "outputs": [], 39 | "source": [ 40 | "import json\n", 41 | "import pennylane as qml\n", 42 | "from pennylane import numpy as np" 43 | ] 44 | }, 45 | { 46 | "cell_type": "markdown", 47 | "id": "784cdade", 48 | "metadata": {}, 49 | "source": [ 50 | "### Code\n", 51 | " Complete the code below. Note that during QHack, some sections were not editable. We've marked those sections accordingly here, but you can still edit them if you wish." 52 | ] 53 | }, 54 | { 55 | "cell_type": "code", 56 | "execution_count": null, 57 | "id": "443c4b39", 58 | "metadata": {}, 59 | "outputs": [], 60 | "source": [ 61 | "# Put your code here #\n", 62 | "\n", 63 | "# Create a default.qubit device with 2 qubits / wires using qml.device\n", 64 | "\n", 65 | "# Turn your circuit into a QNode\n", 66 | "\n", 67 | "def circuit(angles):\n", 68 | " \"\"\"The quantum circuit that you will simulate.\n", 69 | "\n", 70 | " Args:\n", 71 | " angles (list(float)): The gate angles in the circuit.\n", 72 | "\n", 73 | " Returns:\n", 74 | " (numpy.tensor): \n", 75 | " The probability vector of the underlying quantum state that this circuit produces.\n", 76 | " \"\"\"\n", 77 | " # Put the rotation gates here\n", 78 | " return qml.probs(wires=[0, 1])" 79 | ] 80 | }, 81 | { 82 | "cell_type": "markdown", 83 | "id": "ccf83d90", 84 | "metadata": {}, 85 | "source": [ 86 | "These functions are responsible for testing the solution. You will need to run the cell below. ***Do not modify the cell.***" 87 | ] 88 | }, 89 | { 90 | "cell_type": "code", 91 | "execution_count": null, 92 | "id": "44bc4613", 93 | "metadata": {}, 94 | "outputs": [], 95 | "source": [ 96 | "def run(test_case_input: str) -> str:\n", 97 | " angles = json.loads(test_case_input)\n", 98 | " output = circuit(angles).tolist()\n", 99 | "\n", 100 | " return str(output)\n", 101 | "\n", 102 | "def check(solution_output: str, expected_output: str) -> None:\n", 103 | " solution_output = json.loads(solution_output)\n", 104 | " expected_output = json.loads(expected_output)\n", 105 | " assert np.allclose(solution_output, expected_output, rtol=1e-4)" 106 | ] 107 | }, 108 | { 109 | "cell_type": "markdown", 110 | "id": "2970bfac", 111 | "metadata": {}, 112 | "source": [ 113 | "### Test cases\n", 114 | " Running the cell below will load the test cases. ***Do not modify the cell***.\n", 115 | " - input: [1.23, 4.56]\n", 116 | " \t+ expected output: [0.2829251572359589, 0.3841937063262924, 0.1411749135148633, 0.19170622292288542]\n", 117 | " - input: [7.89, 0.12]\n", 118 | " \t+ expected output: [0.48026161094775754, 0.001733099740534947, 0.5161427069791756, 0.001862582332531926]" 119 | ] 120 | }, 121 | { 122 | "cell_type": "code", 123 | "execution_count": null, 124 | "id": "2284a1ea", 125 | "metadata": {}, 126 | "outputs": [], 127 | "source": [ 128 | "test_cases = [['[1.23, 4.56]', '[0.2829251572359589, 0.3841937063262924, 0.1411749135148633, 0.19170622292288542]'], ['[7.89, 0.12]', '[0.48026161094775754, 0.001733099740534947, 0.5161427069791756, 0.001862582332531926]']]" 129 | ] 130 | }, 131 | { 132 | "cell_type": "markdown", 133 | "id": "375a2b5c", 134 | "metadata": {}, 135 | "source": [ 136 | "### Solution testing\n", 137 | " Once you have run every cell above, including the one with your code, the cell below will test your solution. Run the cell. If you are correct for all of the test cases, it means your solutions is correct. Otherwise, you need to double check your work. ***Do not modify the cell below.***" 138 | ] 139 | }, 140 | { 141 | "cell_type": "code", 142 | "execution_count": null, 143 | "id": "780bb0ef", 144 | "metadata": {}, 145 | "outputs": [], 146 | "source": [ 147 | "for i, (input_, expected_output) in enumerate(test_cases):\n", 148 | " print(f\"Running test case {i} with input '{input_}'...\")\n", 149 | "\n", 150 | " try:\n", 151 | " output = run(input_)\n", 152 | "\n", 153 | " except Exception as exc:\n", 154 | " print(f\"Runtime Error. {exc}\")\n", 155 | "\n", 156 | " else:\n", 157 | " if message := check(output, expected_output):\n", 158 | " print(f\"Wrong Answer. Have: '{output}'. Want: '{expected_output}'.\")\n", 159 | "\n", 160 | " else:\n", 161 | " print(\"Correct!\")" 162 | ] 163 | } 164 | ], 165 | "metadata": {}, 166 | "nbformat": 4, 167 | "nbformat_minor": 5 168 | } 169 | -------------------------------------------------------------------------------- /tutorial_challenges/tutorial_2/images/daily2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/XanaduAI/qhack_2023_coding_challenges/efc516ac412dc351ae8bf9745e304717b81d1ff3/tutorial_challenges/tutorial_2/images/daily2.png -------------------------------------------------------------------------------- /tutorial_challenges/tutorial_3/README.md: -------------------------------------------------------------------------------- 1 | Welcome to the QHack 2023 tutorial challenges! These challenges are worth no points — they are specifically designed to get your brain active and into the right mindset for the competition. You will also learn about various aspects of PennyLane that are essential to quantum computing, quantum machine learning, and quantum chemistry. Have fun! 2 | 3 | ### Tutorial \#3 — Shor's 9-qubit-code 4 | 5 | Quantum computational advantage — the ability of quantum computers to perform certain tasks faster than the best classical computers — has now been demonstrated in a number of cases. 6 | Arguably, the next big milestone in quantum computing is *fault-tolerance* for large-scale devices, allowing them to correct errors that crop up as a result of noisy interactions with the environment or between parts of the computer. 7 | 8 | The early years of quantum error correction yielded several ground-breaking protocols, none more famous than Peter Shor's 9-qubit-code, pictured below. 9 | 10 |

11 | 12 |

13 | 14 | In this challenge, you will implement Shor's code for an arbitrary initial state $\vert \psi \rangle$ that is subject to an error. 15 | 16 | ## Challenge code 17 | 18 | In the notebook `a_shor_thing.ipynb`, you are given a couple functions: 19 | 20 | - `shor`: a QNode that contains the operations required to define Shor's code given an initial `state` and an `error` occuring in the middle of the circuit. It must output the expectation value of the Pauli Z operator on each qubit. **You must complete this function**. 21 | - `error`: this function contains the error operator that will be introduced into the circuit you create with `shor`. The possible errors are Pauli X, Y, and Z errors (see `error_dict`). To call this within `shor`, simply write `error(error_key, qubit)` and it will apply the error! 22 | 23 | Here are some helpful resources: 24 | 25 | - [Shor code](https://en.wikipedia.org/wiki/Quantum_error_correction#Shor_code) 26 | - [Quantum error correction](https://en.wikipedia.org/wiki/Quantum_error_correction) 27 | 28 | ### Input 29 | 30 | As input to this problem, you are given: 31 | 32 | - `state` (`list(float)`): defines the initial one-qubit state $\vert \psi \rangle$. The remaining 8 qubits are initialized in the $\vert 0 \rangle$ state. 33 | - `error_key` (`int`): an integer corresponding to a Pauli X, Y, or Z error. See `error_dict`. 34 | - `qubit` (`int`): an integer corresponding to which qubit the error will occur on. 35 | 36 | ### Output 37 | 38 | This code must output a `list(float)` corresponding to the expectation values of the Pauli Z operator on every qubit. 39 | 40 | If your solution matches the correct one within the given tolerance specified in `check` (in this case it's a `1e-4` relative error tolerance), the output will be `"Correct!"` Otherwise, you will receive a `"Wrong answer"` prompt. 41 | 42 | Good luck! 43 | -------------------------------------------------------------------------------- /tutorial_challenges/tutorial_3/a_shor_thing.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "id": "18263c72", 6 | "metadata": {}, 7 | "source": [ 8 | "## Challenge code\n", 9 | " \n", 10 | " In the code below, you are given a couple functions:\n", 11 | " \n", 12 | " - `shor`: a QNode that contains the operations required to define Shor's code given an initial `state` and an `error` occuring in the middle of the circuit. It must output the expectation value of the Pauli Z operator on each qubit. **You must complete this function**.\n", 13 | " - `error`: this function contains the error operator that will be introduced into the circuit you create with `shor`. The possible errors are Pauli X, Y, and Z errors (see `error_dict`). To call this within `shor`, simply write `error(error_key, qubit)` and it will apply the error!\n", 14 | " \n", 15 | " Here are some helpful resources:\n", 16 | " \n", 17 | " - [Shor code](https://en.wikipedia.org/wiki/Quantum_error_correction#Shor_code)\n", 18 | " - [Quantum error correction](https://en.wikipedia.org/wiki/Quantum_error_correction)\n", 19 | " \n", 20 | " ### Input \n", 21 | " \n", 22 | " As input to this problem, you are given:\n", 23 | " \n", 24 | " - `state` (`list(float)`): defines the initial one-qubit state $\\vert \\psi \\rangle$. The remaining 8 qubits are initialized in the $\\vert 0 \\rangle$ state.\n", 25 | " - `error_key` (`int`): an integer corresponding to a Pauli X, Y, or Z error. See `error_dict`.\n", 26 | " - `qubit` (`int`): an integer corresponding to which qubit the error will occur on.\n", 27 | " \n", 28 | " ### Output\n", 29 | " \n", 30 | " This code must output a `list(float)` corresponding to the expectation values of the Pauli Z operator on every qubit.\n", 31 | " \n", 32 | " If your solution matches the correct one within the given tolerance specified in `check` (in this case it's a `1e-4` relative error tolerance), the output will be `\"Correct!\"` Otherwise, you will receive a `\"Wrong answer\"` prompt.\n", 33 | " \n", 34 | " Good luck!\n", 35 | " ### Imports\n", 36 | " The cell below specifies the libraries you should use in this challenge. Run the cell to import the libraries. ***Do not modify the cell.***" 37 | ] 38 | }, 39 | { 40 | "cell_type": "code", 41 | "execution_count": null, 42 | "id": "c0dccc39", 43 | "metadata": {}, 44 | "outputs": [], 45 | "source": [ 46 | "import json\n", 47 | "import pennylane as qml\n", 48 | "from pennylane import numpy as np" 49 | ] 50 | }, 51 | { 52 | "cell_type": "markdown", 53 | "id": "93a4a266", 54 | "metadata": {}, 55 | "source": [ 56 | "### Code\n", 57 | " Complete the code below. Note that during QHack, some sections were not editable. We've marked those sections accordingly here, but you can still edit them if you wish." 58 | ] 59 | }, 60 | { 61 | "cell_type": "code", 62 | "execution_count": null, 63 | "id": "c8616eee", 64 | "metadata": {}, 65 | "outputs": [], 66 | "source": [ 67 | "# Uneditable section #\n", 68 | "n_qubits = 9\n", 69 | "dev = qml.device(\"default.qubit\", wires=n_qubits)\n", 70 | "error_dict = {0: 'PauliX', 1: 'PauliY', 2: 'PauliZ'}\n", 71 | "\n", 72 | "def error(error_key, qubit):\n", 73 | " \"\"\"Defines the error that is induced in the circuit.\n", 74 | "\n", 75 | " Args:\n", 76 | " error_key (int): An integer associated to the type of error (Pauli X, Y, or Z)\n", 77 | " qubit (int): The qubit that the error occurs on.\n", 78 | " \"\"\"\n", 79 | " getattr(qml, error_dict[error_key])(qubit)\n", 80 | "\n", 81 | "@qml.qnode(dev)\n", 82 | "def shor(state, error_key, qubit):\n", 83 | " \"\"\"A circuit defining Shor's code for error correction.\n", 84 | "\n", 85 | " Args:\n", 86 | " state (list(float)): The quantum state of the first qubit in the circuit.\n", 87 | " error_key (int): An integer associated to the type of error (Pauli X, Y, or Z)\n", 88 | " qubit (int): The qubit that the error occurs on.\n", 89 | "\n", 90 | " Returns:\n", 91 | " (list(float)): The expectation value of the Pauli Z operator on every qubit.\n", 92 | " \"\"\"\n", 93 | " qml.QubitStateVector(np.array(state), wires=0)\n", 94 | "\n", 95 | " # End of uneditable section #\n", 96 | "\n", 97 | " # Put your code here #" 98 | ] 99 | }, 100 | { 101 | "cell_type": "markdown", 102 | "id": "063ae44d", 103 | "metadata": {}, 104 | "source": [ 105 | "These functions are responsible for testing the solution. You will need to run the cell below. ***Do not modify the cell.***" 106 | ] 107 | }, 108 | { 109 | "cell_type": "code", 110 | "execution_count": null, 111 | "id": "8d5b9927", 112 | "metadata": {}, 113 | "outputs": [], 114 | "source": [ 115 | "def run(test_case_input: str) -> str:\n", 116 | " state, error_key, qubit = json.loads(test_case_input)\n", 117 | " output = shor(state, error_key, qubit).tolist()\n", 118 | "\n", 119 | " return str(output)\n", 120 | "\n", 121 | "def check(solution_output: str, expected_output: str) -> None:\n", 122 | " solution_output = json.loads(solution_output)\n", 123 | " expected_output = json.loads(expected_output)\n", 124 | "\n", 125 | " assert np.allclose(solution_output, expected_output, rtol=1e-4)" 126 | ] 127 | }, 128 | { 129 | "cell_type": "markdown", 130 | "id": "4022e2b3", 131 | "metadata": {}, 132 | "source": [ 133 | "### Test cases\n", 134 | " Running the cell below will load the test cases. ***Do not modify the cell***.\n", 135 | " - input: [[0, 1], 0, 3]\n", 136 | " \t+ expected output: [-1.0, 1.0, 1.0, 1.0, -1.0, -1.0, 1.0, 1.0, 1.0]\n", 137 | " - input: [[0.5, 0.8660254038], 2, 1]\n", 138 | " \t+ expected output: [-0.5, 1.0, 1.0, -1.0, 1.0, 1.0, -1.0, 1.0, 1.0]" 139 | ] 140 | }, 141 | { 142 | "cell_type": "code", 143 | "execution_count": null, 144 | "id": "69594cad", 145 | "metadata": {}, 146 | "outputs": [], 147 | "source": [ 148 | "test_cases = [['[[0, 1], 0, 3]', '[-1.0, 1.0, 1.0, 1.0, -1.0, -1.0, 1.0, 1.0, 1.0]'], ['[[0.5, 0.8660254038], 2, 1]', '[-0.5, 1.0, 1.0, -1.0, 1.0, 1.0, -1.0, 1.0, 1.0]']]" 149 | ] 150 | }, 151 | { 152 | "cell_type": "markdown", 153 | "id": "91d72bb9", 154 | "metadata": {}, 155 | "source": [ 156 | "### Solution testing\n", 157 | " Once you have run every cell above, including the one with your code, the cell below will test your solution. Run the cell. If you are correct for all of the test cases, it means your solutions is correct. Otherwise, you need to double check your work. ***Do not modify the cell below.***" 158 | ] 159 | }, 160 | { 161 | "cell_type": "code", 162 | "execution_count": null, 163 | "id": "01d82434", 164 | "metadata": {}, 165 | "outputs": [], 166 | "source": [ 167 | "for i, (input_, expected_output) in enumerate(test_cases):\n", 168 | " print(f\"Running test case {i} with input '{input_}'...\")\n", 169 | "\n", 170 | " try:\n", 171 | " output = run(input_)\n", 172 | "\n", 173 | " except Exception as exc:\n", 174 | " print(f\"Runtime Error. {exc}\")\n", 175 | "\n", 176 | " else:\n", 177 | " if message := check(output, expected_output):\n", 178 | " print(f\"Wrong Answer. Have: '{output}'. Want: '{expected_output}'.\")\n", 179 | "\n", 180 | " else:\n", 181 | " print(\"Correct!\")" 182 | ] 183 | } 184 | ], 185 | "metadata": {}, 186 | "nbformat": 4, 187 | "nbformat_minor": 5 188 | } 189 | -------------------------------------------------------------------------------- /tutorial_challenges/tutorial_3/images/daily3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/XanaduAI/qhack_2023_coding_challenges/efc516ac412dc351ae8bf9745e304717b81d1ff3/tutorial_challenges/tutorial_3/images/daily3.png -------------------------------------------------------------------------------- /tutorial_challenges/tutorial_4/README.md: -------------------------------------------------------------------------------- 1 | Welcome to the QHack 2023 tutorial challenges! These challenges are worth no points — they are specifically designed to get your brain active and into the right mindset for the competition. You will also learn about various aspects of PennyLane that are essential to quantum computing, quantum machine learning, and quantum chemistry. Have fun! 2 | 3 | ### Tutorial \#4 — Product states 4 | 5 | Entanglement is a quantum phenomenon that leads to unique statistical properties. We can harness it to do seemingly far-fetched tasks like quantum teleportation! 6 | 7 | Given a multi-qubit *pure* state (i.e., does not need to be described 8 | by a density operator), the presence of entanglement boils down to 9 | whether or not the state is a *product* state. Given a two-qubit state where the qubits are labelled by $A$ and $B$, a general *pure* quantum state can be written as 10 | 11 | $$ 12 | \vert \psi \rangle_{AB} = \sum_{i,j} c_{ij} \vert i \rangle_A \otimes \vert j \rangle_B . 13 | $$ 14 | 15 | $\vert \psi \rangle_{AB}$ is said to be a *product* state for subsystems 16 | $A$ and $B$ if it can be written as a tensor product 17 | 18 | $$ 19 | \vert \psi \rangle_{AB} = \vert \psi \rangle_A \otimes \vert \psi \rangle_B. 20 | $$ 21 | 22 | For example, the well-known Bell states cannot be written as product states 23 | between the two qubits. 24 | 25 | Your job is to create a function that can tell whether or not a pure state can 26 | be written as a product state between a subsystem and its complement (e.g., if 27 | $A$ is the subsystem, then $B = \bar{A}$, meaning that system $B$ is the set of qubits that are not in $A$). 28 | 29 | ## Challenge code 30 | 31 | In the notebook `product_management.ipynb`, you are given a function called `is_product`. This function will output `"yes"` or `"no"` correspondingly. **You must complete this function.** 32 | 33 | Here are some helpful resources: 34 | 35 | - [Separable quantum states](https://en.wikipedia.org/wiki/Separable_state) 36 | - [`qml.density_matrix`](https://docs.pennylane.ai/en/stable/code/api/pennylane.density_matrix.html) 37 | 38 | ### Input 39 | 40 | As input to this problem, you are given: 41 | 42 | - `state` (`list(float)`): this defines $\vert \psi \rangle_{AB}$ (pure quantum state in question). 43 | - `subsystem` (`list(int)`): the subsystem that defines the subsystem of qubits $A$ 44 | and $B = \bar{A}$. I.e., the two groups of qubits that you will 45 | determine if a state can be written as a product state. 46 | - `wires` (`list(int)`): the wire labels associated to the qubit state of interest. 47 | 48 | ### Output 49 | 50 | This code must output `"yes"` or `"no"` if the state $\vert \psi 51 | \rangle_{AB}$ is a product state (with respect to $A$ and $B$). 52 | 53 | If your solution matches the correct one, the output will be `"Correct!"` Otherwise, you will receive a `"Wrong answer"` prompt. 54 | 55 | Good luck! 56 | -------------------------------------------------------------------------------- /tutorial_challenges/tutorial_4/product_management.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "id": "a560ed12", 6 | "metadata": {}, 7 | "source": [ 8 | "## Challenge code\n", 9 | " \n", 10 | " In the code below, you are given a function called `is_product`. This function will output `\"yes\"` or `\"no\"` correspondingly. **You must complete this function.**\n", 11 | " \n", 12 | " Here are some helpful resources:\n", 13 | " \n", 14 | " - [Separable quantum states](https://en.wikipedia.org/wiki/Separable_state)\n", 15 | " - [`qml.density_matrix`](https://docs.pennylane.ai/en/stable/code/api/pennylane.density_matrix.html)\n", 16 | " \n", 17 | " ### Input \n", 18 | " \n", 19 | " As input to this problem, you are given:\n", 20 | " \n", 21 | " - `state` (`list(float)`): this defines $\\vert \\psi \\rangle_{AB}$ (pure quantum state in question).\n", 22 | " - `subsystem` (`list(int)`): the subsystem that defines the subsystem of qubits $A$ \n", 23 | " and $B = \\bar{A}$. I.e., the two groups of qubits that you will\n", 24 | " determine if a state can be written as a product state.\n", 25 | " - `wires` (`list(int)`): the wire labels associated to the qubit state of interest.\n", 26 | " \n", 27 | " ### Output\n", 28 | " \n", 29 | " This code must output `\"yes\"` or `\"no\"` if the state $\\vert \\psi\n", 30 | " \\rangle_{AB}$ is a product state (with respect to $A$ and $B$).\n", 31 | " \n", 32 | " If your solution matches the correct one, the output will be `\"Correct!\"` Otherwise, you will receive a `\"Wrong answer\"` prompt.\n", 33 | " \n", 34 | " Good luck!\n", 35 | " ### Imports\n", 36 | " The cell below specifies the libraries you should use in this challenge. Run the cell to import the libraries. ***Do not modify the cell.***" 37 | ] 38 | }, 39 | { 40 | "cell_type": "code", 41 | "execution_count": null, 42 | "id": "8e61d303", 43 | "metadata": {}, 44 | "outputs": [], 45 | "source": [ 46 | "import json\n", 47 | "import pennylane as qml\n", 48 | "from pennylane import numpy as np" 49 | ] 50 | }, 51 | { 52 | "cell_type": "markdown", 53 | "id": "6a625459", 54 | "metadata": {}, 55 | "source": [ 56 | "### Code\n", 57 | " Complete the code below. Note that during QHack, some sections were not editable. We've marked those sections accordingly here, but you can still edit them if you wish." 58 | ] 59 | }, 60 | { 61 | "cell_type": "code", 62 | "execution_count": null, 63 | "id": "fedf6496", 64 | "metadata": {}, 65 | "outputs": [], 66 | "source": [ 67 | "# Uneditable section #\n", 68 | "def is_product(state, subsystem, wires):\n", 69 | " \"\"\"Determines if a pure quantum state can be written as a product state between \n", 70 | " a subsystem of wires and their compliment.\n", 71 | "\n", 72 | " Args:\n", 73 | " state (numpy.array): The quantum state of interest.\n", 74 | " subsystem (list(int)): The subsystem used to determine if the state is a product state.\n", 75 | " wires (list(int)): The wire/qubit labels for the state. Use these for creating a QNode if you wish!\n", 76 | "\n", 77 | " Returns:\n", 78 | " (str): \"yes\" if the state is a product state or \"no\" if it isn't.\n", 79 | " \"\"\"\n", 80 | " # End of uneditable section #\n", 81 | "\n", 82 | " # Put your solution here #\n", 83 | " return" 84 | ] 85 | }, 86 | { 87 | "cell_type": "markdown", 88 | "id": "92a583cf", 89 | "metadata": {}, 90 | "source": [ 91 | "These functions are responsible for testing the solution. You will need to run the cell below. ***Do not modify the cell.***" 92 | ] 93 | }, 94 | { 95 | "cell_type": "code", 96 | "execution_count": null, 97 | "id": "8f429470", 98 | "metadata": {}, 99 | "outputs": [], 100 | "source": [ 101 | "def run(test_case_input: str) -> str:\n", 102 | " ins = json.loads(test_case_input)\n", 103 | " state, subsystem, wires = ins\n", 104 | " state = np.array(state)\n", 105 | " output = is_product(state, subsystem, wires)\n", 106 | " return output\n", 107 | "\n", 108 | "def check(solution_output: str, expected_output: str) -> None:\n", 109 | " assert solution_output == expected_output" 110 | ] 111 | }, 112 | { 113 | "cell_type": "markdown", 114 | "id": "f397dc47", 115 | "metadata": {}, 116 | "source": [ 117 | "### Test cases\n", 118 | " Running the cell below will load the test cases. ***Do not modify the cell***.\n", 119 | " - input: [[0.707107, 0, 0, 0.707107], [0], [0, 1]]\n", 120 | " \t+ expected output: no\n", 121 | " - input: [[1, 0, 0, 0], [0], [0, 1]]\n", 122 | " \t+ expected output: yes\n", 123 | " - input: [[0.01798476, 0.13092257, -0.02743221, 0.16026384, -0.11828744, 0.28561417, -0.33551182, 0.86484869], [0], [0, 1, 2]]\n", 124 | " \t+ expected output: no\n", 125 | " - input: [[0.5, 0.5, 0.5, 0.5, 0, 0, 0, 0], [1,2], [0, 1, 2]]\n", 126 | " \t+ expected output: yes\n", 127 | " - input: [[0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [2, 3, 0], [0, 1, 2, 3]]\n", 128 | " \t+ expected output: yes" 129 | ] 130 | }, 131 | { 132 | "cell_type": "code", 133 | "execution_count": null, 134 | "id": "89d0b930", 135 | "metadata": {}, 136 | "outputs": [], 137 | "source": [ 138 | "test_cases = [['[[0.707107, 0, 0, 0.707107], [0], [0, 1]]', 'no'], ['[[1, 0, 0, 0], [0], [0, 1]]', 'yes'], ['[[0.01798476, 0.13092257, -0.02743221, 0.16026384, -0.11828744, 0.28561417, -0.33551182, 0.86484869], [0], [0, 1, 2]]', 'no'], ['[[0.5, 0.5, 0.5, 0.5, 0, 0, 0, 0], [1,2], [0, 1, 2]]', 'yes'], ['[[0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [2, 3, 0], [0, 1, 2, 3]]', 'yes']]" 139 | ] 140 | }, 141 | { 142 | "cell_type": "markdown", 143 | "id": "55bcf390", 144 | "metadata": {}, 145 | "source": [ 146 | "### Solution testing\n", 147 | " Once you have run every cell above, including the one with your code, the cell below will test your solution. Run the cell. If you are correct for all of the test cases, it means your solutions is correct. Otherwise, you need to double check your work. ***Do not modify the cell below.***" 148 | ] 149 | }, 150 | { 151 | "cell_type": "code", 152 | "execution_count": null, 153 | "id": "b34c42ac", 154 | "metadata": {}, 155 | "outputs": [], 156 | "source": [ 157 | "for i, (input_, expected_output) in enumerate(test_cases):\n", 158 | " print(f\"Running test case {i} with input '{input_}'...\")\n", 159 | "\n", 160 | " try:\n", 161 | " output = run(input_)\n", 162 | "\n", 163 | " except Exception as exc:\n", 164 | " print(f\"Runtime Error. {exc}\")\n", 165 | "\n", 166 | " else:\n", 167 | " if message := check(output, expected_output):\n", 168 | " print(f\"Wrong Answer. Have: '{output}'. Want: '{expected_output}'.\")\n", 169 | "\n", 170 | " else:\n", 171 | " print(\"Correct!\")" 172 | ] 173 | } 174 | ], 175 | "metadata": {}, 176 | "nbformat": 4, 177 | "nbformat_minor": 5 178 | } 179 | -------------------------------------------------------------------------------- /tutorial_challenges/tutorial_5/README.md: -------------------------------------------------------------------------------- 1 | Welcome to the QHack 2023 tutorial challenges! These challenges are worth no points — they are specifically designed to get your brain active and into the right mindset for the competition. You will also learn about various aspects of PennyLane that are essential to quantum computing, quantum machine learning, and quantum chemistry. Have fun! 2 | 3 | ### Tutorial \#5 — Hi, Hydrogen! 4 | 5 | The Variational Quantum Eigensolver (VQE) algorithm has been touted as a game-changing near-term quantum algorithm. 6 | In particular, VQE is able to efficiently simulate low-energy properties of small molecules. 7 | In this challenge, you will calculate the energy of the hydrogen molecule for various molecular charges and bond length combinations. 8 | 9 |

10 | 11 |

12 | 13 | ## Challenge code 14 | 15 | In the notebook `hi_hydrogen.ipynb`, you are given a few functions: 16 | 17 | - `hydrogen_hamiltonian`: This function will return the qubit Hamiltonian of the hydrogen molecule given the `coordinates` of both hydrogen atoms and the net molecular `charge`. You'll usually find hydrogen molecules with a charge of 0, but here we'll spice it up with a non-zero charge! 18 | - `num_electrons`: In subsequent functions, we'll need the total number of electrons in the hydrogen molecule we're looking at. With a charge of 0, the hydrogen molecule usually has just 2 electrons, one per hydrogen atom. Given the `charge`, how many electrons should it have? ***You must complete this function.*** 19 | - `hf`: The "HF" stands for Hartree–Fock. This function's purpose is calculate the HF approximation — treat every electron as independent, electrons move under a Coulomb potential from the positively charged nuclei, and there's a mean field from the other electrons — for the ground state of the hydrogen molecule we're interested in. We'll use this later, so ***you must complete this function.*** 20 | - `run_VQE`: This function takes the `coordinates`, `charge`, generates the HF state, defines a `cost` function and minimizes it. ***You must complete this function*** by: 21 | + defining the gates within the `cost` function, using the [`qml.AllSinglesDoubles`](https://docs.pennylane.ai/en/stable/code/api/pennylane.AllSinglesDoubles.html) template with `singles` and `doubles` arguments defined below; and 22 | + returning what we want to minimize, namely the expectation value of the hydrogen Hamiltonian! 23 | 24 | Here are some helpful resources: 25 | 26 | - [Building molecular Hamiltonians](https://pennylane.ai/qml/demos/tutorial_quantum_chemistry.html) 27 | - [A brief overview of VQE](https://pennylane.ai/qml/demos/tutorial_vqe.html) 28 | - [Variational Quantum Eigensolver](https://youtu.be/4Xnxa6tzPeA) 29 | - [Quantum Chemistry documentation](https://docs.pennylane.ai/en/stable/introduction/chemistry.html) 30 | 31 | ### Input 32 | 33 | As input to this problem, you are given: 34 | 35 | - `coordinates` (`list(float)`): the $x$, $y$, and $z$ coordinates of each hydrogen atom 36 | - `charge` (`int`): the charge of the hydrogen molecule. It could be positive, negative, or zero! 37 | 38 | ### Output 39 | 40 | This code must output the ground state `energy` (`float`) of the hydrogen molecule in question. 41 | 42 | If your solution matches the correct one within the given tolerance specified in `check` (in this case it's a `1e-3` relative error tolerance), the output will be `"Correct!"` Otherwise, you will receive a `"Wrong answer"` prompt. 43 | 44 | Good luck! 45 | -------------------------------------------------------------------------------- /tutorial_challenges/tutorial_5/images/daily5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/XanaduAI/qhack_2023_coding_challenges/efc516ac412dc351ae8bf9745e304717b81d1ff3/tutorial_challenges/tutorial_5/images/daily5.png -------------------------------------------------------------------------------- /tutorial_challenges/tutorial_5/images/daily5_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/XanaduAI/qhack_2023_coding_challenges/efc516ac412dc351ae8bf9745e304717b81d1ff3/tutorial_challenges/tutorial_5/images/daily5_2.png -------------------------------------------------------------------------------- /tutorial_challenges/tutorial_6/README.md: -------------------------------------------------------------------------------- 1 | Welcome to the QHack 2023 tutorial challenges! These challenges are worth no points — they are specifically designed to get your brain active and into the right mindset for the competition. You will also learn about various aspects of PennyLane that are essential to quantum computing, quantum machine learning, and quantum chemistry. Have fun! 2 | 3 | ### Tutorial \#6 — Hamiltonians 4 | 5 | The Hamiltonian is the energy observable for a quantum system, and a 6 | quintessential component in many quantum algorithms. How do we implement Hamiltonians in PennyLane? You'll be tested on this in this challenge. 7 | 8 | You will be tasked with creating the Hamiltonian 9 | 10 | $$ 11 | H = \frac{1}{3} \sum_{i < j} X_i X_j - \sum_{i = 0}^{n-1} Z_i, 12 | $$ 13 | 14 | where $n$ is the number of qubits, $X_i$ and $Z_i$ are the familiar Pauli X and Z operators, respectively, and $\sum_{i < j}$ denotes a sum over all pairs (e.g. for $n = 3$, the pairs are (i, j) = (0, 1), (0, 2), (1, 2)). Note that we're indexing from 0! 15 | 16 | In this challenge, you need to create the following quantum circuit simulation that returns the expectation value of this Hamiltonian. 17 | 18 |

19 | 20 |

21 | 22 | To be clear, each wire represents $n$ qubits, and $\vert 0\rangle$ 23 | really means $\vert 0\rangle^{\otimes n}$, i.e. the $\vert 0\rangle$ 24 | state for each of these $n$ qubits. Also, be mindful that the $H$ gates 25 | represent the Hadamard gate, not the Hamiltonian (which is not unitary, 26 | in general)! 27 | 28 | ## Challenge code 29 | 30 | In the notebook `hamiltonian_sandwich.ipynb`, you must complete two functions: 31 | 32 | - `hamiltonian`: responsible for creating the Hamiltonian in question for a general number of qubits (`num_wires`). **You must complete this function**. 33 | - `expectation_value`: simulates the circuit in question and returns the expectation value of the Hamiltonian in question. **You must complete this function** by creating a QNode within this function that returns the expectation value of the Hamiltonian. 34 | 35 | Here are some helpful resources and hints: 36 | 37 | - The $X_i X_j$ term, mathematically, denotes a *tensor product* between the two Pauli-X operators. Here are some ways you can perform this in PennyLane: 38 | + use the `@` operator to take the tensor product between operators; 39 | + use [`qml.prod`](https://docs.pennylane.ai/en/stable/code/api/pennylane.prod.html). 40 | - [`qml.Hamiltonian`](https://docs.pennylane.ai/en/stable/code/api/pennylane.Hamiltonian.html) 41 | - [Operator arithmetic](https://pennylane.ai/blog/2022/08/pennylane-v025-released/#intuitive-operator-arithmetic) 42 | 43 | ### Input 44 | 45 | As input to this problem, you are given the number of qubits $n$, `num_wires` (`int`). 46 | 47 | ### Output 48 | 49 | This code must output the expectation value of the Hamiltonian (`float`). 50 | 51 | If your solution matches the correct one within the given tolerance specified in `check` (in this case it's a `1e-4` relative error tolerance), the output will be `"Correct!"` Otherwise, you will receive a `"Wrong answer"` prompt. 52 | 53 | Good luck! 54 | -------------------------------------------------------------------------------- /tutorial_challenges/tutorial_6/hamiltonian_sandwich.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "id": "e35db95a", 6 | "metadata": {}, 7 | "source": [ 8 | "## Challenge code\n", 9 | " \n", 10 | " In the code below, you must complete two functions:\n", 11 | " \n", 12 | " - `hamiltonian`: responsible for creating the Hamiltonian in question for a general number of qubits (`num_wires`). **You must complete this function**.\n", 13 | " - `expectation_value`: simulates the circuit in question and returns the expectation value of the Hamiltonian in question. **You must complete this function** by creating a QNode within this function that returns the expectation value of the Hamiltonian. \n", 14 | " \n", 15 | " Here are some helpful resources and hints:\n", 16 | " \n", 17 | " - The $X_i X_j$ term, mathematically, denotes a *tensor product* between the two Pauli-X operators. Here are some ways you can perform this in PennyLane:\n", 18 | " + use the `@` operator to take the tensor product between operators;\n", 19 | " + use [`qml.prod`](https://docs.pennylane.ai/en/stable/code/api/pennylane.prod.html).\n", 20 | " - [`qml.Hamiltonian`](https://docs.pennylane.ai/en/stable/code/api/pennylane.Hamiltonian.html)\n", 21 | " - [Operator arithmetic](https://pennylane.ai/blog/2022/08/pennylane-v025-released/#intuitive-operator-arithmetic)\n", 22 | " \n", 23 | " ### Input \n", 24 | " \n", 25 | " As input to this problem, you are given the number of qubits $n$, `num_wires` (`int`).\n", 26 | " \n", 27 | " ### Output\n", 28 | " \n", 29 | " This code must output the expectation value of the Hamiltonian (`float`).\n", 30 | " \n", 31 | " If your solution matches the correct one within the given tolerance specified in `check` (in this case it's a `1e-4` relative error tolerance), the output will be `\"Correct!\"` Otherwise, you will receive a `\"Wrong answer\"` prompt.\n", 32 | " \n", 33 | " Good luck!\n", 34 | " ### Imports\n", 35 | " The cell below specifies the libraries you should use in this challenge. Run the cell to import the libraries. ***Do not modify the cell.***" 36 | ] 37 | }, 38 | { 39 | "cell_type": "code", 40 | "execution_count": null, 41 | "id": "b2c6df33", 42 | "metadata": {}, 43 | "outputs": [], 44 | "source": [ 45 | "import json\n", 46 | "import pennylane as qml\n", 47 | "from pennylane import numpy as np" 48 | ] 49 | }, 50 | { 51 | "cell_type": "markdown", 52 | "id": "90f2ca9c", 53 | "metadata": {}, 54 | "source": [ 55 | "### Code\n", 56 | " Complete the code below. Note that during QHack, some sections were not editable. We've marked those sections accordingly here, but you can still edit them if you wish." 57 | ] 58 | }, 59 | { 60 | "cell_type": "code", 61 | "execution_count": null, 62 | "id": "0a60bb9e", 63 | "metadata": {}, 64 | "outputs": [], 65 | "source": [ 66 | "# Uneditable section #\n", 67 | "def hamiltonian(num_wires):\n", 68 | " \"\"\"A function for creating the Hamiltonian in question for a general\n", 69 | " number of qubits.\n", 70 | "\n", 71 | " Args:\n", 72 | " num_wires (int): The number of qubits.\n", 73 | "\n", 74 | " Returns:\n", 75 | " (qml.Hamiltonian): A PennyLane Hamiltonian.\n", 76 | " \"\"\"\n", 77 | " # End of uneditable section #\n", 78 | "\n", 79 | " # Put your solution here #\n", 80 | " return\n", 81 | "\n", 82 | "# Uneditable section #\n", 83 | "def expectation_value(num_wires):\n", 84 | " \"\"\"Simulates the circuit in question and returns the expectation value of the \n", 85 | " Hamiltonian in question.\n", 86 | "\n", 87 | " Args:\n", 88 | " num_wires (int): The number of qubits.\n", 89 | "\n", 90 | " Returns:\n", 91 | " (float): The expectation value of the Hamiltonian.\n", 92 | " \"\"\"\n", 93 | " # End of uneditable section #\n", 94 | "\n", 95 | " # Put your solution here #\n", 96 | "\n", 97 | " # Define a device using qml.device\n", 98 | " dev =\n", 99 | "\n", 100 | "\n", 101 | " # Uneditable section #\n", 102 | " @qml.qnode(dev)\n", 103 | " def circuit(num_wires):\n", 104 | " \"\"\"A quantum circuit with Hadamard gates on every qubit and that measures\n", 105 | " the expectation value of the Hamiltonian in question. \n", 106 | " \"\"\"\n", 107 | "\n", 108 | " # End of uneditable section #\n", 109 | "\n", 110 | " # Put Hadamard gates here #\n", 111 | "\n", 112 | " # Then return the expectation value of the Hamiltonian using qml.expval\n", 113 | " return\n", 114 | " \n", 115 | " # Uneditable section #\n", 116 | " return circuit(num_wires)" 117 | ] 118 | }, 119 | { 120 | "cell_type": "markdown", 121 | "id": "b6c42842", 122 | "metadata": {}, 123 | "source": [ 124 | "These functions are responsible for testing the solution. You will need to run the cell below. ***Do not modify the cell.***" 125 | ] 126 | }, 127 | { 128 | "cell_type": "code", 129 | "execution_count": null, 130 | "id": "a278ee1c", 131 | "metadata": {}, 132 | "outputs": [], 133 | "source": [ 134 | "def run(test_case_input: str) -> str:\n", 135 | " num_wires = json.loads(test_case_input)\n", 136 | " output = expectation_value(num_wires)\n", 137 | "\n", 138 | " return str(output)\n", 139 | "\n", 140 | "def check(solution_output: str, expected_output: str) -> None:\n", 141 | " solution_output = json.loads(solution_output)\n", 142 | " expected_output = json.loads(expected_output)\n", 143 | " assert np.allclose(solution_output, expected_output, rtol=1e-4)" 144 | ] 145 | }, 146 | { 147 | "cell_type": "markdown", 148 | "id": "5f1ab603", 149 | "metadata": {}, 150 | "source": [ 151 | "### Test cases\n", 152 | " Running the cell below will load the test cases. ***Do not modify the cell***.\n", 153 | " - input: 8\n", 154 | " \t+ expected output: 9.33333\n", 155 | " - input: 5\n", 156 | " \t+ expected output: 3.33333" 157 | ] 158 | }, 159 | { 160 | "cell_type": "code", 161 | "execution_count": null, 162 | "id": "caec947d", 163 | "metadata": {}, 164 | "outputs": [], 165 | "source": [ 166 | "test_cases = [['8', '9.33333'], ['5', '3.33333']]" 167 | ] 168 | }, 169 | { 170 | "cell_type": "markdown", 171 | "id": "bd33f0b7", 172 | "metadata": {}, 173 | "source": [ 174 | "### Solution testing\n", 175 | " Once you have run every cell above, including the one with your code, the cell below will test your solution. Run the cell. If you are correct for all of the test cases, it means your solutions is correct. Otherwise, you need to double check your work. ***Do not modify the cell below.***" 176 | ] 177 | }, 178 | { 179 | "cell_type": "code", 180 | "execution_count": null, 181 | "id": "2386cb75", 182 | "metadata": {}, 183 | "outputs": [], 184 | "source": [ 185 | "for i, (input_, expected_output) in enumerate(test_cases):\n", 186 | " print(f\"Running test case {i} with input '{input_}'...\")\n", 187 | "\n", 188 | " try:\n", 189 | " output = run(input_)\n", 190 | "\n", 191 | " except Exception as exc:\n", 192 | " print(f\"Runtime Error. {exc}\")\n", 193 | "\n", 194 | " else:\n", 195 | " if message := check(output, expected_output):\n", 196 | " print(f\"Wrong Answer. Have: '{output}'. Want: '{expected_output}'.\")\n", 197 | "\n", 198 | " else:\n", 199 | " print(\"Correct!\")" 200 | ] 201 | } 202 | ], 203 | "metadata": {}, 204 | "nbformat": 4, 205 | "nbformat_minor": 5 206 | } 207 | -------------------------------------------------------------------------------- /tutorial_challenges/tutorial_6/images/daily6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/XanaduAI/qhack_2023_coding_challenges/efc516ac412dc351ae8bf9745e304717b81d1ff3/tutorial_challenges/tutorial_6/images/daily6.png -------------------------------------------------------------------------------- /tutorial_challenges/tutorial_7/README.md: -------------------------------------------------------------------------------- 1 | Welcome to the QHack 2023 tutorial challenges! These challenges are worth no points — they are specifically designed to get your brain active and into the right mindset for the competition. You will also learn about various aspects of PennyLane that are essential to quantum computing, quantum machine learning, and quantum chemistry. Have fun! 2 | 3 | ### Tutorial \#7 — Quantum machine learning 4 | 5 | Quantum machine learning is an area of research that explores the interplay between quantum computing and machine learning. Quantum machine learning models might offer significant speedups for performing certain tasks like classification, image processing, and regression. 6 | 7 | In this challenge, you'll learn the meat and potatoes of training a quantum machine learning model. Specifically, you will implement a procedure for embedding classical numbers into a quantum computer, construct a simple quantum machine learning model, and perform three optimization steps. The quantum circuit in the model that you will implement looks like this: 8 | 9 |

10 | 11 |

12 | 13 | ## Challenge code 14 | 15 | In the notebook `optimize_this.ipynb`, you must complete the following functions: 16 | 17 | - `three_optimization_steps`: performs three optimization steps. **You must complete this function**. 18 | - `cost`: this is within the `three_optimization_steps` function. **You must complete this function**. `cost` is a QNode that does a few things: 19 | + acts on 3 qubits only; 20 | + embeds the input `data` via [amplitude embedding](https://docs.pennylane.ai/en/stable/code/api/pennylane.AmplitudeEmbedding.html); 21 | + defines some differentiable gates via a template called [qml.BasicEntanglerLayers](https://docs.pennylane.ai/en/stable/code/api/pennylane.BasicEntanglerLayers.html); and 22 | + returns the expectation value of the sum of the Pauli Z operator on all $n$ qubits: 23 | 24 | $$ 25 | \sum_{i = 1}^n Z_i. 26 | $$ 27 | 28 | Within the `three_optimization_steps` function is a variable called `weights`. These are the changeable parameters that help define the `qml.BasicEntanglerLayers` template that you must put in the `cost` function. `weights` are the parameters that will be optimized (and need to be referred to by this name due to the final call `return cost(weights, data=data)`, which cannot be edited). 29 | 30 | To perform three optimization steps, use a gradient decent optimizer — `qml.GradientDescentOptimizer` — with a step size of $0.01$. 31 | 32 | Here are some helpful resources: 33 | 34 | - [Optimizing a quantum circuit — YouTube video](https://youtu.be/TiQ7T1h8VAQ) 35 | - [Basic tutorial: qubit rotation — Optimization](https://pennylane.ai/qml/demos/tutorial_qubit_rotation.html#optimization) 36 | 37 | ### Input 38 | 39 | As input to this problem, you are given classical `data` (`list(float)`) that you must embed into a quantum circuit via [amplitude embedding](https://docs.pennylane.ai/en/stable/code/api/pennylane.AmplitudeEmbedding.html). 40 | 41 | ### Output 42 | 43 | This code must output the evaluation of `cost` after three optimization steps have been performed. 44 | 45 | If your solution matches the correct one within the given tolerance specified in `check` (in this case it's a `1e-4` relative error tolerance), the output will be `"Correct!"` Otherwise, you will receive a `"Wrong answer"` prompt. 46 | 47 | Good luck! 48 | -------------------------------------------------------------------------------- /tutorial_challenges/tutorial_7/images/daily7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/XanaduAI/qhack_2023_coding_challenges/efc516ac412dc351ae8bf9745e304717b81d1ff3/tutorial_challenges/tutorial_7/images/daily7.png -------------------------------------------------------------------------------- /tutorial_challenges/tutorial_8/README.md: -------------------------------------------------------------------------------- 1 | Welcome to the QHack 2023 tutorial challenges! These challenges are worth no points — they are specifically designed to get your brain active and into the right mindset for the competition. You will also learn about various aspects of PennyLane that are essential to quantum computing, quantum machine learning, and quantum chemistry. Have fun! 2 | 3 | ### Tutorial \#8 — Mid-circuit measurements 4 | 5 | In classical computations, inserting control flow — e.g, `if` statements — right 6 | in the middle of a large computation is no problem at all since measuring variables 7 | does not affect the output of the computation. The same can't be said about quantum 8 | computations — if we measure, we better be careful! 9 | 10 | In this challenge, you'll look at how mid-circuit measurements work in PennyLane. 11 | 12 | ## Challenge code 13 | 14 | In the notebook `stuck_in_the_middle_with_u.ipynb`, you are given a function called `circuit`. **You must complete 15 | this function** by constructing the following four-qubit circuit: 16 | 17 |

18 | 19 |

20 | 21 | The circuit has a Hadamard gate on every qubit, an $R_x$ gate, a couple of 22 | CNOTs, and then the mid-circuit measurements. Note here that the measurements happen 23 | on the first and third qubits, and that the [`qml.U3`](https://docs.pennylane.ai/en/stable/code/api/pennylane.U3.html) gate is only applied to the 24 | fourth qubit if the following condition is met upon measuring the first and third 25 | wires: $m_0 + m_2 \geq 1$ (i.e. at least one of them is $1$). The last operator, `qml.PauliZ` on the fourth qubit, is 26 | applied regardless. 27 | 28 | The [`qml.measure`](https://docs.pennylane.ai/en/stable/code/api/pennylane.measure.html) 29 | function should be helpful to you! 30 | 31 | ### Input 32 | 33 | As input to this problem, you are given: 34 | 35 | - `angles` (`list(float)`): a list of angles containing $\theta_0$, $\theta_1$, $\theta_2$, and $\theta_3$ in that order. Use this to create the circuit! 36 | 37 | ### Output 38 | 39 | This code must output a `numpy.tensor` containing the probabilities associated to a computational basis measurement **on the fourth qubit.** 40 | 41 | If your solution matches the correct one within the given tolerance specified in `check` (in this case it's a `1e-4` relative error tolerance), the output will be `"Correct!"` Otherwise, you will receive a `"Wrong answer"` prompt. 42 | 43 | Good luck! 44 | -------------------------------------------------------------------------------- /tutorial_challenges/tutorial_8/images/daily8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/XanaduAI/qhack_2023_coding_challenges/efc516ac412dc351ae8bf9745e304717b81d1ff3/tutorial_challenges/tutorial_8/images/daily8.png -------------------------------------------------------------------------------- /tutorial_challenges/tutorial_8/stuck_in_the_middle_with_u.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "id": "f729dcfc", 6 | "metadata": {}, 7 | "source": [ 8 | "## Challenge code\n", 9 | " \n", 10 | " In the code below, you are given a function called `circuit`. **You must complete \n", 11 | " this function** by constructing the following four-qubit circuit:\n", 12 | " \n", 13 | "

\n", 14 | " \n", 15 | "

\n", 16 | " \n", 17 | " The circuit has a Hadamard gate on every qubit, an $R_x$ gate, a couple of \n", 18 | " CNOTs, and then the mid-circuit measurements. Note here that the measurements happen \n", 19 | " on the first and third qubits, and that the [`qml.U3`](https://docs.pennylane.ai/en/stable/code/api/pennylane.U3.html) gate is only applied to the \n", 20 | " fourth qubit if the following condition is met upon measuring the first and third \n", 21 | " wires: $m_0 + m_2 \\geq 1$ (i.e. at least one of them is $1$). The last operator, `qml.PauliZ` on the fourth qubit, is \n", 22 | " applied regardless.\n", 23 | " \n", 24 | " The [`qml.measure`](https://docs.pennylane.ai/en/stable/code/api/pennylane.measure.html) \n", 25 | " function should be helpful to you!\n", 26 | " \n", 27 | " ### Input \n", 28 | " \n", 29 | " As input to this problem, you are given:\n", 30 | " \n", 31 | " - `angles` (`list(float)`): a list of angles containing $\\theta_0$, $\\theta_1$, $\\theta_2$, and $\\theta_3$ in that order. Use this to create the circuit!\n", 32 | " \n", 33 | " ### Output\n", 34 | " \n", 35 | " This code must output a `numpy.tensor` containing the probabilities associated to a computational basis measurement **on the fourth qubit.**\n", 36 | " \n", 37 | " If your solution matches the correct one within the given tolerance specified in `check` (in this case it's a `1e-4` relative error tolerance), the output will be `\"Correct!\"` Otherwise, you will receive a `\"Wrong answer\"` prompt.\n", 38 | " \n", 39 | " Good luck!\n", 40 | " ### Imports\n", 41 | " The cell below specifies the libraries you should use in this challenge. Run the cell to import the libraries. ***Do not modify the cell.***" 42 | ] 43 | }, 44 | { 45 | "cell_type": "code", 46 | "execution_count": null, 47 | "id": "00c08bf9", 48 | "metadata": {}, 49 | "outputs": [], 50 | "source": [ 51 | "import json\n", 52 | "import pennylane as qml\n", 53 | "from pennylane import numpy as np" 54 | ] 55 | }, 56 | { 57 | "cell_type": "markdown", 58 | "id": "8ea1aecb", 59 | "metadata": {}, 60 | "source": [ 61 | "### Code\n", 62 | " Complete the code below. Note that during QHack, some sections were not editable. We've marked those sections accordingly here, but you can still edit them if you wish." 63 | ] 64 | }, 65 | { 66 | "cell_type": "code", 67 | "execution_count": null, 68 | "id": "eff42708", 69 | "metadata": {}, 70 | "outputs": [], 71 | "source": [ 72 | "# Uneditable section #\n", 73 | "n_qubits = 4\n", 74 | "dev = qml.device(\"default.qubit\", wires=n_qubits)\n", 75 | "\n", 76 | "@qml.qnode(dev)\n", 77 | "def circuit(angles):\n", 78 | " \"\"\"A quantum circuit made from the quantum function U.\n", 79 | "\n", 80 | " Args:\n", 81 | " angles (list(float)): A list of angles containing theta_0, theta_1, theta_2, and theta_3 in that order. \n", 82 | " Returns:\n", 83 | " (numpy.tensor): The probability of the fourth qubit.\n", 84 | " \"\"\"\n", 85 | " # End of uneditable section #\n", 86 | "\n", 87 | " # Put your code here #\n", 88 | " \n", 89 | " # Uneditable section #\n", 90 | " return qml.probs(wires=3)" 91 | ] 92 | }, 93 | { 94 | "cell_type": "markdown", 95 | "id": "60a10739", 96 | "metadata": {}, 97 | "source": [ 98 | "These functions are responsible for testing the solution. You will need to run the cell below. ***Do not modify the cell.***" 99 | ] 100 | }, 101 | { 102 | "cell_type": "code", 103 | "execution_count": null, 104 | "id": "1f80dd77", 105 | "metadata": {}, 106 | "outputs": [], 107 | "source": [ 108 | "def run(test_case_input: str) -> str:\n", 109 | " angles = json.loads(test_case_input)\n", 110 | " output = circuit(angles).tolist()\n", 111 | " return str(output)\n", 112 | "\n", 113 | "def check(solution_output: str, expected_output: str) -> None:\n", 114 | " solution_output = json.loads(solution_output)\n", 115 | " expected_output = json.loads(expected_output)\n", 116 | "\n", 117 | " assert np.allclose(solution_output, expected_output, rtol=1e-4)" 118 | ] 119 | }, 120 | { 121 | "cell_type": "markdown", 122 | "id": "f11a9c4a", 123 | "metadata": {}, 124 | "source": [ 125 | "### Test cases\n", 126 | " Running the cell below will load the test cases. ***Do not modify the cell***.\n", 127 | " - input: [1.0, 1.5, 2.0, 2.5]\n", 128 | " \t+ expected output: [0.79967628, 0.20032372]\n", 129 | " - input: [1.0, 1.1, 2.2, 1.5]\n", 130 | " \t+ expected output: [0.47635943, 0.52364057]\n", 131 | " - input: [5.1, 6.1, 0.2, 2.5]\n", 132 | " \t+ expected output: [0.44527313, 0.55472687]" 133 | ] 134 | }, 135 | { 136 | "cell_type": "code", 137 | "execution_count": null, 138 | "id": "1520d1be", 139 | "metadata": {}, 140 | "outputs": [], 141 | "source": [ 142 | "test_cases = [['[1.0, 1.5, 2.0, 2.5]', '[0.79967628, 0.20032372]'], ['[1.0, 1.1, 2.2, 1.5]', '[0.47635943, 0.52364057]'], ['[5.1, 6.1, 0.2, 2.5]', '[0.44527313, 0.55472687]']]" 143 | ] 144 | }, 145 | { 146 | "cell_type": "markdown", 147 | "id": "4c5a7e22", 148 | "metadata": {}, 149 | "source": [ 150 | "### Solution testing\n", 151 | " Once you have run every cell above, including the one with your code, the cell below will test your solution. Run the cell. If you are correct for all of the test cases, it means your solutions is correct. Otherwise, you need to double check your work. ***Do not modify the cell below.***" 152 | ] 153 | }, 154 | { 155 | "cell_type": "code", 156 | "execution_count": null, 157 | "id": "d1feb2b9", 158 | "metadata": {}, 159 | "outputs": [], 160 | "source": [ 161 | "for i, (input_, expected_output) in enumerate(test_cases):\n", 162 | " print(f\"Running test case {i} with input '{input_}'...\")\n", 163 | "\n", 164 | " try:\n", 165 | " output = run(input_)\n", 166 | "\n", 167 | " except Exception as exc:\n", 168 | " print(f\"Runtime Error. {exc}\")\n", 169 | "\n", 170 | " else:\n", 171 | " if message := check(output, expected_output):\n", 172 | " print(f\"Wrong Answer. Have: '{output}'. Want: '{expected_output}'.\")\n", 173 | "\n", 174 | " else:\n", 175 | " print(\"Correct!\")" 176 | ] 177 | } 178 | ], 179 | "metadata": {}, 180 | "nbformat": 4, 181 | "nbformat_minor": 5 182 | } 183 | --------------------------------------------------------------------------------