In the following, we review some Silq solutions to Microsoft’s Q# Summer
2018 and Winter
2019 coding contest on Codeforces.
Detailed solutions targeted for Q# programmers are available for both
2018
and 2019.
Generate Superposition of Zero State and a Basis State
Given classical bits $b \in 𝔹^n$ with $b[0]=1$, return state $\frac{1}{\sqrt{2}}
\Big(\ket{b}+\ket{0} \Big)$, where $\ket{0}$ is represented using $n$ bits.
Solution
The following solution in particular leverages
vectors (𝔹^n),
Hadamard transform (H)
inline conditionals (if-then-else)
type annotations (0:𝔹)
type casts (as int[n] and as 𝔹^n), and
forget
defsolve[n:!ℕ](bits:!𝔹^n){// prepare superposition between 0 and 1x:=H(0:𝔹);// prepare superposition between bits and 0qs:=ifxthenbitselse(0:int[n])as𝔹^n;// uncompute xforget(x=qs[0]);// valid because `bits[0]==1`returnqs;}// EXAMPLE CALLdefmain(){// example usage for bits=1, n=2x:=1:!int[2];y:=xas!𝔹^2;returnsolve(y);}
defsolve(k:!ℕ){// produce uniform superposition over k-bit uintsi:=0:uint[k];forjin[0..k){i[j]:=H(i[j]);}// invert i-th qubits (results in correct state, but entangled with i)qs:=vector(2^k,0:𝔹);qs[i]=X(qs[i]);// uncompute iforget(i=λ(qs:𝔹^(2^k))lifted{// function to reconstruct i from qsi:=0:uint[k];forjin[0..2^k){ifqs[j]{// in the superposition's summand where qs[j]==1, i==ji=jasuint[k];}}returni;}(qs));// return resultreturnqs;}// EXAMPLE CALLdefmain(){// example usage for k=2returnsolve(2);}
You may modify the given qubit arbitrarily (including measurements).
Solution
Key Insights:
$\psi_0 \perp \psi_1$: The two states are orthogonal.
$\psi_0$ can be transformed to the W state on 3 qubits $W_3$. This process
trasnforms $\psi_1$ to some state $\psi_1’$ orthogonal to $W_3$.
We can generate $W_3$ from $\ket{000}$ (see Problem A4
above). Reversing this process generates $\ket{000}$
from $W_3$, and a state orthogonal to $\ket{000}$ from $\psi_1’$.
The following solution in particular leverages:
decomposing lists: (head,)~tail:=qs
reverse of a recursive function
deftoW[n:!ℕ](qs:𝔹^n)mfree:𝔹^n{// for a single bit, prepare |1⟩ifn==1{qs[0]:=X(qs[0]);}elseifn>1{// split qs into head (first element) and tail (rest)(head,)~tail:=qs;// prepare first bitθ:=2·asin(1/sqrt(n));// sin(θ/2)=1/sqrt(n), cos(θ/2)=sqrt((n-1)/n)head:=rotY(θ,head);// |0⟩ ↦ cos(θ/2)|0⟩ + sin(θ/2)|1⟩ = cos(θ/2) |0⟩ + 1/sqrt(n)|1⟩// prepare remaining bitsif!head{tail:=toW(tail);}// combine head and tail againqs:=(head,)~tail;}returnqs;}defsolve(qs:𝔹^3):!ℕ{// transform ψ₀ to W₃ifqs[1]{phase(-2·π/3);}// exp(2*i*π/3)*exp(i*-2*π/3)=1ifqs[2]{phase(-4·π/3);}// exp(4*i*π/3)*exp(i*-4*π/3)=1// map W₃ to |000⟩qs:=reverse(toW[3])(qs);// check if obtained |000⟩returnmeasure(qsasint[3])!=0;}// EXAMPLE CALLdefgenerate_input_state(state:!𝔹){// prepare ψ_0 (state=false) or ψ_1 (state=true)qs:=vector(3,0:𝔹);qs:=toW[3](qs);ifstate{ifqs[1]{phase(4·π/3);}elseifqs[2]{phase(2·π/3);}}else{ifqs[1]{phase(2·π/3);}elseifqs[2]{phase(4·π/3);}}returnqs;}defmain(){// expected outcome: (0,1)// prepare both statesψ_0:=generate_input_state(false);ψ_1:=generate_input_state(true);check0:=solve(ψ_0);check1:=solve(ψ_1);return(check0,check1);}
A bit string of length $n$ is considered periodic with period $P$ ($1 \leq P
\leq n-1$) if for all $i \in {0,\dots, n-P-1}$, $x_i=x_{i+P}$.
Solution
The following solution in particular leverages
Automatic uncomputation of y and z when they are overwritten
defsolve[n:!ℕ](x:𝔹^n)lifted{y:=0:𝔹;// Check all possible periods.// Periods with P<(n+1)/2 are implicitly detected by period 2P because P<=(n+1)/2-1 implies 2P<=n-1.forpin[(n+1)div2..n){// check period pz:=1:𝔹;foriin[0..n-p){z&=x[i]==x[i+p];}y|=z;}returny;}// EXAMPLE CALLdefmain(){// expected outcome: (0,1)ap:=solve((true,true,false));p:=solve((false,false,false));return(ap,p);}
Implement a unitary operation on $n$ qubits which is represented by a square
matrix of size $2^n$ which has non-zero elements on both main diagonal and
anti-diagonal and zero elements everywhere else.
For example, for $n=3$, the matrix of the operation should have the following
shape:
Here, X denotes a “non-zero” element of the matrix, and . denotes a “zero”
element of the matrix.
The row and column indices of the matrix follow little endian format: The least
significant bit of the index is stored first in the qubit array. Thus, the
second column of the matrix gives you the coefficients of the basis states
you’ll get if you apply the unitary to the $\ket{10…0}$ basis state.
Solution
Key insight: A possible solution is mapping $\ket{b_1 \cdots b_n}$ to
$\frac{1}{\sqrt{2}}\ket{b_1 \cdots b_n} \pm
\frac{1}{\sqrt{2}}\ket{\overline{b_1} \cdots \overline{b_n}}$, where
$\overline{b_i}=1-b_i$. This is because the diagonal from top-left to
bottom-right captures the identity, and the diagonal from bottom-left to
top-right captures the mapping from $v$ to $N-v$ (where $N-v$ can be computed by
inverting all bits of $v$).
The following solution in particular leverages
swapping entries of a vector with other values
defsolve[n:!ℕ](qs:𝔹^n){x:=0:𝔹;// swap x with LSB of qs// necessary because Silq would block `qs` in the body of `if qs[0] {...}`(x,qs[0]):=(qs[0],x);ifx{// flip all other bits if LSB=1foriin[1..n){qs[i]:=X(qs[i]);}}x:=H(x);// map LSB to 1/√̅2 (|0⟩±|1⟩)ifx{// flip all other bits if LSB=1// - if LSB was originally 0, this flips the bits iff H flipped the LSB// - if LSB was originally 1, this leaves the other bits flipped// if H flipped the LSB and restores the other bits otherwiseforiin[1..n){qs[i]:=X(qs[i]);}}// swap x back(qs[0],x):=(x,qs[0]);forget(x=0);returnqs;}// EXAMPLE CALLdefmain(){// example usage for N=3x:=0:!int[3];y:=xas𝔹^3;returnsolve(y);}