├── Part1
├── Task4
│ ├── Task4TestingHarness.1.0.0.nupkg
│ ├── Task4.csproj
│ ├── NuGet.config
│ ├── Tests.qs
│ ├── Task4.sln
│ ├── Tasks.qs
│ └── ReferenceImplementation.qs
├── Task1
│ ├── Task1.csproj
│ ├── ReferenceImplementation.qs
│ ├── Task1.sln
│ ├── Tasks.qs
│ └── Tests.qs
├── Task2
│ ├── Task2.csproj
│ ├── ReferenceImplementation.qs
│ ├── Task2.sln
│ ├── Tasks.qs
│ └── Tests.qs
└── Task3
│ ├── Task3.csproj
│ ├── ReferenceImplementation.qs
│ ├── Task3.sln
│ ├── Utils.qs
│ ├── Tasks.qs
│ ├── Tests.qs
│ └── CounterSimulator.cs
├── Dockerfile
├── .gitignore
└── README.md
/Part1/Task4/Task4TestingHarness.1.0.0.nupkg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/quantumcoalition/qchack-microsoft-challenge/HEAD/Part1/Task4/Task4TestingHarness.1.0.0.nupkg
--------------------------------------------------------------------------------
/Part1/Task1/Task1.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 | netcoreapp3.1
4 | Library
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/Part1/Task2/Task2.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 | netcoreapp3.1
4 | Library
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/Part1/Task3/Task3.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 | netcoreapp3.1
4 | Library
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/Part1/Task4/Task4.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 | netcoreapp3.1
4 | Library
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/Dockerfile:
--------------------------------------------------------------------------------
1 | # This uses the latest Docker image built from the samples repository,
2 | # defined by the Dockerfile in Build/images/samples.
3 | FROM mcr.microsoft.com/quantum/samples:latest
4 |
5 | # Mark that this Dockerfile is used with the samples repository.
6 | ENV IQSHARP_HOSTING_ENV=QCHACK2021
7 |
8 | # Make sure the contents of our repo are in ${HOME}.
9 | # These steps are required for use on mybinder.org.
10 | USER root
11 | COPY . ${HOME}
12 | RUN chown -R ${USER} ${HOME}
13 |
14 | # Finish by dropping back to the notebook user.
15 | USER ${USER}
16 |
--------------------------------------------------------------------------------
/Part1/Task4/NuGet.config:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/Part1/Task1/ReferenceImplementation.qs:
--------------------------------------------------------------------------------
1 | namespace QCHack.Task1 {
2 | open Microsoft.Quantum.Canon;
3 | open Microsoft.Quantum.Intrinsic;
4 |
5 | // Task 1. Check that x is divisible by 4
6 | // Inputs:
7 | // 1) an N-qubit array `inputs`,
8 | // 2) a qubit `output`.
9 | // Goal: Flip the output qubit if and only if the number written in the array `inputs`
10 | // (in little-endian encoding) is divisible by 4.
11 | // For example, for the result of applying the operation to state (|000⟩ + |101⟩ + |111⟩) ⊗ |0⟩
12 | // will be |001⟩ ⊗ |1⟩ + |101⟩ ⊗ |0⟩ + |111⟩ ⊗ |0⟩.
13 | operation Task1_DivisibleByFour_Reference (inputs : Qubit[], output : Qubit) : Unit is Adj+Ctl {
14 | // The first two qubits must be in 00 state
15 | (ControlledOnInt(0, X))(inputs[0 .. 1], output);
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/Part1/Task2/ReferenceImplementation.qs:
--------------------------------------------------------------------------------
1 | namespace QCHack.Task2 {
2 | open Microsoft.Quantum.Canon;
3 | open Microsoft.Quantum.Intrinsic;
4 |
5 | // Task 2. Check that colors don't form a triangle
6 | // Inputs:
7 | // 1) a 3-qubit array `inputs`,
8 | // 2) a qubit `output`.
9 | // Goal: Flip the output qubit if and only if at least two of the input qubits are different.
10 | // For example, for the result of applying the operation to state (|001⟩ + |110⟩ + |111⟩) ⊗ |0⟩
11 | // will be |001⟩ ⊗ |1⟩ + |110⟩ ⊗ |1⟩ + |111⟩ ⊗ |0⟩.
12 | operation Task2_ValidTriangle_Reference (inputs : Qubit[], output : Qubit) : Unit is Adj+Ctl {
13 | // We don't want to mark only all 0s and all 1s - mark them and flip
14 | (ControlledOnInt(0, X))(inputs, output);
15 | Controlled X(inputs, output);
16 | X(output);
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/Part1/Task4/Tests.qs:
--------------------------------------------------------------------------------
1 | namespace QCHack.Task4 {
2 | open Microsoft.Quantum.Arrays;
3 | open Microsoft.Quantum.Arithmetic;
4 | open Microsoft.Quantum.Canon;
5 | open Microsoft.Quantum.Convert;
6 | open Microsoft.Quantum.Diagnostics;
7 | open Microsoft.Quantum.Intrinsic;
8 | open Microsoft.Quantum.Logical;
9 | open Microsoft.Quantum.Math;
10 | open Microsoft.Quantum.Measurement;
11 |
12 | open Quantum.Kata.Utils;
13 | open QCHack.Task4.TestingHarness;
14 |
15 |
16 | // ------------------------------------------------------
17 | @Test("Microsoft.Quantum.Katas.CounterSimulator")
18 | operation Test4_ValidTriangle_Small() : Unit {
19 | TestingHarness_ValidTriangle_Small(Task4_TriangleFreeColoringOracle);
20 | }
21 |
22 |
23 | // ------------------------------------------------------
24 | @Test("Microsoft.Quantum.Katas.CounterSimulator")
25 | operation Test4_ValidTriangle_Large() : Unit {
26 | TestingHarness_ValidTriangle_Large(Task4_TriangleFreeColoringOracle);
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/Part1/Task3/ReferenceImplementation.qs:
--------------------------------------------------------------------------------
1 | namespace QCHack.Task3 {
2 | open Microsoft.Quantum.Canon;
3 | open Microsoft.Quantum.Intrinsic;
4 |
5 | // Task 3. Check that colors don't form a triangle
6 | // Inputs:
7 | // 1) a 3-qubit array `inputs`,
8 | // 2) a qubit `output`.
9 | // Goal: Flip the output qubit if and only if at least two of the input qubits are different.
10 | // For example, for the result of applying the operation to state (|001⟩ + |110⟩ + |111⟩) ⊗ |0⟩
11 | // will be |001⟩ ⊗ |1⟩ + |110⟩ ⊗ |1⟩ + |111⟩ ⊗ |0⟩.
12 | operation Task3_ValidTriangle_Reference (inputs : Qubit[], output : Qubit) : Unit is Adj+Ctl {
13 | // We cannot just enumerate all the inputs for which f(x) = 1, so need to do some computation
14 | within {
15 | CNOT(inputs[1], inputs[0]);
16 | CNOT(inputs[1], inputs[2]);
17 | } apply {
18 | Controlled X([inputs[0], inputs[2]], output);
19 | CNOT(inputs[0], output);
20 | CNOT(inputs[2], output);
21 | }
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/Part1/Task1/Task1.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio Version 16
4 | VisualStudioVersion = 16.0.29926.136
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Task1", "Task1.csproj", "{56369BA0-DEE9-4860-884B-EB52DB6AB3DE}"
7 | EndProject
8 | Global
9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
10 | Debug|Any CPU = Debug|Any CPU
11 | Release|Any CPU = Release|Any CPU
12 | EndGlobalSection
13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
14 | {56369BA0-DEE9-4860-884B-EB52DB6AB3DE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
15 | {56369BA0-DEE9-4860-884B-EB52DB6AB3DE}.Debug|Any CPU.Build.0 = Debug|Any CPU
16 | {56369BA0-DEE9-4860-884B-EB52DB6AB3DE}.Release|Any CPU.ActiveCfg = Release|Any CPU
17 | {56369BA0-DEE9-4860-884B-EB52DB6AB3DE}.Release|Any CPU.Build.0 = Release|Any CPU
18 | EndGlobalSection
19 | GlobalSection(SolutionProperties) = preSolution
20 | HideSolutionNode = FALSE
21 | EndGlobalSection
22 | GlobalSection(ExtensibilityGlobals) = postSolution
23 | SolutionGuid = {53090785-98FE-4532-A3BF-3C65223037EE}
24 | EndGlobalSection
25 | EndGlobal
26 |
--------------------------------------------------------------------------------
/Part1/Task2/Task2.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio Version 16
4 | VisualStudioVersion = 16.0.29926.136
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Task2", "Task2.csproj", "{56369BA0-DEE9-4860-884B-EB52DB6AB3DE}"
7 | EndProject
8 | Global
9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
10 | Debug|Any CPU = Debug|Any CPU
11 | Release|Any CPU = Release|Any CPU
12 | EndGlobalSection
13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
14 | {56369BA0-DEE9-4860-884B-EB52DB6AB3DE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
15 | {56369BA0-DEE9-4860-884B-EB52DB6AB3DE}.Debug|Any CPU.Build.0 = Debug|Any CPU
16 | {56369BA0-DEE9-4860-884B-EB52DB6AB3DE}.Release|Any CPU.ActiveCfg = Release|Any CPU
17 | {56369BA0-DEE9-4860-884B-EB52DB6AB3DE}.Release|Any CPU.Build.0 = Release|Any CPU
18 | EndGlobalSection
19 | GlobalSection(SolutionProperties) = preSolution
20 | HideSolutionNode = FALSE
21 | EndGlobalSection
22 | GlobalSection(ExtensibilityGlobals) = postSolution
23 | SolutionGuid = {53090785-98FE-4532-A3BF-3C65223037EE}
24 | EndGlobalSection
25 | EndGlobal
26 |
--------------------------------------------------------------------------------
/Part1/Task3/Task3.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio Version 16
4 | VisualStudioVersion = 16.0.29926.136
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Task3", "Task3.csproj", "{56369BA0-DEE9-4860-884B-EB52DB6AB3DE}"
7 | EndProject
8 | Global
9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
10 | Debug|Any CPU = Debug|Any CPU
11 | Release|Any CPU = Release|Any CPU
12 | EndGlobalSection
13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
14 | {56369BA0-DEE9-4860-884B-EB52DB6AB3DE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
15 | {56369BA0-DEE9-4860-884B-EB52DB6AB3DE}.Debug|Any CPU.Build.0 = Debug|Any CPU
16 | {56369BA0-DEE9-4860-884B-EB52DB6AB3DE}.Release|Any CPU.ActiveCfg = Release|Any CPU
17 | {56369BA0-DEE9-4860-884B-EB52DB6AB3DE}.Release|Any CPU.Build.0 = Release|Any CPU
18 | EndGlobalSection
19 | GlobalSection(SolutionProperties) = preSolution
20 | HideSolutionNode = FALSE
21 | EndGlobalSection
22 | GlobalSection(ExtensibilityGlobals) = postSolution
23 | SolutionGuid = {53090785-98FE-4532-A3BF-3C65223037EE}
24 | EndGlobalSection
25 | EndGlobal
26 |
--------------------------------------------------------------------------------
/Part1/Task4/Task4.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio Version 16
4 | VisualStudioVersion = 16.0.29926.136
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Task4", "Task4.csproj", "{56369BA0-DEE9-4860-884B-EB52DB6AB3DE}"
7 | EndProject
8 | Global
9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
10 | Debug|Any CPU = Debug|Any CPU
11 | Release|Any CPU = Release|Any CPU
12 | EndGlobalSection
13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
14 | {56369BA0-DEE9-4860-884B-EB52DB6AB3DE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
15 | {56369BA0-DEE9-4860-884B-EB52DB6AB3DE}.Debug|Any CPU.Build.0 = Debug|Any CPU
16 | {56369BA0-DEE9-4860-884B-EB52DB6AB3DE}.Release|Any CPU.ActiveCfg = Release|Any CPU
17 | {56369BA0-DEE9-4860-884B-EB52DB6AB3DE}.Release|Any CPU.Build.0 = Release|Any CPU
18 | EndGlobalSection
19 | GlobalSection(SolutionProperties) = preSolution
20 | HideSolutionNode = FALSE
21 | EndGlobalSection
22 | GlobalSection(ExtensibilityGlobals) = postSolution
23 | SolutionGuid = {53090785-98FE-4532-A3BF-3C65223037EE}
24 | EndGlobalSection
25 | EndGlobal
26 |
--------------------------------------------------------------------------------
/Part1/Task2/Tasks.qs:
--------------------------------------------------------------------------------
1 | namespace QCHack.Task2 {
2 | open Microsoft.Quantum.Canon;
3 | open Microsoft.Quantum.Intrinsic;
4 |
5 | // Task 2 (2 points). f(x) = 1 if at least two of three input bits are different - easy version
6 | //
7 | // Inputs:
8 | // 1) a 3-qubit array "inputs",
9 | // 2) a qubit "output".
10 | // Goal: Implement a marking oracle for function f(x) = 1 if at least two of the three bits of x are different.
11 | // That is, if both inputs are in a basis state, flip the state of the output qubit
12 | // if and only if the three bits written in the array "inputs" have both 0 and 1 among them,
13 | // and leave the state of the array "inputs" unchanged.
14 | // The effect of the oracle on superposition states should be defined by its linearity.
15 | // Don't use measurements; the implementation should use only X gates and its controlled variants.
16 | // This task will be tested using ToffoliSimulator.
17 | //
18 | // For example, the result of applying the operation to state (|001⟩ + |110⟩ + |111⟩)/√3 ⊗ |0⟩
19 | // will be 1/√3|001⟩ ⊗ |1⟩ + 1/√3|110⟩ ⊗ |1⟩ + 1/√3|111⟩ ⊗ |0⟩.
20 | //
21 | operation Task2_ValidTriangle (inputs : Qubit[], output : Qubit) : Unit is Adj+Ctl {
22 | // ...
23 | }
24 | }
25 |
26 |
--------------------------------------------------------------------------------
/Part1/Task1/Tasks.qs:
--------------------------------------------------------------------------------
1 | namespace QCHack.Task1 {
2 | open Microsoft.Quantum.Canon;
3 | open Microsoft.Quantum.Intrinsic;
4 |
5 | // Task 1 (1 point). f(x) = 1 if x is divisible by 4
6 | //
7 | // Inputs:
8 | // 1) an N-qubit array "inputs" (3 ≤ N ≤ 5),
9 | // 2) a qubit "output".
10 | // Goal: Implement a marking oracle for function f(x) = 1 if x is divisible by 4.
11 | // That is, if both inputs are in a basis state, flip the state of the output qubit
12 | // if and only if the number written in the array "inputs" is divisible by 4,
13 | // and leave the state of the array "inputs" unchanged.
14 | // The array "inputs" uses little-endian encoding, i.e.,
15 | // the least significant bit of the integer is stored first.
16 | // The effect of the oracle on superposition states should be defined by its linearity.
17 | // Don't use measurements; the implementation should use only X gates and its controlled variants.
18 | // This task will be tested using ToffoliSimulator.
19 | //
20 | // Example: the result of applying the oracle to a state (|001⟩ + |100⟩ + |111⟩)/√3 ⊗ |0⟩
21 | // will be 1/√3|001⟩ ⊗ |1⟩ + 1/√3|100⟩ ⊗ |0⟩ + 1/√3|111⟩ ⊗ |0⟩.
22 | //
23 | operation Task1_DivisibleByFour (inputs : Qubit[], output : Qubit) : Unit is Adj+Ctl {
24 | // ...
25 | }
26 | }
27 |
28 |
--------------------------------------------------------------------------------
/Part1/Task3/Utils.qs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Microsoft Corporation. All rights reserved.
2 | // Licensed under the MIT license.
3 |
4 | //////////////////////////////////////////////////////////////////////
5 | // This file contains some Q# intrinsic operations
6 | // needed for the validation of some Katas' answers.
7 | //////////////////////////////////////////////////////////////////////
8 |
9 | namespace Quantum.Kata.Utils {
10 |
11 | /// # Summary
12 | /// Returns how many times a given oracle is executed.
13 | /// # Input
14 | /// ## oracle
15 | /// The operation whose call count is being requested.
16 | operation GetOracleCallsCount<'T> (oracle : 'T) : Int { body intrinsic; }
17 |
18 | /// # Summary
19 | /// Resets the variable that tracks how many times an oracle
20 | /// is executed back to 0.
21 | operation ResetOracleCallsCount () : Unit { body intrinsic; }
22 |
23 |
24 | /// # Summary
25 | /// Returns the max number of qubits allocated at any given point by the simulator.
26 | operation GetMaxQubitCount () : Int { body intrinsic; }
27 |
28 |
29 | /// # Summary
30 | /// Resets the variable that tracks the numbers of multi-qubit operations.
31 | operation ResetNQubitOpCount () : Unit { body intrinsic; }
32 |
33 |
34 | /// # Summary
35 | /// Returns the number of multi-qubit operations that take exactly nQubit qubits.
36 | operation GetExactlyNQubitOpCount (nQubit : Int) : Int { body intrinsic; }
37 |
38 |
39 | /// # Summary
40 | /// Returns the number of multi-qubit operations that take nQubit qubits or more.
41 | operation GetNPlusQubitOpCount (nQubit : Int) : Int { body intrinsic; }
42 | }
43 |
--------------------------------------------------------------------------------
/Part1/Task3/Tasks.qs:
--------------------------------------------------------------------------------
1 | namespace QCHack.Task3 {
2 | open Microsoft.Quantum.Canon;
3 | open Microsoft.Quantum.Intrinsic;
4 |
5 | // Task 3 (5 points). f(x) = 1 if at least two of three input bits are different - hard version
6 | //
7 | // Inputs:
8 | // 1) a 3-qubit array "inputs",
9 | // 2) a qubit "output".
10 | // Goal: Implement a marking oracle for function f(x) = 1 if at least two of the three bits of x are different.
11 | // That is, if both inputs are in a basis state, flip the state of the output qubit
12 | // if and only if the three bits written in the array "inputs" have both 0 and 1 among them,
13 | // and leave the state of the array "inputs" unchanged.
14 | // The effect of the oracle on superposition states should be defined by its linearity.
15 | // Don't use measurements; the implementation should use only X gates and its controlled variants.
16 | // This task will be tested using ToffoliSimulator.
17 | //
18 | // For example, the result of applying the operation to state (|001⟩ + |110⟩ + |111⟩)/√3 ⊗ |0⟩
19 | // will be 1/√3|001⟩ ⊗ |1⟩ + 1/√3|110⟩ ⊗ |1⟩ + 1/√3|111⟩ ⊗ |0⟩.
20 | //
21 | // In this task, unlike in task 2, you are not allowed to use 4-qubit gates,
22 | // and you are allowed to use at most one 3-qubit gate.
23 | // Warning: some library operations, such as ApplyToEach, might count as multi-qubit gate,
24 | // even though they apply single-qubit gates to separate qubits. Make sure you run the test
25 | // on your solution to check that it passes before you submit the solution!
26 | operation Task3_ValidTriangle (inputs : Qubit[], output : Qubit) : Unit is Adj+Ctl {
27 | // ...
28 | }
29 | }
30 |
31 |
--------------------------------------------------------------------------------
/Part1/Task1/Tests.qs:
--------------------------------------------------------------------------------
1 | namespace QCHack.Task1 {
2 | open Microsoft.Quantum.Arrays;
3 | open Microsoft.Quantum.Arithmetic;
4 | open Microsoft.Quantum.Canon;
5 | open Microsoft.Quantum.Convert;
6 | open Microsoft.Quantum.Diagnostics;
7 | open Microsoft.Quantum.Intrinsic;
8 | open Microsoft.Quantum.Logical;
9 | open Microsoft.Quantum.Math;
10 | open Microsoft.Quantum.Measurement;
11 |
12 |
13 | internal operation VerifySingleOutputFunction(numInputs : Int, op : ((Qubit[], Qubit) => Unit is Adj+Ctl), predicate : (Int -> Bool)) : Unit {
14 | for assignment in 0 .. 2^numInputs - 1 {
15 | use (inputs, output) = (Qubit[numInputs], Qubit());
16 | within {
17 | ApplyXorInPlace(assignment, LittleEndian(inputs));
18 | AllowAtMostNCallsCA(0, Measure, "You are not allowed to use measurements");
19 | } apply {
20 | op(inputs, output);
21 | }
22 |
23 | // Check that the result is expected
24 | let actual = ResultAsBool(MResetZ(output));
25 | let expected = predicate(assignment);
26 | Fact(actual == expected,
27 | $"Oracle evaluation result {actual} does not match expected {expected} for assignment {IntAsBoolArray(assignment, numInputs)}");
28 |
29 | // Check that the inputs were not modified
30 | Fact(MeasureInteger(LittleEndian(inputs)) == 0,
31 | $"The input states were modified for assignment {assignment}");
32 | }
33 | }
34 |
35 |
36 | // ------------------------------------------------------
37 | internal function IsDivisibleByFour (input : Int) : Bool {
38 | return input % 4 == 0;
39 | }
40 |
41 | @Test("ToffoliSimulator")
42 | operation Test1_DivisibleByFour() : Unit {
43 | for i in 3 .. 5 {
44 | VerifySingleOutputFunction(3, Task1_DivisibleByFour, IsDivisibleByFour);
45 | }
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/Part1/Task2/Tests.qs:
--------------------------------------------------------------------------------
1 | namespace QCHack.Task2 {
2 | open Microsoft.Quantum.Arrays;
3 | open Microsoft.Quantum.Arithmetic;
4 | open Microsoft.Quantum.Canon;
5 | open Microsoft.Quantum.Convert;
6 | open Microsoft.Quantum.Diagnostics;
7 | open Microsoft.Quantum.Intrinsic;
8 | open Microsoft.Quantum.Logical;
9 | open Microsoft.Quantum.Math;
10 | open Microsoft.Quantum.Measurement;
11 |
12 |
13 | internal operation VerifySingleOutputFunction(numInputs : Int, op : ((Qubit[], Qubit) => Unit is Adj+Ctl), predicate : (Int -> Bool)) : Unit {
14 | for assignment in 0 .. 2^numInputs - 1 {
15 | use (inputs, output) = (Qubit[numInputs], Qubit());
16 | within {
17 | ApplyXorInPlace(assignment, LittleEndian(inputs));
18 | AllowAtMostNCallsCA(0, Measure, "You are not allowed to use measurements");
19 | } apply {
20 | op(inputs, output);
21 | }
22 |
23 | // Check that the result is expected
24 | let actual = ResultAsBool(MResetZ(output));
25 | let expected = predicate(assignment);
26 | Fact(actual == expected,
27 | $"Oracle evaluation result {actual} does not match expected {expected} for assignment {IntAsBoolArray(assignment, numInputs)}");
28 |
29 | // Check that the inputs were not modified
30 | Fact(MeasureInteger(LittleEndian(inputs)) == 0,
31 | $"The input states were modified for assignment {assignment}");
32 | }
33 | }
34 |
35 |
36 | // ------------------------------------------------------
37 | internal function IsTriangleValid (input : Int) : Bool {
38 | // the triangle is valid if it has at least two different bits (i.e., not all are the same)
39 | return input > 0 and input < 7;
40 | }
41 |
42 | @Test("ToffoliSimulator")
43 | operation Test2_ValidTriangle() : Unit {
44 | VerifySingleOutputFunction(3, Task2_ValidTriangle, IsTriangleValid);
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/Part1/Task4/Tasks.qs:
--------------------------------------------------------------------------------
1 | namespace QCHack.Task4 {
2 | open Microsoft.Quantum.Canon;
3 | open Microsoft.Quantum.Intrinsic;
4 |
5 | // Task 4 (12 points). f(x) = 1 if the graph edge coloring is triangle-free
6 | //
7 | // Inputs:
8 | // 1) The number of vertices in the graph "V" (V ≤ 6).
9 | // 2) An array of E tuples of integers "edges", representing the edges of the graph (0 ≤ E ≤ V(V-1)/2).
10 | // Each tuple gives the indices of the start and the end vertices of the edge.
11 | // The vertices are indexed 0 through V - 1.
12 | // The graph is undirected, so the order of the start and the end vertices in the edge doesn't matter.
13 | // 3) An array of E qubits "colorsRegister" that encodes the color assignments of the edges.
14 | // Each color will be 0 or 1 (stored in 1 qubit).
15 | // The colors of edges in this array are given in the same order as the edges in the "edges" array.
16 | // 4) A qubit "target" in an arbitrary state.
17 | //
18 | // Goal: Implement a marking oracle for function f(x) = 1 if
19 | // the coloring of the edges of the given graph described by this colors assignment is triangle-free, i.e.,
20 | // no triangle of edges connecting 3 vertices has all three edges in the same color.
21 | //
22 | // Example: a graph with 3 vertices and 3 edges [(0, 1), (1, 2), (2, 0)] has one triangle.
23 | // The result of applying the operation to state (|001⟩ + |110⟩ + |111⟩)/√3 ⊗ |0⟩
24 | // will be 1/√3|001⟩ ⊗ |1⟩ + 1/√3|110⟩ ⊗ |1⟩ + 1/√3|111⟩ ⊗ |0⟩.
25 | // The first two terms describe triangle-free colorings,
26 | // and the last term describes a coloring where all edges of the triangle have the same color.
27 | //
28 | // In this task you are not allowed to use quantum gates that use more qubits than the number of edges in the graph,
29 | // unless there are 3 or less edges in the graph. For example, if the graph has 4 edges, you can only use 4-qubit gates or less.
30 | // You are guaranteed that in tests that have 4 or more edges in the graph the number of triangles in the graph
31 | // will be strictly less than the number of edges.
32 | //
33 | // Hint: Make use of helper functions and helper operations, and avoid trying to fit the complete
34 | // implementation into a single operation - it's not impossible but make your code less readable.
35 | // GraphColoring kata has an example of implementing oracles for a similar task.
36 | //
37 | // Hint: Remember that you can examine the inputs and the intermediary results of your computations
38 | // using Message function for classical values and DumpMachine for quantum states.
39 | //
40 | operation Task4_TriangleFreeColoringOracle (
41 | V : Int,
42 | edges : (Int, Int)[],
43 | colorsRegister : Qubit[],
44 | target : Qubit
45 | ) : Unit is Adj+Ctl {
46 | // ...
47 | }
48 | }
49 |
50 |
--------------------------------------------------------------------------------
/Part1/Task3/Tests.qs:
--------------------------------------------------------------------------------
1 | namespace QCHack.Task3 {
2 | open Microsoft.Quantum.Arrays;
3 | open Microsoft.Quantum.Arithmetic;
4 | open Microsoft.Quantum.Canon;
5 | open Microsoft.Quantum.Convert;
6 | open Microsoft.Quantum.Diagnostics;
7 | open Microsoft.Quantum.Intrinsic;
8 | open Microsoft.Quantum.Logical;
9 | open Microsoft.Quantum.Math;
10 | open Microsoft.Quantum.Measurement;
11 |
12 | open Quantum.Kata.Utils;
13 |
14 |
15 | internal operation VerifySingleOutputFunction(numInputs : Int, op : ((Qubit[], Qubit) => Unit is Adj+Ctl), predicate : (Int -> Bool)) : Unit {
16 | for assignment in 0 .. 2^numInputs - 1 {
17 | use (inputs, output) = (Qubit[numInputs], Qubit());
18 | within {
19 | ApplyXorInPlace(assignment, LittleEndian(inputs));
20 | AllowAtMostNCallsCA(0, Measure, "You are not allowed to use measurements");
21 | } apply {
22 | ResetNQubitOpCount();
23 |
24 | op(inputs, output);
25 |
26 | // Take into account that CCNOT is NOT natively implemented on Toffoli simulator,
27 | // so it counts as two three-qubit gates - CCNOT and Controlled X.
28 | // ApplyAnd has the same implementation.
29 | let op3 = GetExactlyNQubitOpCount(3) - GetOracleCallsCount(CCNOT) - GetOracleCallsCount(ApplyAnd);
30 | // Message($"{GetExactlyNQubitOpCount(3)} - {GetOracleCallsCount(CCNOT)} - {GetOracleCallsCount(ApplyAnd)} = {op3}");
31 |
32 | // One 4-qubit operation goes for calling op itself and should be allowed
33 | let op4plus = GetNPlusQubitOpCount(4) - 1;
34 |
35 | Fact(op3 <= 1, $"You are allowed to use at most one 3-qubit gate, and you used {op3}");
36 | Fact(op4plus == 0, $"You are not allowed to use gates with 4 or more qubits, and you used {op4plus}");
37 | }
38 |
39 | // Check that the result is expected
40 | let actual = ResultAsBool(MResetZ(output));
41 | let expected = predicate(assignment);
42 | Fact(actual == expected,
43 | $"Oracle evaluation result {actual} does not match expected {expected} for assignment {IntAsBoolArray(assignment, numInputs)}");
44 |
45 | // Check that the inputs were not modified
46 | Fact(MeasureInteger(LittleEndian(inputs)) == 0,
47 | $"The input states were modified for assignment {assignment}");
48 | }
49 | }
50 |
51 |
52 | // ------------------------------------------------------
53 | internal function IsTriangleValid (input : Int) : Bool {
54 | // the triangle is valid if it has at least two different bits (i.e., not all are the same)
55 | return input > 0 and input < 7;
56 | }
57 |
58 | @Test("Microsoft.Quantum.Katas.CounterSimulator")
59 | operation Test3_ValidTriangle() : Unit {
60 | VerifySingleOutputFunction(3, Task3_ValidTriangle, IsTriangleValid);
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/Part1/Task4/ReferenceImplementation.qs:
--------------------------------------------------------------------------------
1 | namespace QCHack.Task4 {
2 | open Microsoft.Quantum.Convert;
3 | open Microsoft.Quantum.Arrays;
4 | open Microsoft.Quantum.Canon;
5 | open Microsoft.Quantum.Intrinsic;
6 |
7 | // Check that colors don't form a triangle of edges
8 | operation IsValidTriangle_Reference (inputs : Qubit[], output : Qubit) : Unit is Adj+Ctl {
9 | // We don't want to mark only all 0s and all 1s - mark them and flip
10 | (ControlledOnInt(0, X))(inputs, output);
11 | Controlled X(inputs, output);
12 | X(output);
13 | }
14 |
15 |
16 | // ------------------------------------------------------
17 | // Convert the list of edges into adjacency matrix (with indices of edges)
18 | function AdjacencyMatrix_Reference (V : Int, edges : (Int, Int)[]) : Int[][] {
19 | mutable adjVertices = new Int[][V];
20 | for ind in 0 .. V - 1 {
21 | set adjVertices w/= ind <- ConstantArray(V, -1);
22 | }
23 | for edgeInd in 0 .. Length(edges) - 1 {
24 | let (v1, v2) = edges[edgeInd];
25 | // track both directions in the adjacency matrix
26 | set adjVertices w/= v1 <- (adjVertices[v1] w/ v2 <- edgeInd);
27 | set adjVertices w/= v2 <- (adjVertices[v2] w/ v1 <- edgeInd);
28 | }
29 | return adjVertices;
30 | }
31 |
32 |
33 | // ------------------------------------------------------
34 | // Extract the list of triangles from the adjacency matrix
35 | function TrianglesList_Reference (V : Int, adjacencyMatrix : Int[][]) : (Int, Int, Int)[] {
36 | mutable triangles = new (Int, Int, Int)[0];
37 | for v1 in 0 .. V - 1 {
38 | for v2 in v1 + 1 .. V - 1 {
39 | for v3 in v2 + 1 .. V - 1 {
40 | if (adjacencyMatrix[v1][v2] > -1 and adjacencyMatrix[v1][v3] > -1 and adjacencyMatrix[v2][v3] > -1) {
41 | set triangles = triangles + [(v1, v2, v3)];
42 | }
43 | }
44 | }
45 | }
46 | return triangles;
47 | }
48 |
49 |
50 | // ------------------------------------------------------
51 | operation Task4_TriangleFreeColoringOracle_Reference (
52 | V : Int,
53 | edges : (Int, Int)[],
54 | colorsRegister : Qubit[],
55 | target : Qubit
56 | ) : Unit is Adj+Ctl {
57 | // Construct adjacency matrix of the graph
58 | let adjacencyMatrix = AdjacencyMatrix_Reference(V, edges);
59 | // Enumerate all possible triangles of edges
60 | let trianglesList = TrianglesList_Reference(V, adjacencyMatrix);
61 |
62 | // Allocate one extra qubit per triangle
63 | let nTr = Length(trianglesList);
64 | use aux = Qubit[nTr];
65 | within {
66 | for i in 0 .. nTr - 1 {
67 | // For each triangle, form an array of qubits that holds its edge colors
68 | let (v1, v2, v3) = trianglesList[i];
69 | let edgeColors = [colorsRegister[adjacencyMatrix[v1][v2]],
70 | colorsRegister[adjacencyMatrix[v1][v3]],
71 | colorsRegister[adjacencyMatrix[v2][v3]]];
72 | IsValidTriangle_Reference(edgeColors, aux[i]);
73 | }
74 | } apply {
75 | // If all triangles are good, all aux qubits are 1
76 | Controlled X(aux, target);
77 | }
78 | }
79 | }
80 |
--------------------------------------------------------------------------------
/Part1/Task3/CounterSimulator.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Microsoft Corporation. All rights reserved.
2 | // Licensed under the MIT license.
3 |
4 | using System;
5 | using System.Collections.Generic;
6 |
7 | using Microsoft.Quantum.Simulation.Common;
8 | using Microsoft.Quantum.Simulation.Core;
9 | using Microsoft.Quantum.Simulation.Simulators;
10 |
11 | using Quantum.Kata.Utils;
12 |
13 | namespace Microsoft.Quantum.Katas
14 | {
15 | ///
16 | /// This custom quantum simulator keeps track of the number of times each operation is executed
17 | /// and the maximum number of qubits allocated at any point during program execution.
18 | ///
19 | public class CounterSimulator : ToffoliSimulator
20 | {
21 | private Dictionary _operationsCount = new Dictionary();
22 | private Dictionary _arityOperationsCount = new Dictionary();
23 |
24 | public CounterSimulator() : base()
25 | {
26 | this.OnOperationStart += CountOperationCalls;
27 | }
28 |
29 | ///
30 | /// Getter method for _operationsCount designed to be accessed from C# code.
31 | /// See GetOracleCallsCount for accessing within Q#.
32 | ///
33 | public int GetOperationCount(ICallable op)
34 | {
35 | return _operationsCount.TryGetValue(op.ToString(), out var value) ? value : 0;
36 | }
37 |
38 | #region Counting operations upon each operation call
39 | ///
40 | /// Callback method for the OnOperationStart event.
41 | ///
42 | public void CountOperationCalls(ICallable op, IApplyData data)
43 | {
44 | // Count all operations, grouped by operation
45 | if (_operationsCount.ContainsKey(op.ToString()))
46 | {
47 | _operationsCount[op.ToString()]++;
48 | }
49 | else
50 | {
51 | _operationsCount[op.ToString()] = 1;
52 | }
53 |
54 | // Check if the operation has multiple qubit parameters, if yes, count it
55 | int nQubits = 0;
56 | using (IEnumerator enumerator = data?.Qubits?.GetEnumerator())
57 | {
58 | if (enumerator is null)
59 | {
60 | // The operation doesn't have qubit parameters
61 | return;
62 | }
63 | while (enumerator.MoveNext())
64 | nQubits++;
65 | }
66 |
67 | if (_arityOperationsCount.ContainsKey(nQubits))
68 | {
69 | _arityOperationsCount[nQubits]++;
70 | }
71 | else
72 | {
73 | _arityOperationsCount[nQubits] = 1;
74 | }
75 | }
76 | #endregion
77 |
78 | #region Implementations of Q# operations for specific operation counting
79 | ///
80 | /// Custom Native operation to reset the oracle counts back to 0.
81 | ///
82 | public class ResetOracleCallsImpl : ResetOracleCallsCount
83 | {
84 | CounterSimulator _sim;
85 |
86 | public ResetOracleCallsImpl(CounterSimulator m) : base(m)
87 | {
88 | _sim = m;
89 | }
90 |
91 | public override Func __Body__ => (__in) =>
92 | {
93 | _sim._operationsCount.Clear();
94 | return QVoid.Instance;
95 | };
96 | }
97 |
98 | ///
99 | /// Custom Native operation to get the number of operation calls.
100 | ///
101 | public class GetOracleCallsImpl : GetOracleCallsCount
102 | {
103 | CounterSimulator _sim;
104 |
105 | public GetOracleCallsImpl(CounterSimulator m) : base(m)
106 | {
107 | _sim = m;
108 | }
109 |
110 | public override Func __Body__ => (__in) =>
111 | {
112 | var oracle = __in;
113 |
114 | var op = oracle as ICallable;
115 | if (op == null)
116 | throw new InvalidOperationException($"Expected an operation as the argument, got: {oracle}");
117 |
118 | var actual = _sim._operationsCount.ContainsKey(op.ToString()) ? _sim._operationsCount[op.ToString()] : 0;
119 |
120 | return actual;
121 | };
122 | }
123 | #endregion
124 |
125 | #region Implementations of Q# operations for counting operations of certain arity
126 | ///
127 | /// Custom Native operation to reset the operation counts back to 0.
128 | ///
129 | public class ResetNQubitOpCountImpl : ResetNQubitOpCount
130 | {
131 | CounterSimulator _sim;
132 |
133 | public ResetNQubitOpCountImpl(CounterSimulator m) : base(m)
134 | {
135 | _sim = m;
136 | }
137 |
138 | public override Func __Body__ => (__in) =>
139 | {
140 | _sim._arityOperationsCount.Clear();
141 | return QVoid.Instance;
142 | };
143 | }
144 |
145 |
146 | ///
147 | /// Custom operation to get the number of operations that take exactly nQubit qubits.
148 | ///
149 | public class GetExactlyNQubitOpCountImpl : GetExactlyNQubitOpCount
150 | {
151 | CounterSimulator _sim;
152 |
153 | public GetExactlyNQubitOpCountImpl(CounterSimulator m) : base(m)
154 | {
155 | _sim = m;
156 | }
157 |
158 | public override Func __Body__ => (__in) =>
159 | {
160 | long nQubit = __in;
161 | return _sim._arityOperationsCount.ContainsKey(nQubit) ? _sim._arityOperationsCount[nQubit] : 0;
162 | };
163 | }
164 |
165 |
166 | ///
167 | /// Custom operation to get the number of operations that take exactly nQubit qubits.
168 | ///
169 | public class GetNPlusQubitOpCountImpl : GetNPlusQubitOpCount
170 | {
171 | CounterSimulator _sim;
172 |
173 | public GetNPlusQubitOpCountImpl(CounterSimulator m) : base(m)
174 | {
175 | _sim = m;
176 | }
177 |
178 | public override Func __Body__ => (__in) =>
179 | {
180 | long nQubit = __in;
181 | long total = 0;
182 | foreach (var pair in _sim._arityOperationsCount) {
183 | if (pair.Key >= nQubit) {
184 | total += pair.Value;
185 | }
186 | }
187 | return total;
188 | };
189 | }
190 | #endregion
191 |
192 | }
193 | }
194 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | ## Ignore Visual Studio temporary files, build results, and
2 | ## files generated by popular Visual Studio add-ons.
3 | ##
4 | ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
5 |
6 | # User-specific files
7 | *.rsuser
8 | *.suo
9 | *.user
10 | *.userosscache
11 | *.sln.docstates
12 |
13 | # User-specific files (MonoDevelop/Xamarin Studio)
14 | *.userprefs
15 |
16 | # Mono auto generated files
17 | mono_crash.*
18 |
19 | # Build results
20 | [Dd]ebug/
21 | [Dd]ebugPublic/
22 | [Rr]elease/
23 | [Rr]eleases/
24 | x64/
25 | x86/
26 | [Aa][Rr][Mm]/
27 | [Aa][Rr][Mm]64/
28 | bld/
29 | [Bb]in/
30 | [Oo]bj/
31 | [Ll]og/
32 | [Ll]ogs/
33 |
34 | # Visual Studio 2015/2017 cache/options directory
35 | .vs/
36 | # Uncomment if you have tasks that create the project's static files in wwwroot
37 | #wwwroot/
38 |
39 | # Visual Studio 2017 auto generated files
40 | Generated\ Files/
41 |
42 | # MSTest test Results
43 | [Tt]est[Rr]esult*/
44 | [Bb]uild[Ll]og.*
45 |
46 | # NUnit
47 | *.VisualState.xml
48 | TestResult.xml
49 | nunit-*.xml
50 |
51 | # Build Results of an ATL Project
52 | [Dd]ebugPS/
53 | [Rr]eleasePS/
54 | dlldata.c
55 |
56 | # Benchmark Results
57 | BenchmarkDotNet.Artifacts/
58 |
59 | # .NET Core
60 | project.lock.json
61 | project.fragment.lock.json
62 | artifacts/
63 |
64 | # StyleCop
65 | StyleCopReport.xml
66 |
67 | # Files built by Visual Studio
68 | *_i.c
69 | *_p.c
70 | *_h.h
71 | *.ilk
72 | *.meta
73 | *.obj
74 | *.iobj
75 | *.pch
76 | *.pdb
77 | *.ipdb
78 | *.pgc
79 | *.pgd
80 | *.rsp
81 | *.sbr
82 | *.tlb
83 | *.tli
84 | *.tlh
85 | *.tmp
86 | *.tmp_proj
87 | *_wpftmp.csproj
88 | *.log
89 | *.vspscc
90 | *.vssscc
91 | .builds
92 | *.pidb
93 | *.svclog
94 | *.scc
95 |
96 | # Chutzpah Test files
97 | _Chutzpah*
98 |
99 | # Visual C++ cache files
100 | ipch/
101 | *.aps
102 | *.ncb
103 | *.opendb
104 | *.opensdf
105 | *.sdf
106 | *.cachefile
107 | *.VC.db
108 | *.VC.VC.opendb
109 |
110 | # Visual Studio profiler
111 | *.psess
112 | *.vsp
113 | *.vspx
114 | *.sap
115 |
116 | # Visual Studio Trace Files
117 | *.e2e
118 |
119 | # TFS 2012 Local Workspace
120 | $tf/
121 |
122 | # Guidance Automation Toolkit
123 | *.gpState
124 |
125 | # ReSharper is a .NET coding add-in
126 | _ReSharper*/
127 | *.[Rr]e[Ss]harper
128 | *.DotSettings.user
129 |
130 | # TeamCity is a build add-in
131 | _TeamCity*
132 |
133 | # DotCover is a Code Coverage Tool
134 | *.dotCover
135 |
136 | # AxoCover is a Code Coverage Tool
137 | .axoCover/*
138 | !.axoCover/settings.json
139 |
140 | # Visual Studio code coverage results
141 | *.coverage
142 | *.coveragexml
143 |
144 | # NCrunch
145 | _NCrunch_*
146 | .*crunch*.local.xml
147 | nCrunchTemp_*
148 |
149 | # MightyMoose
150 | *.mm.*
151 | AutoTest.Net/
152 |
153 | # Web workbench (sass)
154 | .sass-cache/
155 |
156 | # Installshield output folder
157 | [Ee]xpress/
158 |
159 | # DocProject is a documentation generator add-in
160 | DocProject/buildhelp/
161 | DocProject/Help/*.HxT
162 | DocProject/Help/*.HxC
163 | DocProject/Help/*.hhc
164 | DocProject/Help/*.hhk
165 | DocProject/Help/*.hhp
166 | DocProject/Help/Html2
167 | DocProject/Help/html
168 |
169 | # Click-Once directory
170 | publish/
171 |
172 | # Publish Web Output
173 | *.[Pp]ublish.xml
174 | *.azurePubxml
175 | # Note: Comment the next line if you want to checkin your web deploy settings,
176 | # but database connection strings (with potential passwords) will be unencrypted
177 | *.pubxml
178 | *.publishproj
179 |
180 | # Microsoft Azure Web App publish settings. Comment the next line if you want to
181 | # checkin your Azure Web App publish settings, but sensitive information contained
182 | # in these scripts will be unencrypted
183 | PublishScripts/
184 |
185 | # NuGet Packages
186 | # NuGet Symbol Packages
187 | *.snupkg
188 | # The packages folder can be ignored because of Package Restore
189 | **/[Pp]ackages/*
190 | # except build/, which is used as an MSBuild target.
191 | !**/[Pp]ackages/build/
192 | # Uncomment if necessary however generally it will be regenerated when needed
193 | #!**/[Pp]ackages/repositories.config
194 | # NuGet v3's project.json files produces more ignorable files
195 | *.nuget.props
196 | *.nuget.targets
197 |
198 | # Microsoft Azure Build Output
199 | csx/
200 | *.build.csdef
201 |
202 | # Microsoft Azure Emulator
203 | ecf/
204 | rcf/
205 |
206 | # Windows Store app package directories and files
207 | AppPackages/
208 | BundleArtifacts/
209 | Package.StoreAssociation.xml
210 | _pkginfo.txt
211 | *.appx
212 | *.appxbundle
213 | *.appxupload
214 |
215 | # Visual Studio cache files
216 | # files ending in .cache can be ignored
217 | *.[Cc]ache
218 | # but keep track of directories ending in .cache
219 | !?*.[Cc]ache/
220 |
221 | # Others
222 | ClientBin/
223 | ~$*
224 | *~
225 | *.dbmdl
226 | *.dbproj.schemaview
227 | *.jfm
228 | *.pfx
229 | *.publishsettings
230 | orleans.codegen.cs
231 |
232 | # Including strong name files can present a security risk
233 | # (https://github.com/github/gitignore/pull/2483#issue-259490424)
234 | #*.snk
235 |
236 | # Since there are multiple workflows, uncomment next line to ignore bower_components
237 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
238 | #bower_components/
239 |
240 | # RIA/Silverlight projects
241 | Generated_Code/
242 |
243 | # Backup & report files from converting an old project file
244 | # to a newer Visual Studio version. Backup files are not needed,
245 | # because we have git ;-)
246 | _UpgradeReport_Files/
247 | Backup*/
248 | UpgradeLog*.XML
249 | UpgradeLog*.htm
250 | ServiceFabricBackup/
251 | *.rptproj.bak
252 |
253 | # SQL Server files
254 | *.mdf
255 | *.ldf
256 | *.ndf
257 |
258 | # Business Intelligence projects
259 | *.rdl.data
260 | *.bim.layout
261 | *.bim_*.settings
262 | *.rptproj.rsuser
263 | *- [Bb]ackup.rdl
264 | *- [Bb]ackup ([0-9]).rdl
265 | *- [Bb]ackup ([0-9][0-9]).rdl
266 |
267 | # Microsoft Fakes
268 | FakesAssemblies/
269 |
270 | # GhostDoc plugin setting file
271 | *.GhostDoc.xml
272 |
273 | # Node.js Tools for Visual Studio
274 | .ntvs_analysis.dat
275 | node_modules/
276 |
277 | # Visual Studio 6 build log
278 | *.plg
279 |
280 | # Visual Studio 6 workspace options file
281 | *.opt
282 |
283 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
284 | *.vbw
285 |
286 | # Visual Studio LightSwitch build output
287 | **/*.HTMLClient/GeneratedArtifacts
288 | **/*.DesktopClient/GeneratedArtifacts
289 | **/*.DesktopClient/ModelManifest.xml
290 | **/*.Server/GeneratedArtifacts
291 | **/*.Server/ModelManifest.xml
292 | _Pvt_Extensions
293 |
294 | # Paket dependency manager
295 | .paket/paket.exe
296 | paket-files/
297 |
298 | # FAKE - F# Make
299 | .fake/
300 |
301 | # CodeRush personal settings
302 | .cr/personal
303 |
304 | # Python Tools for Visual Studio (PTVS)
305 | __pycache__/
306 | *.pyc
307 |
308 | # Cake - Uncomment if you are using it
309 | # tools/**
310 | # !tools/packages.config
311 |
312 | # Tabs Studio
313 | *.tss
314 |
315 | # Telerik's JustMock configuration file
316 | *.jmconfig
317 |
318 | # BizTalk build output
319 | *.btp.cs
320 | *.btm.cs
321 | *.odx.cs
322 | *.xsd.cs
323 |
324 | # OpenCover UI analysis results
325 | OpenCover/
326 |
327 | # Azure Stream Analytics local run output
328 | ASALocalRun/
329 |
330 | # MSBuild Binary and Structured Log
331 | *.binlog
332 |
333 | # NVidia Nsight GPU debugger configuration file
334 | *.nvuser
335 |
336 | # MFractors (Xamarin productivity tool) working folder
337 | .mfractor/
338 |
339 | # Local History for Visual Studio
340 | .localhistory/
341 |
342 | # BeatPulse healthcheck temp database
343 | healthchecksdb
344 |
345 | # Backup folder for Package Reference Convert tool in Visual Studio 2017
346 | MigrationBackup/
347 |
348 | # Ionide (cross platform F# VS Code tools) working folder
349 | .ionide/
350 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Welcome to Microsoft challenge at QCHack 2021!
2 |
3 | We are excited to offer this challenge to [QCHack 2021](https://www.qchack.io/) participants, and we are looking forward to the solutions you will come up with!
4 |
5 | ## Challenge overview
6 |
7 | Grover's search algorithm is one of the fundamental algorithms of quantum computing. At the same time it is frequently misinterpreted and misrepresented, and figuring out how to apply it to solve a given problem can be quite challenging! The main part of the challenge is implementing the given problem as a *quantum oracle* - the core part of Grover's algorithm.
8 |
9 | This challenge consists of two parts. In part 1, you will explore implementing given classical problems of varying complexity as quantum oracles. In part 2, you will come up with an interesting problem yourself, and solve it using Grover's search.
10 |
11 | **To participate in this challenge, you must use Q# programming language and tools available as part of the Microsoft Quantum Development Kit.**
12 | You do not need to use Azure Quantum to run your solutions on quantum hardware.
13 |
14 | ## Part 1: Automatically judged tasks
15 |
16 | Part 1 of this challenge can be found in folder [Part1](./Part1). It contains 4 independent tasks of increasing difficulty: task 1 is the easiest one, and task 4 is quite challenging.
17 |
18 | In each task you need to implement a marking quantum oracle for a classical function by filling in the code in the given Q# operation. The task description and the operation skeleton are given in the file Tasks.qs; this is the only file you should modify in the task.
19 |
20 | The file Tests.qs contains the testing harness for the task. Once you solved the task and wrote the code for it, you can run the provided test to verify that the your solution to the task is correct.
21 | The workflow of working on the task is extremely similar to that of working on the [Quantum Katas](https://github.com/microsoft/QuantumKatas/).
22 | You can read more about opening the project and running the test [here](https://github.com/microsoft/QuantumKatas/#run-a-kata-as-a-q-project-).
23 |
24 | We will evaluate your solutions to the tasks using similar testing harnesses, possibly including more tests than were provided to you. If your solution to a task passes the tests, you get the points for that task! The point values for tasks are:
25 |
26 | * [Task 1. f(x) = 1 if x is divisible by 4](./Part1/Task1/) - 1 point.
27 | * [Task 2. f(x) = 1 if at least two of three input bits are different - easy](./Part1/Task2/) - 2 points.
28 | * [Task 3. f(x) = 1 if at least two of three input bits are different - hard](./Part1/Task3/) - 5 points.
29 | * [Task 4. f(x) = 1 if the graph edge coloring is triangle-free](./Part1/Task4/) - 12 points.
30 |
31 |
32 | ## Part 2: Free-form project
33 |
34 | In part 2 of the challenge, you will come up with a problem you'd like to solve using Grover's search, and create a project that solves this problem! There is no "right" or "wrong" way to solve this challenge; you have the freedom to decide what you want to do and how far you want to go!
35 |
36 | Your project for part 2:
37 |
38 | * Must include a problem description and instructions on running the project in README.md file.
39 | * Must solve a small instance of the problem using a full-state simulator without any user input, or with a well-documented user input. If your solution requires an input, its format should be documented in README.md, including an example.
40 | * Must produce an output presenting the instance of the problem solved and the solution in human-readable format.
41 | * Must be original, i.e., not previously covered in Quantum Development Kit samples, learning materials, or the Quantum Katas.
42 |
43 | The judging for part 2 of the challenge will be more flexible than for part 1. Since there is no single "right" solution, we'll be evaluating the projects based on several criteria. Here is the list of criteria and example questions we'll consider when evaluating the projects:
44 |
45 | * *Technical depth* (6 points). How complicated is the selected problem? How well is it solved?
46 | * *Use of tools* (5 points). Evaluates the breadth of Quantum Development Kit tools used in the project. Is the project relying on the libraries to maximize code readability? Is the oracle implementation covered by unit tests? Does the project use specialized simulators and/or resource estimation? Is the solution to the problem displayed using a clever visualization?
47 | * *Creativity* (4 points). How original is the problem selection? How creative is the output presentation?
48 | * *Educational value* (5 points): Is this project valuable for helping others learn? Did the team write a blog post about the project sharing their learnings with others? Is the project structured as a tutorial?
49 |
50 | For the general guidelines on judging projects, please refer to the [Official QCHack Hacking Rules 2021](https://docs.google.com/document/d/1_Jln3lIfNmYPlUtJ17zgwi5FQtNtzhHR-fH15QqW3xc/edit).
51 |
52 | ## Submitting your solutions
53 |
54 | To submit your solutions:
55 | 1. Fork (or duplicate) this repository to your GitHub account.
56 | 2. Work on the solutions to the tasks from part 1 and the project from part 2.
57 | 3. Commit your work to your forked repository.
58 | For part 1 tasks, you should only modify Tasks.qs files. For part 2 project, commit any files you consider relevant: the project itself, screenshots of results, any visualizations you've done, etc.
59 | 4. To submit your project, submit the link to your repository.
60 | Your repository has to be made public at the time of the Hackathon end for us to be able to judge your solutions. We don't recommend making your work public early during the Hackathon, so as not to tempt other teams to borrow from your work. Let everybody enjoy their exploration!
61 | *Note that GitHub doesn't allow to change visibility of the forks. You can either fork the repository, keep it public, and push your changes at the last possible moment, or you can duplicate the repository, make it private to work on it during the Hackathon, and make it public at the end of the Hackathon. Your repo is not required to be an actual fork, it just has to follow the folder structure of this repo for Part 1 tasks.*
62 | 5. If your project for part 2 includes a blog post about your project, publish it shortly after the Hackathon end and add a link to it to your GitHub repository.
63 |
64 | For the general guidelines on judging projects, please refer to the [Official QCHack Hacking Rules 2021](https://docs.google.com/document/d/1_Jln3lIfNmYPlUtJ17zgwi5FQtNtzhHR-fH15QqW3xc/edit).
65 |
66 |
67 | ## Eligibility and prizes
68 |
69 | The (6) highest cumulative team scores from parts 1 and 2 of the challenge will receive a **$250 Visa Gift Card** (physical or virtual) for the team. The winning teams will have an opportunity to present their projects to the Microsoft Quantum Team, at a later date and time (to be scheduled after the results announcement).
70 |
71 | Government officials and Microsoft employees are not eligible to participate in this challenge.
72 |
73 | For the general rules on eligibility and prizes, please refer to the [Official QCHack Hacking Rules 2021](https://docs.google.com/document/d/1_Jln3lIfNmYPlUtJ17zgwi5FQtNtzhHR-fH15QqW3xc/edit).
74 |
75 | ## Resources
76 |
77 | Here is a list of resources to help you learn more about various parts of our challenge:
78 |
79 | #### Microsoft Quantum Development Kit installation
80 |
81 | For this Hackathon, you will need to install at least the [standalone QDK](https://docs.microsoft.com/en-us/azure/quantum/install-command-line-qdk), and possibly (depending on what kind of project you decide to do) integration with [Q# Jupyter Notebooks](https://docs.microsoft.com/en-us/azure/quantum/install-jupyter-qkd) or with [Python](https://docs.microsoft.com/en-us/azure/quantum/install-python-qdk).
82 |
83 | We also recommend you to install the [Quantum Katas](https://github.com/Microsoft/QuantumKatas/#kata-locally), since a lot of learning and practice resources in this list are from that resource.
84 |
85 | #### Quantum oracles (tutorials and programming exercises)
86 |
87 | * ["Oracles"](https://github.com/microsoft/QuantumKatas/blob/main/tutorials/Oracles) tutorial
88 | * [Microsoft's workshop at QCHack](https://www.twitch.tv/videos/979926267)
89 | * [Simple practice problems](https://github.com/microsoft/QuantumKatas/blob/main/DeutschJozsaAlgorithm)
90 | * Microsoft Learn module ["Solve graph coloring problems by using Grover's search"](https://docs.microsoft.com/en-us/learn/modules/solve-graph-coloring-problems-grovers-search/)
91 | * Microsoft Learn page ["Write an oracle to validate ISBNs"](https://docs.microsoft.com/en-us/learn/modules/use-qsharp-libraries/4-write-oracle)
92 |
93 | #### Grover's search algorithm (with more practice for oracles implementation)
94 |
95 | * Microsoft Learn module ["Solve graph coloring problems by using Grover's search"](https://docs.microsoft.com/en-us/learn/modules/solve-graph-coloring-problems-grovers-search/)
96 | * [Microsoft's workshop at QCHack](https://www.twitch.tv/videos/979926267)
97 | * [Simple Grover's search sample in Q#](https://github.com/microsoft/Quantum/tree/main/samples/algorithms/simple-grover) - an implementation for a trivial problem "find 0101... state", and an example of a standalone Q# project implementation
98 | * [Solving Sudoku using Grover's search](https://github.com/microsoft/Quantum/tree/main/samples/algorithms/sudoku-grover) - an implementation for a Sudoku solver, an example of more interesting oracles, and a template for calling Q# code from C# classical host
99 | * ["Implementing Grover's algorithm" kata](https://github.com/microsoft/QuantumKatas/blob/main/GroversAlgorithm) - step-by-step implementation of the algorithm itself
100 | * ["Exploring Grover's search algorithm" tutorial](https://github.com/microsoft/QuantumKatas/blob/main/tutorials/ExploringGroversAlgorithm) - exploring high-level behaviors of the algorithm, such as retrying in case of a failure, the required number of iterations, etc.
101 | * ["Solving SAT problems using Grover's algorithm" kata](https://github.com/microsoft/QuantumKatas/blob/main/SolveSATWithGrover) - practice implementing oracles and using Grover's algorithm to solve a problem
102 | * ["Solving graph coloring problems using Grover's algorithm" kata](https://github.com/microsoft/QuantumKatas/blob/main/GraphColoring) - practice implementing oracles and using Grover's algorithm to solve a problem
103 | * ["Solving bounded knapsack problem using Grover's algorithm" kata (work in progress)](https://github.com/microsoft/QuantumKatas/pull/457)
104 |
105 | ## Rules
106 |
107 | This page lists Microsoft additional unique rules for its Challenge, including judging criteria, submission guidelines, eligibility and prizes. Please refer to the [Official QCHack Hacking Rules 2021](https://docs.google.com/document/d/1_Jln3lIfNmYPlUtJ17zgwi5FQtNtzhHR-fH15QqW3xc/edit) for general QCHack rules.
108 |
109 |
110 | [](https://mybinder.org/v2/gh/quantumcoalition/qchack-microsoft-challenge/master)
111 |
--------------------------------------------------------------------------------