Instantly share code, notes, and snippets.

Embed
What would you like to do?
Getting PoSh with Q#
<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>
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;
}
}
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