From dc5562b5fc058c66347da6ba1f27ab20ddd1eec3 Mon Sep 17 00:00:00 2001 From: Mine Starks Date: Fri, 29 May 2026 22:26:33 +0000 Subject: [PATCH 1/3] Use structured :::hint markers in katas content --- .../complex_arithmetic/cartesian_to_polar/index.md | 7 ++----- .../complex_arithmetic/complex_addition/index.md | 6 ++---- .../complex_arithmetic/complex_conjugate/index.md | 7 ++----- .../complex_arithmetic/complex_division/index.md | 7 ++----- .../complex_arithmetic/complex_exponents/index.md | 7 +++---- .../complex_arithmetic/complex_modulus/index.md | 9 +++------ .../complex_multiplication/index.md | 7 ++----- .../complex_powers_real/index.md | 7 +++---- .../polar_multiplication/index.md | 8 +++----- .../complex_arithmetic/polar_to_cartesian/index.md | 7 ++----- .../deutsch_algo/one_minus_x_oracle/index.md | 5 ++--- katas/content/deutsch_jozsa/parity_oracle/index.md | 5 ++--- katas/content/getting_started/flip_qubit/index.md | 5 ++--- katas/content/grovers_search/phase_oracle/index.md | 7 +++---- katas/content/linear_algebra/inverse/index.md | 7 ++----- katas/content/marking_oracles/parity/index.md | 5 ++--- .../marking_oracles/product_negation/index.md | 5 ++--- .../multi_qubit_gates/arbitrary_controls/index.md | 7 +++---- .../multi_qubit_gates/compound_gate/index.md | 7 +++---- .../multi_qubit_gates/controlled_rotation/index.md | 7 +++---- .../state_preparation/index.md | 7 +++---- .../learn_basis_state_amplitudes/index.md | 7 +++---- .../prepare_superposition/index.md | 7 +++---- .../prepare_with_complex/index.md | 7 +++---- .../multi_qubit_systems/prepare_with_real/index.md | 7 +++---- .../content/oracles/bit_pattern_challenge/index.md | 7 +++---- katas/content/oracles/bit_pattern_oracle/index.md | 7 +++---- .../oracles/marking_oracle_as_phase/index.md | 7 +++---- katas/content/oracles/or_but_kth_oracle/index.md | 11 +++++------ katas/content/oracles/or_oracle/index.md | 7 +++---- katas/content/oracles/phase_oracle_seven/index.md | 7 +++---- .../phase_estimation/one_bit_eigenphase/index.md | 2 +- .../phase_estimation/state_eigenvector/index.md | 2 +- .../even_sup_two_qubits_complex_phases/index.md | 7 +++---- .../preparing_states/parity_bitstrings/index.md | 7 +++---- katas/content/preparing_states/plus_state/index.md | 7 +++---- .../unequal_superposition/index.md | 7 +++---- .../preparing_states/wstate_arbitrary/index.md | 7 +++---- .../preparing_states/wstate_power_of_two/index.md | 7 +++---- katas/content/qft/all_even_vectors/index.md | 7 +++---- katas/content/qft/binary_fraction_inplace/index.md | 6 ++---- katas/content/qft/qft/index.md | 6 ++---- .../qubit/learn_single_qubit_state/index.md | 7 +++---- katas/content/random_numbers/random_bit/index.md | 14 ++++++-------- .../content/random_numbers/random_n_bits/index.md | 7 +++---- .../random_numbers/random_two_bits/index.md | 7 +++---- .../a_b_basis_measurements/index.md | 7 +++---- .../distinguish_orthogonal_states_1/index.md | 5 ++--- .../distinguish_orthogonal_states_2/index.md | 7 +++---- source/npm/qsharp/generate_katas_content.js | 3 +-- 50 files changed, 134 insertions(+), 201 deletions(-) diff --git a/katas/content/complex_arithmetic/cartesian_to_polar/index.md b/katas/content/complex_arithmetic/cartesian_to_polar/index.md index ab7996150a..cfcc2971d0 100644 --- a/katas/content/complex_arithmetic/cartesian_to_polar/index.md +++ b/katas/content/complex_arithmetic/cartesian_to_polar/index.md @@ -7,13 +7,10 @@ Return the polar representation of $x = re^{i\theta}$, that is, the distance fro * $r$ should be non-negative: $r \geq 0$ * $\theta$ should be between $-\pi$ and $\pi$: $-\pi < \theta \leq \pi$ -
- Need a hint? - +:::hint A video explanation of this conversion can be found [here](https://www.youtube.com/watch?v=8RasCV_Lggg). Q# namespace `Std.Math` includes a useful function `ArcTan2()`. - -
+::: > Q# function `ComplexAsComplexPolar` from `Std.Math` namespace converts a complex number of type `Complex` to a complex number of type `ComplexPolar`. For educational purposes, try to do this task by hand. diff --git a/katas/content/complex_arithmetic/complex_addition/index.md b/katas/content/complex_arithmetic/complex_addition/index.md index 5500a51ef6..aacd5197a3 100644 --- a/katas/content/complex_arithmetic/complex_addition/index.md +++ b/katas/content/complex_arithmetic/complex_addition/index.md @@ -6,12 +6,10 @@ **Goal:** Return the sum of $x$ and $y$ as a complex number. -
- Need a hint? - +:::hint Adding complex numbers is just like adding polynomials. Add components of the same type - add the real part to the real part, add the imaginary part to the imaginary part. A video explanation of adding complex numbers can be found [here](https://www.youtube.com/watch?v=SfbjqVyQljk). -
+::: > Q# function `PlusC` from `Std.Math` namespace adds two complex numbers. For educational purposes, try to do this task by hand. diff --git a/katas/content/complex_arithmetic/complex_conjugate/index.md b/katas/content/complex_arithmetic/complex_conjugate/index.md index 58a7e13611..98936898f4 100644 --- a/katas/content/complex_arithmetic/complex_conjugate/index.md +++ b/katas/content/complex_arithmetic/complex_conjugate/index.md @@ -4,9 +4,6 @@ A complex number $x = a + bi$. **Goal:** Return the complex conjugate of $x$ $\overline{x} = a - bi$. -
- Need a hint? - +:::hint A video explanation of the complex conjugate can be found [here](https://www.youtube.com/watch?v=BZxZ_eEuJBM). - -
+::: diff --git a/katas/content/complex_arithmetic/complex_division/index.md b/katas/content/complex_arithmetic/complex_division/index.md index ee1f04f516..fef78d7063 100644 --- a/katas/content/complex_arithmetic/complex_division/index.md +++ b/katas/content/complex_arithmetic/complex_division/index.md @@ -5,11 +5,8 @@ **Goal:** Return the result of the division $\frac{x}{y} = \frac{a + bi}{c + di}$. -
- Need a hint? - +:::hint A video explanation of complex division can be found [here](https://www.youtube.com/watch?v=Z8j5RDOibV4). - -
+::: > Q# function `DividedByC` from `Std.Math` namespace divides two complex numbers. For educational purposes, try to do this task by hand. diff --git a/katas/content/complex_arithmetic/complex_exponents/index.md b/katas/content/complex_arithmetic/complex_exponents/index.md index 600b7b62e4..15c9a64057 100644 --- a/katas/content/complex_arithmetic/complex_exponents/index.md +++ b/katas/content/complex_arithmetic/complex_exponents/index.md @@ -2,7 +2,6 @@ **Goal:** Return the complex number $e^x = e^{a + bi}$. -
- Need a hint? - Q# namespace Std.Math includes a function E() that returns the value of the constant $e$. -
+:::hint +Q# namespace Std.Math includes a function E() that returns the value of the constant $e$. +::: diff --git a/katas/content/complex_arithmetic/complex_modulus/index.md b/katas/content/complex_arithmetic/complex_modulus/index.md index 4bf8565163..3dd8847079 100644 --- a/katas/content/complex_arithmetic/complex_modulus/index.md +++ b/katas/content/complex_arithmetic/complex_modulus/index.md @@ -2,11 +2,8 @@ **Goal:** Return the modulus of this number, $|x|$. -
- Need a hint? - - A video explanation of absolute value and complex numbers can be found [here](https://www.youtube.com/watch?v=FwuPXchH2rA). - -
+:::hint +A video explanation of absolute value and complex numbers can be found [here](https://www.youtube.com/watch?v=FwuPXchH2rA). +::: > Q# function `AbsComplex` from `Std.Math` namespace gets the absolute value of a complex number. For educational purposes, try to do this task by hand. diff --git a/katas/content/complex_arithmetic/complex_multiplication/index.md b/katas/content/complex_arithmetic/complex_multiplication/index.md index a30bdcfccf..ecab5d1b4d 100644 --- a/katas/content/complex_arithmetic/complex_multiplication/index.md +++ b/katas/content/complex_arithmetic/complex_multiplication/index.md @@ -6,15 +6,12 @@ **Goal:** Return the product of $x$ and $y$ as a complex number. -
- Need a hint? - +:::hint Multiplying complex numbers is just like multiplying polynomials. Distribute one of the complex numbers: $$(a + bi)(c + di) = a(c + di) + bi(c + di)$$ Then multiply through, keeping in mind that $i^2=-1$, and group the real and imaginary terms together. A video explanation of multiplying complex numbers can be found [here](https://www.youtube.com/watch?v=cWn6g8Qqvs4). - -
+::: > Q# function `TimesC` from `Std.Math` namespace multiplies two complex numbers. For educational purposes, try to do this task by hand. diff --git a/katas/content/complex_arithmetic/complex_powers_real/index.md b/katas/content/complex_arithmetic/complex_powers_real/index.md index 30eec5293a..4238596456 100644 --- a/katas/content/complex_arithmetic/complex_powers_real/index.md +++ b/katas/content/complex_arithmetic/complex_powers_real/index.md @@ -5,9 +5,8 @@ **Goal:** Return the complex number $r^x = r^{a + bi}$. -
- Need a hint? - You can use the fact that $r = e^{\ln r}$ to convert exponent bases. Remember though, $\ln r$ is only defined for positive numbers - make sure to check for $r = 0$ separately! +:::hint +You can use the fact that $r = e^{\ln r}$ to convert exponent bases. Remember though, $\ln r$ is only defined for positive numbers - make sure to check for $r = 0$ separately! Q# namespace `Std.Math` includes useful functions `Log()`, `Sin()`, and `Cos()`. -
+::: diff --git a/katas/content/complex_arithmetic/polar_multiplication/index.md b/katas/content/complex_arithmetic/polar_multiplication/index.md index 7db9c5c8ac..faca6f4469 100644 --- a/katas/content/complex_arithmetic/polar_multiplication/index.md +++ b/katas/content/complex_arithmetic/polar_multiplication/index.md @@ -12,12 +12,10 @@ Return the product of $x$ and $y$ as a complex polar number $x \cdot y = r_{3}e^ * $\theta_3$ should be between $-\pi$ and $\pi$: $-\pi < \theta_3 \leq \pi$ * Try to avoid converting the numbers into their Cartesian form. -
- Need a hint? - - Remember, a number written in polar form already involves multiplication. What is $r_1e^{i\theta_1} \cdot r_2e^{i\theta_2}$? +:::hint +Remember, a number written in polar form already involves multiplication. What is $r_1e^{i\theta_1} \cdot r_2e^{i\theta_2}$? Is the value of $\theta$ in the product incorrect? Remember you might have to check your boundaries and adjust it to be in the range requested. -
+::: > Q# function `TimesCP` from `Std.Math` namespace multiplies two complex numbers, but it doesn't normalize the argument of the resulting number. For educational purposes, try to do this task by hand. diff --git a/katas/content/complex_arithmetic/polar_to_cartesian/index.md b/katas/content/complex_arithmetic/polar_to_cartesian/index.md index a3e7608f04..44e6f8f330 100644 --- a/katas/content/complex_arithmetic/polar_to_cartesian/index.md +++ b/katas/content/complex_arithmetic/polar_to_cartesian/index.md @@ -4,11 +4,8 @@ A complex number in polar form $x = re^{i\theta}$. **Goal:** Return the Cartesian representation of $x = a + bi$ as a `Complex`. -
- Need a hint? - +:::hint A video explanation of this conversion can be found [here](https://www.youtube.com/watch?v=auywa7dydAk). - -
+::: > Q# function `ComplexPolarAsComplex` from `Std.Math` namespace converts a complex number of type `ComplexPolar` to a complex number of type `Complex`. For educational purposes, try to do this task by hand. diff --git a/katas/content/deutsch_algo/one_minus_x_oracle/index.md b/katas/content/deutsch_algo/one_minus_x_oracle/index.md index 255b0a6934..059030bab5 100644 --- a/katas/content/deutsch_algo/one_minus_x_oracle/index.md +++ b/katas/content/deutsch_algo/one_minus_x_oracle/index.md @@ -3,11 +3,10 @@ **Goal:** Apply the phase oracle $U_f$ for $f(x) = 1 - x$ to the qubit. That is, apply a relative phase $(-1)^{f(x)}$ to each basis state $\ket{x}$. -
-Need a hint? +:::hint You can represent the effect of the oracle as $$U_f \ket{x} = (-1)^{1-x} \ket{x} = (-1) \cdot (-1)^x \ket{x}$$ Can you get this effect by combining some of the previous oracles implementations? -
+::: diff --git a/katas/content/deutsch_jozsa/parity_oracle/index.md b/katas/content/deutsch_jozsa/parity_oracle/index.md index 69f84281d6..ae66f24411 100644 --- a/katas/content/deutsch_jozsa/parity_oracle/index.md +++ b/katas/content/deutsch_jozsa/parity_oracle/index.md @@ -3,8 +3,7 @@ **Goal:** Apply the phase oracle $U_f$ for $f(x) = 1 \text{ if x has odd number of 1s, and } 0 \text{ otherwise }$ to the qubits. That is, apply a relative phase $(-1)^{f(x)}$ to each basis state $\ket{x}$. -
-Need a hint? +:::hint Can you represent the function as a sum of expressions that depend on individual bits of $x$ (modulo $2$)? Can you then represent the effect of the oracle on the array of qubits as a product of effects on each qubit in the array? -
+::: diff --git a/katas/content/getting_started/flip_qubit/index.md b/katas/content/getting_started/flip_qubit/index.md index e10739756b..c6dabeb7e1 100644 --- a/katas/content/getting_started/flip_qubit/index.md +++ b/katas/content/getting_started/flip_qubit/index.md @@ -4,7 +4,6 @@ Exercises are problems that you have to solve by writing Q# code. In each exerci **Goal:** Apply the X gate to the qubit, that is, perform a "bit flip" to set the qubit into the $\ket{1}$ state. -
-Need a hint? +:::hint For some problems a hint will be provided to help you if you are stuck. For this exercise, read line number 3 in the code below. -
+::: diff --git a/katas/content/grovers_search/phase_oracle/index.md b/katas/content/grovers_search/phase_oracle/index.md index 0c5bada041..1f19434421 100644 --- a/katas/content/grovers_search/phase_oracle/index.md +++ b/katas/content/grovers_search/phase_oracle/index.md @@ -10,7 +10,6 @@ Flip the phase of each basis state $\ket{x}$ for which $f(x) = 1$. You can only The operation you implement is the phase oracle for the same function.
-
- Need a hint? - Recall that you can allocate extra qubits to assist in this operation. Is there a state that you could prepare with an auxiliary qubit which would help you to convert the marking oracle to a phase oracle? -
+:::hint +Recall that you can allocate extra qubits to assist in this operation. Is there a state that you could prepare with an auxiliary qubit which would help you to convert the marking oracle to a phase oracle? +::: diff --git a/katas/content/linear_algebra/inverse/index.md b/katas/content/linear_algebra/inverse/index.md index 44affd148a..8f76abf9f7 100644 --- a/katas/content/linear_algebra/inverse/index.md +++ b/katas/content/linear_algebra/inverse/index.md @@ -4,9 +4,6 @@ $$\begin{bmatrix} 1 & 2 \\ 3 & 4 \end{bmatrix}$$ -
- Need a hint? - +:::hint You can check out [this Wikipedia article](https://en.wikipedia.org/wiki/Invertible_matrix#Inversion_of_2_%C3%97_2_matrices) about invertible matrices. - -
+::: diff --git a/katas/content/marking_oracles/parity/index.md b/katas/content/marking_oracles/parity/index.md index c9bda61e41..2c277cec4b 100644 --- a/katas/content/marking_oracles/parity/index.md +++ b/katas/content/marking_oracles/parity/index.md @@ -11,7 +11,6 @@ In other words, for each basis state $\ket{x}$, flip the state of the target qub Leave the qubits in the input register in the same state they started in. Your solution should work on inputs in superposition, and not use any measurements. -
-Need a hint? +:::hint $f(x)$ can be represented as $x_0 \oplus x_1 \oplus ... \oplus x_{N-1}$. -
+::: diff --git a/katas/content/marking_oracles/product_negation/index.md b/katas/content/marking_oracles/product_negation/index.md index ccc244f4be..0170fd6557 100644 --- a/katas/content/marking_oracles/product_negation/index.md +++ b/katas/content/marking_oracles/product_negation/index.md @@ -12,7 +12,6 @@ In other words, for each basis state $\ket{x}$, flip the state of the target qub Leave the qubits in the input register in the same state they started in. Your solution should work on inputs in superposition, and not use any measurements. -
-Need a hint? +:::hint Since each addition is done modulo $2$, you can evaluate the effect of each term independently. -
+::: diff --git a/katas/content/multi_qubit_gates/arbitrary_controls/index.md b/katas/content/multi_qubit_gates/arbitrary_controls/index.md index 7afcb5d909..f9a2430f07 100644 --- a/katas/content/multi_qubit_gates/arbitrary_controls/index.md +++ b/katas/content/multi_qubit_gates/arbitrary_controls/index.md @@ -8,7 +8,6 @@ > For example, if `controlBits = [true, false, true]`, the controlled $X$ gate should only be applied if the control qubits are in state $\ket{101}$. -
- Need a hint? -

Consider using a library operation for this task. If you want to do it without a library operation, don't forget to reset the qubits back to the state they were originally in.

-
+:::hint +

Consider using a library operation for this task. If you want to do it without a library operation, don't forget to reset the qubits back to the state they were originally in.

+::: diff --git a/katas/content/multi_qubit_gates/compound_gate/index.md b/katas/content/multi_qubit_gates/compound_gate/index.md index eb1b130b62..70679e0326 100644 --- a/katas/content/multi_qubit_gates/compound_gate/index.md +++ b/katas/content/multi_qubit_gates/compound_gate/index.md @@ -18,7 +18,6 @@ $$ > It's recommended to keep a list of common quantum gates on hand. -
- Need a hint? -

Start by noticing that the top right and bottom left quadrants of the matrix are filled with $0$s, and the bottom right quadrant equals to the top left one, multiplied by $i$. Does this look like a tensor product of a 1-qubit and 2-qubit matrices? Which ones?

-
+:::hint +

Start by noticing that the top right and bottom left quadrants of the matrix are filled with $0$s, and the bottom right quadrant equals to the top left one, multiplied by $i$. Does this look like a tensor product of a 1-qubit and 2-qubit matrices? Which ones?

+::: diff --git a/katas/content/multi_qubit_gates/controlled_rotation/index.md b/katas/content/multi_qubit_gates/controlled_rotation/index.md index be5144d00a..71207171fe 100644 --- a/katas/content/multi_qubit_gates/controlled_rotation/index.md +++ b/katas/content/multi_qubit_gates/controlled_rotation/index.md @@ -5,7 +5,6 @@ **Goal:** Apply a controlled $R_x$ gate, using the first qubit as control and the second qubit as target, with $\theta$ as the angle argument for the gate. -
- Need a hint? -

If you were to apply a regular version of $R_x$ gate, it would take two parameters - angle $\theta$ as the first parameter and the target qubit as the second parameter.

-
\ No newline at end of file +:::hint +

If you were to apply a regular version of $R_x$ gate, it would take two parameters - angle $\theta$ as the first parameter and the target qubit as the second parameter.

+::: \ No newline at end of file diff --git a/katas/content/multi_qubit_measurements/state_preparation/index.md b/katas/content/multi_qubit_measurements/state_preparation/index.md index 51b9e09644..44aec47876 100644 --- a/katas/content/multi_qubit_measurements/state_preparation/index.md +++ b/katas/content/multi_qubit_measurements/state_preparation/index.md @@ -3,8 +3,7 @@ **Goal:** Modify the qubits to the state $\frac{1}{\sqrt{3}} \big(\ket{00} + \ket{01} + \ket{10}\big)$ using post-selection.
-
- Need a hint? - Consider a 3-qubit state $\frac{1}{2}(\ket{00} + \ket{01} + \ket{11}) \otimes \ket{0} + \frac{1}{2} \ket{11} \otimes \ket{1}$. +:::hint +Consider a 3-qubit state $\frac{1}{2}(\ket{00} + \ket{01} + \ket{11}) \otimes \ket{0} + \frac{1}{2} \ket{11} \otimes \ket{1}$. What happens when you measure the third qubit? -
+::: diff --git a/katas/content/multi_qubit_systems/learn_basis_state_amplitudes/index.md b/katas/content/multi_qubit_systems/learn_basis_state_amplitudes/index.md index a27c3e38cc..3dd149d009 100644 --- a/katas/content/multi_qubit_systems/learn_basis_state_amplitudes/index.md +++ b/katas/content/multi_qubit_systems/learn_basis_state_amplitudes/index.md @@ -8,7 +8,6 @@ Please note that the state parameter is guaranteed to be the same if you run the code several times. Your operation will be called once for every run. -
- Need a hint? - On a physical quantum system, there would be no way to obtain these values from a single observation. Since this program runs on a simulator, you can use DumpMachine to inspect the qubits and take a note of their state. Furthermore, the problem statement guarantees that the state will be the same from invocation to invocation. So, you can update the code to return the amplitudes that you've taken note of, then run the code again. -
+:::hint +On a physical quantum system, there would be no way to obtain these values from a single observation. Since this program runs on a simulator, you can use DumpMachine to inspect the qubits and take a note of their state. Furthermore, the problem statement guarantees that the state will be the same from invocation to invocation. So, you can update the code to return the amplitudes that you've taken note of, then run the code again. +::: diff --git a/katas/content/multi_qubit_systems/prepare_superposition/index.md b/katas/content/multi_qubit_systems/prepare_superposition/index.md index 60940e0346..8d09755f8f 100644 --- a/katas/content/multi_qubit_systems/prepare_superposition/index.md +++ b/katas/content/multi_qubit_systems/prepare_superposition/index.md @@ -2,7 +2,6 @@ **Goal:** Transform the system into the state $\frac{1}{\sqrt2}\big(\ket{00} - \ket{01}\big) = \frac{1}{\sqrt2}\begin{bmatrix} 1 \\ -1 \\ 0 \\ 0 \end{bmatrix}$. -
- Need a hint? - Represent the target state as a tensor product $\ket{0} \otimes \frac{1}{\sqrt2}\big(\ket{0} - \ket{1}\big) = \begin{bmatrix} 1 \\ 0 \end{bmatrix} \otimes \frac{1}{\sqrt2}\begin{bmatrix} 1 \\ -1 \end{bmatrix}$. -
+:::hint +Represent the target state as a tensor product $\ket{0} \otimes \frac{1}{\sqrt2}\big(\ket{0} - \ket{1}\big) = \begin{bmatrix} 1 \\ 0 \end{bmatrix} \otimes \frac{1}{\sqrt2}\begin{bmatrix} 1 \\ -1 \end{bmatrix}$. +::: diff --git a/katas/content/multi_qubit_systems/prepare_with_complex/index.md b/katas/content/multi_qubit_systems/prepare_with_complex/index.md index f6a848edf5..74804bed97 100644 --- a/katas/content/multi_qubit_systems/prepare_with_complex/index.md +++ b/katas/content/multi_qubit_systems/prepare_with_complex/index.md @@ -3,7 +3,6 @@ **Goal:** Transform the system into the state $\frac{1}{2}\big(\ket{00} + e^{i\pi/4}\ket{01} + e^{i\pi/2}\ket{10} + e^{3i\pi/4}\ket{11}\big) = \frac{1}{2}\begin{bmatrix} 1 \\ e^{i\pi/4} \\ e^{i\pi/2} \\ e^{3i\pi/4} \end{bmatrix}$. -
- Need a hint? - Represent the target state as a tensor product $\frac{1}{\sqrt2}\big(\ket{0} + e^{i\pi/2}\ket{1}\big) \otimes \frac{1}{\sqrt2}\big(\ket{0} + e^{i\pi/4}\ket{1}\big) = \frac{1}{\sqrt2} \begin{bmatrix} 1 \\ e^{i\pi/2} \end{bmatrix} \otimes \frac{1}{\sqrt2}\begin{bmatrix} 1 \\ e^{i\pi/4} \end{bmatrix}$. -
+:::hint +Represent the target state as a tensor product $\frac{1}{\sqrt2}\big(\ket{0} + e^{i\pi/2}\ket{1}\big) \otimes \frac{1}{\sqrt2}\big(\ket{0} + e^{i\pi/4}\ket{1}\big) = \frac{1}{\sqrt2} \begin{bmatrix} 1 \\ e^{i\pi/2} \end{bmatrix} \otimes \frac{1}{\sqrt2}\begin{bmatrix} 1 \\ e^{i\pi/4} \end{bmatrix}$. +::: diff --git a/katas/content/multi_qubit_systems/prepare_with_real/index.md b/katas/content/multi_qubit_systems/prepare_with_real/index.md index 27dcd8e9c3..249b4c5f6b 100644 --- a/katas/content/multi_qubit_systems/prepare_with_real/index.md +++ b/katas/content/multi_qubit_systems/prepare_with_real/index.md @@ -3,7 +3,6 @@ **Goal:** Transform the system into the state $\frac{1}{2}\big(\ket{00} - \ket{01} + \ket{10} - \ket{11}\big) = \frac{1}{2}\begin{bmatrix} 1 \\ -1 \\ 1 \\ -1 \end{bmatrix}$. -
- Need a hint? - Represent the target state as a tensor product $\frac{1}{\sqrt2}\big(\ket{0} + \ket{1}\big) \otimes \frac{1}{\sqrt2}\big(\ket{0} - \ket{1}\big) = \frac{1}{\sqrt2} \begin{bmatrix} 1 \\ 1 \end{bmatrix} \otimes \frac{1}{\sqrt2}\begin{bmatrix} 1 \\ -1 \end{bmatrix}$. -
+:::hint +Represent the target state as a tensor product $\frac{1}{\sqrt2}\big(\ket{0} + \ket{1}\big) \otimes \frac{1}{\sqrt2}\big(\ket{0} - \ket{1}\big) = \frac{1}{\sqrt2} \begin{bmatrix} 1 \\ 1 \end{bmatrix} \otimes \frac{1}{\sqrt2}\begin{bmatrix} 1 \\ -1 \end{bmatrix}$. +::: diff --git a/katas/content/oracles/bit_pattern_challenge/index.md b/katas/content/oracles/bit_pattern_challenge/index.md index 84b7ecba80..0b86500644 100644 --- a/katas/content/oracles/bit_pattern_challenge/index.md +++ b/katas/content/oracles/bit_pattern_challenge/index.md @@ -21,7 +21,6 @@ represented by `pattern`.
-
- Need a hint? - Can you transform the state of the input register based on the pattern value so as to have to flip the phase only for the $\ket{1...1}$ state? -
+:::hint +Can you transform the state of the input register based on the pattern value so as to have to flip the phase only for the $\ket{1...1}$ state? +::: diff --git a/katas/content/oracles/bit_pattern_oracle/index.md b/katas/content/oracles/bit_pattern_oracle/index.md index f50ce45149..be3035df25 100644 --- a/katas/content/oracles/bit_pattern_oracle/index.md +++ b/katas/content/oracles/bit_pattern_oracle/index.md @@ -21,7 +21,6 @@ represented by `pattern`.
-
- Need a hint? - You need to flip the state of $\ket{y}$ if $\ket{x}$ matches the given pattern. You may find the Q# library operation ApplyControlledOnBitString useful in your implementation. -
+:::hint +You need to flip the state of $\ket{y}$ if $\ket{x}$ matches the given pattern. You may find the Q# library operation ApplyControlledOnBitString useful in your implementation. +::: diff --git a/katas/content/oracles/marking_oracle_as_phase/index.md b/katas/content/oracles/marking_oracle_as_phase/index.md index 8a30894571..e8dd05a20e 100644 --- a/katas/content/oracles/marking_oracle_as_phase/index.md +++ b/katas/content/oracles/marking_oracle_as_phase/index.md @@ -8,7 +8,6 @@ Flip the phase of each basis state $\ket{x}$ for which $f(x) = 1$. You can only access $f(x)$ via the marking oracle you are given.
-
- Need a hint? - Recall that you can allocate extra qubits to assist in this operation. Is there a state that you could prepare with an auxiliary qubit which would help you to convert the marking oracle to a phase oracle? -
+:::hint +Recall that you can allocate extra qubits to assist in this operation. Is there a state that you could prepare with an auxiliary qubit which would help you to convert the marking oracle to a phase oracle? +::: diff --git a/katas/content/oracles/or_but_kth_oracle/index.md b/katas/content/oracles/or_but_kth_oracle/index.md index 58bea03149..5d89b23f1e 100644 --- a/katas/content/oracles/or_but_kth_oracle/index.md +++ b/katas/content/oracles/or_but_kth_oracle/index.md @@ -19,9 +19,8 @@ Flip the sign of the basis state $\ket{x}$ if any of the bits of $x$ (not consid This is a phase oracle, because you're changing the phase of the input state $\ket{x}$ based on the value of the function $f(x)$. -
- Need a hint? - You can use the previously implemented oracles if needed by copying the code. -
- You can use array slicing to get parts of the array before and after the $k$-th element. -
+:::hint +You can use the previously implemented oracles if needed by copying the code. +
+You can use array slicing to get parts of the array before and after the $k$-th element. +::: diff --git a/katas/content/oracles/or_oracle/index.md b/katas/content/oracles/or_oracle/index.md index 23c184216b..00d3ebe243 100644 --- a/katas/content/oracles/or_oracle/index.md +++ b/katas/content/oracles/or_oracle/index.md @@ -20,7 +20,6 @@ except for $\ket{00...0}$ (the all zero state).
-
- Need a hint? - You need to flip the state of $\ket{y}$ for every input except $\ket{00...0}$, or, alternatively, flip it unconditionally and then flip it for the $\ket{00...0}$ state. You may find the Q# library function ApplyControlledOnInt useful in your implementation. -
+:::hint +You need to flip the state of $\ket{y}$ for every input except $\ket{00...0}$, or, alternatively, flip it unconditionally and then flip it for the $\ket{00...0}$ state. You may find the Q# library function ApplyControlledOnInt useful in your implementation. +::: diff --git a/katas/content/oracles/phase_oracle_seven/index.md b/katas/content/oracles/phase_oracle_seven/index.md index 2859c73e87..fef7ff812d 100644 --- a/katas/content/oracles/phase_oracle_seven/index.md +++ b/katas/content/oracles/phase_oracle_seven/index.md @@ -12,7 +12,6 @@ Don't allocate extra qubits to perform this operation. * If the query register is in the state $\ket{111}$, flip its sign. * If the query register is in the state $\ket{010}$ or $\ket{101}$, do nothing. -
- Need a hint? - To solve this problem, you need to find a gate that will only flip the sign of the $\ket{111}$ basis state. Which single-qubit gate flips the sign of the basis state $\ket{1}$ but not $\ket{0}$? How can you modify this gate to solve this problem? -
+:::hint +To solve this problem, you need to find a gate that will only flip the sign of the $\ket{111}$ basis state. Which single-qubit gate flips the sign of the basis state $\ket{1}$ but not $\ket{0}$? How can you modify this gate to solve this problem? +::: diff --git a/katas/content/phase_estimation/one_bit_eigenphase/index.md b/katas/content/phase_estimation/one_bit_eigenphase/index.md index a85e3a5bb9..c1ad31f99d 100644 --- a/katas/content/phase_estimation/one_bit_eigenphase/index.md +++ b/katas/content/phase_estimation/one_bit_eigenphase/index.md @@ -10,4 +10,4 @@
Need a hint? You can do this by allocating exactly two qubits and calling Controlled U exactly once. -
\ No newline at end of file + diff --git a/katas/content/phase_estimation/state_eigenvector/index.md b/katas/content/phase_estimation/state_eigenvector/index.md index fc87409034..ae23929f96 100644 --- a/katas/content/phase_estimation/state_eigenvector/index.md +++ b/katas/content/phase_estimation/state_eigenvector/index.md @@ -11,4 +11,4 @@ The library operation CheckZero (from Std.Diagnostics) allows you to check whether the state of the given qubit is $\ket{0}$. - \ No newline at end of file + diff --git a/katas/content/preparing_states/even_sup_two_qubits_complex_phases/index.md b/katas/content/preparing_states/even_sup_two_qubits_complex_phases/index.md index 6698bd76b0..2b830d1222 100644 --- a/katas/content/preparing_states/even_sup_two_qubits_complex_phases/index.md +++ b/katas/content/preparing_states/even_sup_two_qubits_complex_phases/index.md @@ -3,7 +3,6 @@ **Goal:** Change the state of the qubits to $\frac{1}{2} \big(\ket{00} + i\ket{01} - \ket{10} - i\ket{11}\big)$.
-
- Need a hint? Click here - Is this state separable? -
+:::hint +Is this state separable? +::: diff --git a/katas/content/preparing_states/parity_bitstrings/index.md b/katas/content/preparing_states/parity_bitstrings/index.md index 8d1fb136b0..6c47280dbd 100644 --- a/katas/content/preparing_states/parity_bitstrings/index.md +++ b/katas/content/preparing_states/parity_bitstrings/index.md @@ -8,7 +8,6 @@ > For example, for $N = 2$ the required state is $\frac{1}{\sqrt{2}}\big(\ket{00} + \ket{11}\big)$ if `parity = 0`, or $\frac{1}{\sqrt{2}}\big(\ket{01} + \ket{10}\big)$ if `parity = 1`. -
- Need a hint? - Remember that you can call the solution recursively. -
+:::hint +Remember that you can call the solution recursively. +::: diff --git a/katas/content/preparing_states/plus_state/index.md b/katas/content/preparing_states/plus_state/index.md index 45df589ced..95eaf2dd2f 100644 --- a/katas/content/preparing_states/plus_state/index.md +++ b/katas/content/preparing_states/plus_state/index.md @@ -3,7 +3,6 @@ **Goal:** Change the state of the qubit to $\ket{+} = \frac{1}{\sqrt{2}} \big(\ket{0} + \ket{1}\big)$. -
- Need a hint? - Hadamard gate $H$ will convert $\ket{0}$ state to $\ket{+}$ state. -
+:::hint +Hadamard gate $H$ will convert $\ket{0}$ state to $\ket{+}$ state. +::: diff --git a/katas/content/preparing_states/unequal_superposition/index.md b/katas/content/preparing_states/unequal_superposition/index.md index 4e85fa7ebc..cd9ea1829a 100644 --- a/katas/content/preparing_states/unequal_superposition/index.md +++ b/katas/content/preparing_states/unequal_superposition/index.md @@ -5,8 +5,7 @@ **Goal**: Change the state of the qubit to $\cos{α} \ket{0} + \sin{α} \ket{1}$. -
- Need a hint? - Experiment with rotation gates you learned about in the Single-Qubit Gates kata. +:::hint +Experiment with rotation gates you learned about in the Single-Qubit Gates kata. Note that all rotation operators rotate the state by half of its angle argument. -
+::: diff --git a/katas/content/preparing_states/wstate_arbitrary/index.md b/katas/content/preparing_states/wstate_arbitrary/index.md index 871810fd90..8b79cc4caa 100644 --- a/katas/content/preparing_states/wstate_arbitrary/index.md +++ b/katas/content/preparing_states/wstate_arbitrary/index.md @@ -4,7 +4,6 @@ For example, for $N = 3$ the required state is $\frac{1}{\sqrt{3}}\big(\ket{100} + \ket{010} + \ket{001}\big)$. -
- Need a hint? - You can modify the signature of the given operation to specify its controlled specialization. -
+:::hint +You can modify the signature of the given operation to specify its controlled specialization. +::: diff --git a/katas/content/preparing_states/wstate_power_of_two/index.md b/katas/content/preparing_states/wstate_power_of_two/index.md index c6888261ea..e04133967e 100644 --- a/katas/content/preparing_states/wstate_power_of_two/index.md +++ b/katas/content/preparing_states/wstate_power_of_two/index.md @@ -4,7 +4,6 @@ For example, for $N = 4$ the required state is $\frac{1}{2}\big(\ket{1000} + \ket{0100} + \ket{0010} + \ket{0001}\big)$. -
- Need a hint? - You can use Controlled modifier to perform arbitrary controlled gates. -
+:::hint +You can use Controlled modifier to perform arbitrary controlled gates. +::: diff --git a/katas/content/qft/all_even_vectors/index.md b/katas/content/qft/all_even_vectors/index.md index 1bba41dc5f..a5a7e5f227 100644 --- a/katas/content/qft/all_even_vectors/index.md +++ b/katas/content/qft/all_even_vectors/index.md @@ -6,8 +6,7 @@ $$\frac1{\sqrt{2^{n-1}}} \big(\ket{0} + \ket{2} + ... + \ket{2^n-2} \big)$$ > For example, for $n = 2$ the goal state is $\frac1{\sqrt2} \big(\ket{0} + \ket{2}\big)$. -
- Need a hint? - Which superposition of two basis states can be mapped to this state using QFT? +:::hint +Which superposition of two basis states can be mapped to this state using QFT? Use the solutions to earlier tasks in this lesson to figure out the answer. -
\ No newline at end of file +::: \ No newline at end of file diff --git a/katas/content/qft/binary_fraction_inplace/index.md b/katas/content/qft/binary_fraction_inplace/index.md index 71e15cf770..954c156c0a 100644 --- a/katas/content/qft/binary_fraction_inplace/index.md +++ b/katas/content/qft/binary_fraction_inplace/index.md @@ -4,8 +4,6 @@ A register of $n$ qubits in state $\ket{j_1 j_2 ... j_n}$. **Goal**: Change the state of the register from $\ket{j_1} \otimes \ket{j_2 ... j_n}$ to $\frac1{\sqrt2}(\ket{0} + e^{2\pi i \cdot 0.j_1 j_2 ... j_n} \ket{1}) \otimes \ket{j_2 ... j_n}$. -
- Need a hint? - +:::hint This task is very similar to the previous task, but the digit $j_1$ has to be encoded in-place. You can do this using the first task of the kata, "Single-Qubit QFT". -
+::: diff --git a/katas/content/qft/qft/index.md b/katas/content/qft/qft/index.md index 2a7436e7a3..a03ec3114d 100644 --- a/katas/content/qft/qft/index.md +++ b/katas/content/qft/qft/index.md @@ -15,8 +15,6 @@ the behavior in this case is defined by behavior on the basis states and the lin > Notice that this implementation will let you use inverse QFT without writing any extra code, just by using the adjoint of this operation! -
- Need a hint? - +:::hint Consider first preparing a state with the states of individual qubits reversed and then transforming it to the goal state. -
\ No newline at end of file +::: \ No newline at end of file diff --git a/katas/content/qubit/learn_single_qubit_state/index.md b/katas/content/qubit/learn_single_qubit_state/index.md index c05f105fb4..9b7f014bbd 100644 --- a/katas/content/qubit/learn_single_qubit_state/index.md +++ b/katas/content/qubit/learn_single_qubit_state/index.md @@ -8,7 +8,6 @@ Please note that the state parameter is guaranteed to be the same if you run the code several times. Your operation will be called once for every run. -
- Need a hint? - On a physical quantum system, there's no way to obtain the values of $\alpha$ and $\beta$ from a single observation. Since this program runs on a simulator, you can use DumpMachine to inspect the qubit and take a note of its state. Furthermore, the problem statement guarantees, that the state will be the same from invocation to invocation. So you can update the code to return the amplitudes that you've taken note of. Then run the code again. -
+:::hint +On a physical quantum system, there's no way to obtain the values of $\alpha$ and $\beta$ from a single observation. Since this program runs on a simulator, you can use DumpMachine to inspect the qubit and take a note of its state. Furthermore, the problem statement guarantees, that the state will be the same from invocation to invocation. So you can update the code to return the amplitudes that you've taken note of. Then run the code again. +::: diff --git a/katas/content/random_numbers/random_bit/index.md b/katas/content/random_numbers/random_bit/index.md index ae234a8ed9..bd44f48002 100644 --- a/katas/content/random_numbers/random_bit/index.md +++ b/katas/content/random_numbers/random_bit/index.md @@ -1,13 +1,11 @@ **Input:** None. **Goal:** Generate a $0$ or $1$ with equal probability. -
- Need a hint? - Use the allocated qubit, apply a quantum gate to it, measure it and use the result to return a $0$ or $1$. -
+:::hint +Use the allocated qubit, apply a quantum gate to it, measure it and use the result to return a $0$ or $1$. +::: **Stretch goal:** Can you find a different way to implement this operation? -
- Need a hint? - What are the different quantum states that produce $0$ and $1$ measurement results with the same probability? How would measuring the qubit in a different basis change the result? -
+:::hint +What are the different quantum states that produce $0$ and $1$ measurement results with the same probability? How would measuring the qubit in a different basis change the result? +::: diff --git a/katas/content/random_numbers/random_n_bits/index.md b/katas/content/random_numbers/random_n_bits/index.md index ee1a364ada..aad68ffd86 100644 --- a/katas/content/random_numbers/random_n_bits/index.md +++ b/katas/content/random_numbers/random_n_bits/index.md @@ -9,7 +9,6 @@ Let's take it a step further and generate an $N$-bit number. > * for loops > * mutable variables -
- Need a hint? - Remember that you can use previously defined operations to implement your solution. For convenience, the RandomBit operation is already available for you to use in this exercise. -
+:::hint +Remember that you can use previously defined operations to implement your solution. For convenience, the RandomBit operation is already available for you to use in this exercise. +::: diff --git a/katas/content/random_numbers/random_two_bits/index.md b/katas/content/random_numbers/random_two_bits/index.md index 78c43ba3fb..30cbc08e9b 100644 --- a/katas/content/random_numbers/random_two_bits/index.md +++ b/katas/content/random_numbers/random_two_bits/index.md @@ -6,7 +6,6 @@ Now that you can generate a single random bit, you can use that logic to create **Goal:** Generate a random number in the range $[0, 3]$ with an equal probability of getting each of the four numbers. **Stretch goal:** Can you do this without allocating qubits in this operation? -
- Need a hint? - Remember that you can use previously defined operations to implement your solution. For convenience, the RandomBit operation is already available for you to use in this exercise. -
+:::hint +Remember that you can use previously defined operations to implement your solution. For convenience, the RandomBit operation is already available for you to use in this exercise. +::: diff --git a/katas/content/single_qubit_measurements/a_b_basis_measurements/index.md b/katas/content/single_qubit_measurements/a_b_basis_measurements/index.md index 13eb21afcc..5590e10e30 100644 --- a/katas/content/single_qubit_measurements/a_b_basis_measurements/index.md +++ b/katas/content/single_qubit_measurements/a_b_basis_measurements/index.md @@ -6,7 +6,6 @@ **Output:** Implement a measurement in the $\{\ket A, \ket B\}$ basis. Same as in the previous exercise, $\ket{A} = \cos \alpha \ket{0} - i \sin \alpha \ket{1}$ and $\ket{B} = - i \sin \alpha \ket{0} + \cos \alpha \ket{1}$. Return `Zero` if the measurement outcome is $A$, and `One` if the outcome is $B$. The state of the qubit after the measurement should correspond to the measurement result. -
- Need a hint? -

An $R_x$ rotation can be used to go from the computational basis $\{ \ket 0, \ket 1 \}$ to the $\{ \ket{A}, \ket{B} \}$ basis and vice versa.

-
+:::hint +

An $R_x$ rotation can be used to go from the computational basis $\{ \ket 0, \ket 1 \}$ to the $\{ \ket{A}, \ket{B} \}$ basis and vice versa.

+::: diff --git a/katas/content/single_qubit_measurements/distinguish_orthogonal_states_1/index.md b/katas/content/single_qubit_measurements/distinguish_orthogonal_states_1/index.md index 1ddf0905c2..68059d68ba 100644 --- a/katas/content/single_qubit_measurements/distinguish_orthogonal_states_1/index.md +++ b/katas/content/single_qubit_measurements/distinguish_orthogonal_states_1/index.md @@ -2,7 +2,6 @@ **Output:** `true` if the qubit was in the $\ket {\psi_+}$ state, or `false` if it was in the $\ket{\psi_-} $ state. The state of the qubit at the end of the operation does not matter. -
-Need a hint? +:::hint A suitable $R_y$ rotation can be used to go from the computational basis $\{ \ket 0, \ket 1 \}$ to the $\{ \ket{\psi_+}, \ket{\psi_-} \}$ basis and vice versa. -
+::: diff --git a/katas/content/single_qubit_measurements/distinguish_orthogonal_states_2/index.md b/katas/content/single_qubit_measurements/distinguish_orthogonal_states_2/index.md index 68a276ad28..3756210d99 100644 --- a/katas/content/single_qubit_measurements/distinguish_orthogonal_states_2/index.md +++ b/katas/content/single_qubit_measurements/distinguish_orthogonal_states_2/index.md @@ -5,7 +5,6 @@ **Output:** `true` if the qubit was in the $\ket{A}$ state, or `false` if it was in the $\ket{B}$ state. The state of the qubit at the end of the operation does not matter. -
- Need a hint? -

An $R_x$ rotation can be used to go from the computational basis $\{ \ket 0, \ket 1 \}$ to the $\{ \ket{A}, \ket{B} \}$ basis and vice versa.

-
+:::hint +

An $R_x$ rotation can be used to go from the computational basis $\{ \ket 0, \ket 1 \}$ to the $\{ \ket{A}, \ket{B} \}$ basis and vice versa.

+::: diff --git a/source/npm/qsharp/generate_katas_content.js b/source/npm/qsharp/generate_katas_content.js index 82122e42a0..f95cbb8c5a 100644 --- a/source/npm/qsharp/generate_katas_content.js +++ b/source/npm/qsharp/generate_katas_content.js @@ -447,8 +447,7 @@ function createExerciseSection(kataPath, properties, globalCodeSources) { // Strip inline hint blocks from exercise descriptions when requested. // The VS Code extension provides hints through a separate AI-powered // button instead of the embedded
blocks. - const hintPattern = - /
\s*[\s\S]*?Need a hint[\s\S]*?<\/summary>([\s\S]*?)<\/details>/gi; + const hintPattern = /^:::hint\s*\n([\s\S]*?)^:::\s*$/gm; /** @type {string[]} */ let hints = []; if (!emitHtml) { From 738be0ae348705c8ebdb9598d6cf6e0d49619155 Mon Sep 17 00:00:00 2001 From: Mine Starks Date: Fri, 29 May 2026 22:28:55 +0000 Subject: [PATCH 2/3] Consolidate AI files into ai/ directory and add model auto-fallback --- source/vscode/agents/qdk-learning.agent.md | 2 +- .../openqasm.instructions.md | 0 source/vscode/ai/qdk-learning.agent.md | 102 ++++++++++++++++++ .../{prompts => ai}/qdk-learning.prompt.md | 0 .../{skills => ai}/qdk-programming/SKILL.md | 0 .../qdk-programming/openqasm.md | 0 .../{skills => ai}/qdk-programming/python.md | 0 .../{skills => ai}/qdk-programming/qsharp.md | 0 .../qsharp.instructions.md | 0 source/vscode/package.json | 14 ++- 10 files changed, 112 insertions(+), 6 deletions(-) rename source/vscode/{resources/chat-instructions => ai}/openqasm.instructions.md (100%) create mode 100644 source/vscode/ai/qdk-learning.agent.md rename source/vscode/{prompts => ai}/qdk-learning.prompt.md (100%) rename source/vscode/{skills => ai}/qdk-programming/SKILL.md (100%) rename source/vscode/{skills => ai}/qdk-programming/openqasm.md (100%) rename source/vscode/{skills => ai}/qdk-programming/python.md (100%) rename source/vscode/{skills => ai}/qdk-programming/qsharp.md (100%) rename source/vscode/{resources/chat-instructions => ai}/qsharp.instructions.md (100%) diff --git a/source/vscode/agents/qdk-learning.agent.md b/source/vscode/agents/qdk-learning.agent.md index 4142536b38..eea30cf640 100644 --- a/source/vscode/agents/qdk-learning.agent.md +++ b/source/vscode/agents/qdk-learning.agent.md @@ -1,7 +1,7 @@ --- name: QDK Learning description: "Learn quantum computing interactively with the Quantum Katas — guided lessons, hands-on exercises, and Q# code you can run, check, and explore right in VS Code." -model: "Claude Haiku 4.5 (copilot)" +model: ["Claude Haiku 4.5 (copilot)", "auto"] --- # Quantum Development Kit Learning diff --git a/source/vscode/resources/chat-instructions/openqasm.instructions.md b/source/vscode/ai/openqasm.instructions.md similarity index 100% rename from source/vscode/resources/chat-instructions/openqasm.instructions.md rename to source/vscode/ai/openqasm.instructions.md diff --git a/source/vscode/ai/qdk-learning.agent.md b/source/vscode/ai/qdk-learning.agent.md new file mode 100644 index 0000000000..eea30cf640 --- /dev/null +++ b/source/vscode/ai/qdk-learning.agent.md @@ -0,0 +1,102 @@ +--- +name: QDK Learning +description: "Learn quantum computing interactively with the Quantum Katas — guided lessons, hands-on exercises, and Q# code you can run, check, and explore right in VS Code." +model: ["Claude Haiku 4.5 (copilot)", "auto"] +--- + +# Quantum Development Kit Learning + +You are an agent that helps users navigate and interact with the Quantum Katas panel in VS Code. Your role is to respond to chat prompts related to the katas, provide hints, explanations, and guidance. + +The `qdk-learning-*` tools drive a **Quantum Katas panel** in VS Code. The panel renders the current activity, action bar, and progress bar. Its buttons handle navigation, run, check, etc. directly — they bypass the LLM. Your job: set up the workspace, show the current activity, then step aside. You only handle chat prompts and concept questions. + +## Definitions + +Following is a user-ready description of the Quantum Katas. You may refer to it if the user asks what the katas are or how they work. + +> Quantum Katas (_kaˑta_ | kah-tuh — Japanese for "form", a pattern of learning and practicing new skills) are self-paced, AI-assisted tutorials for quantum computing and Q# programming. Each tutorial includes relevant theory and interactive hands-on exercises designed to test knowledge. + +The tools refer to each kata as a "unit." Each unit contains ordered activities (lessons, examples, exercises). + +**Tool naming:** All learning tools share the `qdk-learning-` prefix. This document uses short names (e.g. `show` for `qdk-learning-show`). + +## Key Rules + +1. **Always get fresh state.** Before any response that references the current activity, call `get-state`. The user may have clicked around in the panel — those clicks bypass you. Stale state → wrong answers. +2. **Don't echo the activity content.** The panel renders it. Reprinting in chat is noise. +3. **Do render tool results in chat.** The panel shows the activity content, not tool output. When you call run/check/hint/etc., present the result in chat. + +## Startup + +Call `get-state` first. It never requires confirmation and tells you whether the workspace is initialized. + +- **If `initialized: true`** — you have the current position and progress. Greet the user briefly, then call `show` to open the activity panel. Direct the user's attention to the Quantum Katas panel so they can continue where they left off. +- **If `initialized: false`** — the workspace hasn't been set up yet. Greet the user warmly and explain what the Quantum Katas are (use the description from **Definitions** above). Then call `show` to initialize the workspace — let the user know they'll be asked to confirm workspace creation. Once initialized, direct them to the panel to get started. + +Mention that they can chat with you at any time for hints, explanations, or guidance. Don't explain how the agent works, list tools, or show menus. + +## Tone + +Warm, friendly tutor. Celebrate passes, encourage on failures, use natural language. + +## Panel Behavior + +Panel actions (Next, Run, Check, Solution…) work directly — no LLM round-trip. You're only invoked when the user types in chat or invokes one of the panel actions that explicitly routes a message to chat. + +### Chat Entry Points + +The panel routes these messages to chat. Always call `get-state` first to understand context. + +| Button / Link | Shown on | Chat message | +| --------------------- | --------------------- | ------------------------------------------- | +| **Hint** | Exercises | "Give me a hint" | +| **Explain** | Lessons & examples | "Explain this concept in more detail" | +| What went wrong? | Failed check output | "Help me understand why my solution failed" | +| Explain this solution | After solution reveal | "Explain this solution step by step" | + +**Handling guidance:** + +- **"Explain this concept in more detail"** — Provide a deeper pedagogical explanation. Offer analogies, relate to prior units. Don't repeat the panel content. +- **"Help me understand why my solution failed"** — Analyze common mistakes for that exercise. Give targeted debugging hints, not the full solution. +- **"Explain this solution step by step"** — Walk through the reference solution line by line, explaining the quantum concepts and Q# patterns. + +## Procedure + +### 1. Show Activity + +Call `show`. Use the returned state for your greeting. Don't call on every turn — use `get-state` for silent reads between turns. + +To start a specific unit: `list-units` → find `unitId` → `goto`. + +### 2. Route Chat Input + +Call `get-state` first. If the user is asking to navigate, run, check, reset, etc., call the matching tool directly. Notable cases: + +- **hint** → use the **Hint Strategy** below instead of just calling the tool +- **solution** → warn about spoilers before calling +- **reset** → confirm the user wants to lose their code before calling +- **"help with my code" / "debug"** → call `read-code`, then give personalized feedback +- **Q# or QDK question** → if the answer isn't obvious from the current lesson context, **always** read the `/qdk-programming` skill before responding. +- **free-form question** → answer using knowledge + current state; no tool needed + +Render tool results in chat. Keep responses short and tutor-like. + +### Hint Strategy + +Call `hint` and `read-code` together. The response contains `hints` (short nudges, easiest→hardest) and `solutionExplanation` (deeper walkthrough). + +- Reveal `hints` one at a time ("Hint 1/N"). Skip any the user's code already satisfies. +- On follow-up requests, continue through the list — don't re-call the tool. +- After all hints: paraphrase `solutionExplanation` as a deeper nudge (never dump verbatim). +- No hints at all: generate one yourself from the exercise description and Q# knowledge. + +### After a Passing Check + +Render the result, offer a brief reaction. Don't auto-call `next` — the user may want to review the solution first. + +## Don'ts + +- Don't echo activity content in chat +- Don't reveal the solution without a spoiler warning +- Don't invent state — call `get-state` if unsure +- Don't dump raw state JSON to the user diff --git a/source/vscode/prompts/qdk-learning.prompt.md b/source/vscode/ai/qdk-learning.prompt.md similarity index 100% rename from source/vscode/prompts/qdk-learning.prompt.md rename to source/vscode/ai/qdk-learning.prompt.md diff --git a/source/vscode/skills/qdk-programming/SKILL.md b/source/vscode/ai/qdk-programming/SKILL.md similarity index 100% rename from source/vscode/skills/qdk-programming/SKILL.md rename to source/vscode/ai/qdk-programming/SKILL.md diff --git a/source/vscode/skills/qdk-programming/openqasm.md b/source/vscode/ai/qdk-programming/openqasm.md similarity index 100% rename from source/vscode/skills/qdk-programming/openqasm.md rename to source/vscode/ai/qdk-programming/openqasm.md diff --git a/source/vscode/skills/qdk-programming/python.md b/source/vscode/ai/qdk-programming/python.md similarity index 100% rename from source/vscode/skills/qdk-programming/python.md rename to source/vscode/ai/qdk-programming/python.md diff --git a/source/vscode/skills/qdk-programming/qsharp.md b/source/vscode/ai/qdk-programming/qsharp.md similarity index 100% rename from source/vscode/skills/qdk-programming/qsharp.md rename to source/vscode/ai/qdk-programming/qsharp.md diff --git a/source/vscode/resources/chat-instructions/qsharp.instructions.md b/source/vscode/ai/qsharp.instructions.md similarity index 100% rename from source/vscode/resources/chat-instructions/qsharp.instructions.md rename to source/vscode/ai/qsharp.instructions.md diff --git a/source/vscode/package.json b/source/vscode/package.json index aac99fddbe..3d9b63ade1 100644 --- a/source/vscode/package.json +++ b/source/vscode/package.json @@ -452,6 +452,10 @@ } ], "qsharp-vscode-katas": [ + { + "id": "quantum-workspaces", + "name": "Azure Quantum" + }, { "id": "qsharp-vscode.learningWelcome", "name": "QDK Learning", @@ -482,25 +486,25 @@ ], "chatInstructions": [ { - "path": "./resources/chat-instructions/qsharp.instructions.md" + "path": "./ai/qsharp.instructions.md" }, { - "path": "./resources/chat-instructions/openqasm.instructions.md" + "path": "./ai/openqasm.instructions.md" } ], "chatSkills": [ { - "path": "./skills/qdk-programming/SKILL.md" + "path": "./ai/qdk-programming/SKILL.md" } ], "chatPromptFiles": [ { - "path": "./prompts/qdk-learning.prompt.md" + "path": "./ai/qdk-learning.prompt.md" } ], "chatAgents": [ { - "path": "./agents/qdk-learning.agent.md" + "path": "./ai/qdk-learning.agent.md" } ], "commands": [ From b995c555e4e96e29e78fe19cb83e7bd186a11861 Mon Sep 17 00:00:00 2001 From: Mine Starks Date: Fri, 29 May 2026 22:29:02 +0000 Subject: [PATCH 3/3] Surface progress file errors in UI and LLM contexts --- source/vscode/src/gh-copilot/learningTools.ts | 7 +- source/vscode/src/learning/service.ts | 141 ++++++++++++------ 2 files changed, 100 insertions(+), 48 deletions(-) diff --git a/source/vscode/src/gh-copilot/learningTools.ts b/source/vscode/src/gh-copilot/learningTools.ts index f3996fd9e1..6ce2a94ebf 100644 --- a/source/vscode/src/gh-copilot/learningTools.ts +++ b/source/vscode/src/gh-copilot/learningTools.ts @@ -107,9 +107,14 @@ export class LearningTools { * so the caller can decide whether to prompt for initialization. */ async getState(): Promise< - { initialized: false } | ({ initialized: true } & StateSnapshot) + | { initialized: false; error?: string } + | ({ initialized: true } & StateSnapshot) > { if (!this.service.initialized) { + const errorMsg = this.service.progressFileError; + if (errorMsg) { + return { initialized: false, error: errorMsg }; + } const detected = await detectLearningWorkspace(); if (!detected) { return { initialized: false }; diff --git a/source/vscode/src/learning/service.ts b/source/vscode/src/learning/service.ts index 92e9281a92..25d06664e2 100644 --- a/source/vscode/src/learning/service.ts +++ b/source/vscode/src/learning/service.ts @@ -110,6 +110,7 @@ export class LearningService { private _progressFileWatcher: vscode.FileSystemWatcher | undefined; private _writingProgress = false; private _initPromise: Promise | undefined; + private _progressCorruptError: string | undefined; constructor(private readonly extensionUri: vscode.Uri) {} @@ -117,6 +118,11 @@ export class LearningService { return this.workspace !== undefined; } + /** Non-null when the progress file is corrupt and blocks initialization. */ + get progressFileError(): string | undefined { + return this._progressCorruptError; + } + get learningContentRoot(): vscode.Uri { return this.requireWorkspace().learningContentRoot; } @@ -160,7 +166,13 @@ export class LearningService { dispose(): void { if (this.workspace) { - this.saveProgress().catch(() => {}); + this.saveProgress().catch((err) => { + vscode.window.showWarningMessage( + `Could not save learning progress: ${ + err instanceof Error ? err.message : String(err) + }`, + ); + }); } this._onDidChangeState.dispose(); this._onDidChangeProgress.dispose(); @@ -655,10 +667,18 @@ export class LearningService { const detected = await detectLearningWorkspace(); if (detected) { - await this.loadWorkspace( - detected.workspaceRoot, - detected.learningContentRoot, - ); + try { + await this.loadWorkspace( + detected.workspaceRoot, + detected.learningContentRoot, + ); + } catch (err) { + if (this._progressCorruptError) { + vscode.window.showErrorMessage(this._progressCorruptError); + return false; + } + throw err; + } this.startWatcher(); sendTelemetryEvent( EventType.LearningSessionStarted, @@ -807,7 +827,10 @@ export class LearningService { { key: "r", label: "Reset", action: "reset" }, ], ]; - return [primaryGroup, ...extraGroups, navGroup].filter( + const resetGroup: ActionGroup = [ + { key: "x", label: "Reset", action: "reset" }, + ]; + return [primaryGroup, ...extraGroups, resetGroup, navGroup].filter( (g) => g.length > 0, ); } @@ -981,52 +1004,69 @@ export class LearningService { } private async loadProgress(ws: WorkspaceState): Promise { + let bytes: Uint8Array; + try { + bytes = await vscode.workspace.fs.readFile(ws.learningFile); + } catch { + // File doesn't exist yet — use defaults. + ws.progressData = { + version: 1, + position: { + courseId: ws.catalog.id, + unitId: ws.catalog.units[0]?.id ?? "", + activityId: ws.catalog.units[0]?.activities[0]?.id ?? "", + }, + completions: {}, + startedAt: new Date().toISOString(), + }; + return; + } + + // File exists — parse and validate. + let parsed: unknown; try { - const bytes = await vscode.workspace.fs.readFile(ws.learningFile); - const parsed = JSON.parse(new TextDecoder().decode(bytes)); - if ( - parsed && - typeof parsed === "object" && - parsed.version === 1 && - typeof parsed.completions === "object" && - parsed.completions !== null && - typeof parsed.position === "object" && - parsed.position !== null - ) { - ws.progressData = parsed as ProgressFileData; - // Validate saved position references a known unit and activity - if (ws.catalog.units.length > 0) { - const unit = ws.catalog.units.find( - (k) => k.id === ws.progressData.position.unitId, + parsed = JSON.parse(new TextDecoder().decode(bytes)); + } catch { + this._progressCorruptError = + "The qdk-learning.json file contains invalid JSON. Fix or delete the file to continue."; + throw new Error(this._progressCorruptError); + } + + if ( + parsed && + typeof parsed === "object" && + (parsed as any).version === 1 && + typeof (parsed as any).completions === "object" && + (parsed as any).completions !== null && + typeof (parsed as any).position === "object" && + (parsed as any).position !== null + ) { + ws.progressData = parsed as ProgressFileData; + // Validate saved position references a known unit and activity + if (ws.catalog.units.length > 0) { + const unit = ws.catalog.units.find( + (k) => k.id === ws.progressData.position.unitId, + ); + const activityValid = + unit && + unit.activities.some( + (s) => s.id === ws.progressData.position.activityId, ); - const activityValid = - unit && - unit.activities.some( - (s) => s.id === ws.progressData.position.activityId, - ); - if (!activityValid) { - ws.progressData.position = { - courseId: ws.catalog.id, - unitId: ws.catalog.units[0].id, - activityId: ws.catalog.units[0].activities[0]?.id ?? "", - }; - } + if (!activityValid) { + ws.progressData.position = { + courseId: ws.catalog.id, + unitId: ws.catalog.units[0].id, + activityId: ws.catalog.units[0].activities[0]?.id ?? "", + }; } - return; } - } catch { - // expected when file is missing or corrupt + return; } - ws.progressData = { - version: 1, - position: { - courseId: ws.catalog.id, - unitId: ws.catalog.units[0]?.id ?? "", - activityId: ws.catalog.units[0]?.activities[0]?.id ?? "", - }, - completions: {}, - startedAt: new Date().toISOString(), - }; + + // File exists but has unexpected structure. + this._progressCorruptError = + "The qdk-learning.json file is corrupt (unexpected structure). Fix or delete the file to continue."; + throw new Error(this._progressCorruptError); } private async saveProgress(): Promise { @@ -1038,6 +1078,13 @@ export class LearningService { ws.learningFile, new TextEncoder().encode(json), ); + } catch (err) { + throw new Error( + `Failed to save learning progress: ${ + err instanceof Error ? err.message : String(err) + }`, + { cause: err }, + ); } finally { this._writingProgress = false; }