├── 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 | [![Binder](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/quantumcoalition/qchack-microsoft-challenge/master) 111 | --------------------------------------------------------------------------------