Last active
December 3, 2018 19:37
-
-
Save cgranade/ae96f866edae67c6550a93cf463a8f43 to your computer and use it in GitHub Desktop.
Getting PoSh with Q#
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<Project Sdk="Microsoft.NET.Sdk"> | |
<PropertyGroup> | |
<TargetFramework>netstandard2.0</TargetFramework> | |
</PropertyGroup> | |
<ItemGroup> | |
<PackageReference Include="Microsoft.Quantum.Canon" Version="0.3.1811.1501-preview" /> | |
<PackageReference Include="Microsoft.Quantum.Development.Kit" Version="0.3.1811.1501-preview" /> | |
<PackageReference Include="PowerShellStandard.Library" Version="5.1.0-RC1" /> | |
</ItemGroup> | |
</Project> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
namespace Quantum.Advent.PoSh { | |
// The MResetX operation is provided by the canon, so we open that here. | |
open Microsoft.Quantum.Canon; | |
/// # Summary | |
/// Implements a quantum random number generator (QRNG) by preparing a qubit | |
/// in the |0⟩ state and then measuring it in the 𝑋 basis. | |
/// | |
/// # Output | |
/// Either `Zero` or `One` with equal probability. | |
operation NextRandomBit() : Int { | |
mutable result = 1; | |
using (qubit = Qubit()) { | |
// We use the ternary operator (?|) to turn the Result from | |
// MResetX into an Int to match how the C# RNG works. | |
set result = MResetX(qubit) == One ? 1 | 0; | |
} | |
return result; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Linq; | |
// This namespace provides the API that we need to implement | |
// to interact with PowerShell. | |
using System.Management.Automation; | |
// This namespace provides the target machine that we will use to run our Q# | |
// code. | |
using Microsoft.Quantum.Simulation.Simulators; | |
namespace Quantum.Advent.PoSh | |
{ | |
// Each cmdlet is a class that inherits from Cmdlet, and is given | |
// a name with the CmdletAttribute attribute. | |
// Here, for instance, we define a new class that is exposed to | |
// PowerShell as the Get-DieRoll cmdlet. | |
[Cmdlet(VerbsCommon.Get, "DieRoll")] | |
public class GetDieRoll : Cmdlet | |
{ | |
// Our cmdlet class can have whatever private member variables, | |
// just as any other C# class. | |
private Random rng = new Random(); | |
// We can expose properties as command-line parameters using | |
// ParameterAttribute. | |
// For instance, this property is exposed as the -NSides command- | |
// line parameter, and allows the user to select what kind of die | |
// they want to roll. | |
[Parameter] | |
public int NSides { get; set; } = 6; | |
[Parameter] | |
public int NRolls { get; set; } = 1; | |
// The main logic to any cmdlet is implemented in the ProcessRecord | |
// method, which is called whenever the cmdlet receives new data from | |
// the pipeline. | |
protected override void ProcessRecord() | |
{ | |
foreach (var idxRoll in Enumerable.Range(0, NRolls)) | |
{ | |
// The WriteObject method lets us send new data out to the | |
// pipeline. If there's no other commands to receive that data, | |
// then it is printed out to the console. | |
WriteObject(rng.Next(1, NSides + 1)); | |
} | |
} | |
} | |
[Cmdlet(VerbsCommon.Get, "CoinFlip")] | |
public class GetCoinFlip : Cmdlet | |
{ | |
[Parameter] | |
public int NFlips { get; set; } = 1; | |
protected override void ProcessRecord() | |
{ | |
// This time we make a new target machine that we can use to run the | |
// QRNG. | |
using (var sim = new QuantumSimulator()) | |
{ | |
// The foreach loop is the same as before, except that we call into | |
// Q# in each iteration instead of calling methods of a Random | |
// instance. | |
foreach (var idxFlip in Enumerable.Range(0, NFlips)) | |
{ | |
WriteObject(NextRandomBit.Run(sim).Result); | |
} | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment