\(\langle Program \rangle\)
// 可印出N面量子骰程式的程式 //
#include <algorithm>
#include <cmath>
#include <fstream>
#include <iostream>
#include <string>
#include <vector>
using namespace std;
vector<std::string> Ry;
short CCXcount;
// 使用輾轉相除法化簡分數 a/b
void Simp(int a, int b) {
int Ta = a, Tb = b;
while(a != 0 && b != 0) {
if(a > b) a %= b;
else b %= a;
}
CCXcount++;
Ry.push_back(to_string(Ta/max(a, b)) + '/' + to_string(Tb/max(a, b)));//將化簡完的分數儲存於 Ry 旋轉紀錄矩陣中
}
string ry(string ry, int c) {
return "circuit.ry(2*asin(sqrt(" + ry + ")), " + to_string(c) + ")";
}
string cry(string ry, int c1, int c2) {
return "circuit.cry(2*asin(sqrt(" + ry + ")), " + to_string(c1) + ", " + to_string(c2) + ")";
}
string CircuitMeasure(short QB) {
string D;
for(short i = 0; i < QB; i++) D.append(to_string(i)), D.append(", ");
D.erase(D.end() - 2, D.end());
return "circuit.measure([" + D + "], [" + D + "])\n";
}
int main() {
int N, T;
vector<short> A;
cin >> N;
T = ceil(log2(N));
if(log2(N) != int(log2(N))) { //判別N是否為2^n
for(int I = pow(2, ceil(log2(N) - 1)); I >= 1; I /= 2) {
if(N < I) A.push_back(0), Ry.push_back("0");
else if(N >= I) {
if(N > I) Simp(N - I, N);
N -= I;
A.push_back(1);
if(N == 0) break;
}
}
}
else A.push_back(-1);
std::fstream File;
File.open("D:\\QDC.txt", std::ios::out | std::ios::trunc);
int SH; //Stable_H
int LA, AC = 0; //Last_active & Active_count
int pAC, dq; //pre - Active_Count & Differential_qubit
if(A[0] == -1) goto skip;
for(int i = 0; i < A.size(); i++) if(A[i] == 1) pAC++;
if(pAC == 1) dq = 0;
else if(pAC == 2) dq = 1;
else if(pAC >= 3) dq = 2;
File << "from math import *\n";
File << "circuit = QuantumCircuit(" << T + dq << ", " << T << ")\n";
SH = T - A.size();
for(int i = 0; i < A.size() - 1; i++) {
if(A[i] == 1) {
AC++;
if(i == 0) {
File << ry(Ry[0], T - 1) << "\n";
File << "circuit.barrier()\n";
File << "circuit.x(" << T - 1 << ")\n";
for(int j = T - 2; j >= SH; j--) File << "circuit.ch(" << T - 1 << ", " << j << ")\n";
File << "circuit.x(" << T - 1 << ")\n";
File << "circuit.barrier()\n";
}
else {
File << cry(Ry[i], LA, T - 1 - i) << "\n";
File << "circuit.barrier()\n";
//判別 0的 ccX
if(AC >= 4) File << "circuit.reset(" << T + (AC % 2) << ")\n";
File << "circuit.x(" << T - 1 - i << ")\n";
File << "circuit.ccx(" << T - 1 - i << ", " << LA << ", " << T + (AC % 2) << ")\n";
File << "circuit.x(" << T - 1 - i << ")\n";
File << "circuit.barrier()\n";
for(int j = T - 2 - i; j >= SH; j--) File << "circuit.ch(" << T + (AC % 2) << ", " << j << ")\n";
File << "circuit.reset(" << T + (AC % 2) << ")\n";
File << "circuit.barrier()\n";
//判別 1的 ccX
if(i < CCXcount - 1) {
File << "circuit.ccx(" << T - 1 - i << ", " << LA << ", " << T + (AC % 2) << ")\n";
File << "circuit.barrier()\n";
}
}
if(i == 0) LA = T - 1;
else if(A[i] == 1 && i != 0) LA = T + (AC % 2);
}
}
for(int j = 0; j < SH; j++) File << "circuit.h(" << j << ")\n";
File << "circuit.barrier()\n";
skip:
if(A[0] == -1) {
for(int i = 0; i < T; i++) File << "circuit.h(" << i << ")\n";
File << "circuit.barrier()\n";
}
File << CircuitMeasure(T);
File.close();
}
(working on project...)
#include <iostream>
#include <fstream>
#include <vector>
#include <string>
#include <cmath>
#include <algorithm>
using namespace std;
int S_H = 0;
vector<int> N_Fac;
vector<int> N_sFac;
vector<int> N_sFac_c;
vector<int> N_CCXcount;
vector<vector<short>> Ap_i;
vector<vector<string>> Pp_i;
bool is_prime(int k) {
for(int i = 2; i <= sqrt(k); i++) {
if(k%i == 0 && k != i) return false;
}
return true;
}
int fac_N(int N) {
int i = 2;
while(1) {
if(is_prime(N)) break;
else if(is_prime(i) && N%i == 0) {
N_Fac.push_back(i);
N/=i;
}
else i++;
}
N_Fac.push_back(N);
}
int Cc; //CCXcount
vector<string> Ry_N;
void Simp(int a, int b) {
int Ta = a, Tb = b;
while(a != 0 && b != 0) {
if(a > b) a %= b;
else b %= a;
}
Cc++;
Ry_N.push_back(to_string(Ta/max(a, b)) + '/' + to_string(Tb/max(a, b)));
}
void Nface_Data(int N) {
Cc = 0;
Ry_N.clear();
vector<short> A_N;
for(int I = pow(2, ceil(log2(N) - 1)); I >= 1; I /= 2) {
if(N < I) A_N.push_back(0), Ry_N.push_back("0");
else {
if(N > I) Simp(N - I, N);
N -= I;
A_N.push_back(1);
if(N == 0) break;
}
}
Pp_i.push_back(Ry_N);
Ap_i.push_back(A_N);
N_CCXcount.push_back(Cc);
}
void simpN_Fac() {
int i = 0;
while(i < N_Fac.size()) {
int l_pi = 1;
if(i != N_Fac.size() - 1) {
int j = i+1;
while(N_Fac[i] == N_Fac[j]) l_pi++, j++;
}
N_sFac.push_back(N_Fac[i]);
N_sFac_c.push_back(l_pi);
i += l_pi;
}
}
void H_pre_simp() {
S_H += N_sFac_c[0];
N_sFac.erase(N_sFac.begin(), N_sFac.begin() + 1);
N_sFac_c.erase(N_sFac_c.begin(), N_sFac_c.begin() + 1);
}
vector<string> Measure_qubits;
vector<short> N_sneeded_qcount;
short _needed_bcount;
void qubit_need_measure() {
short loc = S_H;
for(int i = 0; i < Ap_i.size(); i++) {
int T = ceil(log2(N_sFac[i]));
int pre_AC = 0, data_qc = 0; //pre activecount & data qubit count
for(int j = 0; j < Ap_i[i].size(); j++) if(Ap_i[i][j] == 1) pre_AC++;
if(pre_AC <= 2) data_qc = 0;
else if(pre_AC == 3) data_qc = 1;
else if(pre_AC >= 4) data_qc = 2;
N_sneeded_qcount.push_back(T+data_qc);
_needed_bcount += T*N_sFac_c[i];
//load uti-measure qubit
for(int k = 0; k < N_sFac_c[i]; k++) {
for(int l = loc; l < T+loc; l++) Measure_qubits.push_back(to_string(l));
loc += T+data_qc;
}
}
}
string ry(string ry, int c) {
return "circuit.ry(2*asin(sqrt(" + ry + ")), " + to_string(c) + ")";
}
string cry(string ry, int c1, int c2) {
return "circuit.cry(2*asin(sqrt(" + ry + ")), " + to_string(c1) + ", " + to_string(c2) + ")";
}
string CircuitMeasure() {
string Q = "circuit.measure([";
for(int i = 0; i < S_H; i++) Q.append(to_string(i) + ", ");
for(int i = 0; i < Measure_qubits.size(); i++) Q.append(Measure_qubits[i] + ", ");
Q.erase(Q.end() - 2, Q.end());
Q.append("], [");
for(int i = 0; i < _needed_bcount + S_H; i++) Q.append(to_string(i) + ", ");
Q.erase(Q.end() - 2, Q.end());
Q.append("])");
return Q;
}
string Barrier(short ini, short end) {
string Q = "circuit.barrier([";
for(int i = ini; i >= end; i--) Q.append(to_string(i) + ", ");
Q.erase(Q.end() - 2, Q.end());
Q.append("])");
return Q;
}
int main() {
//input N
int N;
cin >> N;
fac_N(N); //factorize N
simpN_Fac(); //simp the facs if N
N_Fac.clear(); //discard the old fac_vector
if(N_sFac[0] == 2) H_pre_simp(); //pre-count H
for(int i = 0; i < N_sFac.size(); i++) Nface_Data(N_sFac[i]); //make infor of N
//setup file
std::fstream File;
File.open("D:\\QDC.txt", std::ios::out | std::ios::trunc);
File << "from math import *\n";
//pre_count all needed qubit
qubit_need_measure();
short _needed_qcount = 0;
for(int i = 0; i < N_sFac.size(); i++) _needed_qcount += N_sneeded_qcount[i]*N_sFac_c[i];
File << "circuit = QuantumCircuit(" << _needed_qcount + S_H << ", " << _needed_bcount + S_H << ")\n";
File << "\n";
if(S_H != 0) {
File << "#2-facedice\n" << endl;
for(int i = 0; i < S_H; i++) File << "circuit.h(" << i << ")\n";
File << "\n";
}
short used_qc = S_H;
for(int i = 0; i < N_sFac.size(); i++) { //i is the Ni face
File << "#" << N_sFac[i] << "-facedice\n";
for(int j = 0; j < N_sFac_c[i]; j++) { //j is Ni^j
int T = ceil(log2(N_sFac[i]));
File << "\n";
int LA, AC = 0; //Last_active & Active_count
for(int k = 0; k < Ap_i[i].size() - 1; k++) { //k is the element in A_Ni
if(Ap_i[i][k] == 1) {
AC++;
if(k == 0) {
File << ry(Pp_i[i][0], T - 1 + used_qc) << "\n";
File << Barrier(T - 1 + used_qc, used_qc) << "\n";
File << "circuit.x(" << T - 1 + used_qc << ")\n";
for(int l = T - 2; l >= 0; l--) File << "circuit.ch(" << T - 1 + used_qc << ", " << l + used_qc << ")\n";
File << "circuit.x(" << T - 1 + used_qc << ")\n";
File << Barrier(T - 1 + used_qc, used_qc) << "\n";
}
else {
File << cry(Pp_i[i][k], LA, T - 1 - k + used_qc) << "\n";
File << Barrier(T - 1 + used_qc, used_qc) << "\n";
if(AC >= 4) File << "circuit.reset(" << T + (AC % 2) + used_qc << ")\n";
File << "circuit.x(" << T - 1 - k + used_qc << ")\n";
File << "circuit.ccx(" << T - 1 - k + used_qc << ", " << LA << ", " << T + (AC % 2) + used_qc << ")\n";
File << "circuit.x(" << T - 1 - k + used_qc << ")\n";
File << Barrier(T - 1 + used_qc, used_qc) << "\n";
for(int l = T - 2 - k; l >= 0; l--) File << "circuit.ch(" << T + (AC % 2) + used_qc << ", " << l + used_qc << ")\n";
if(AC >= 4) File << "circuit.reset(" << T + (AC % 2) + used_qc << ")\n";
File << Barrier(T - 1 + used_qc, used_qc) << "\n";
if(k < N_CCXcount[i] - 1) {
File << "circuit.ccx(" << T - 1 - k + used_qc << ", " << LA << ", " << T + (AC % 2) + used_qc << ")\n";
File << Barrier(T - 1 + used_qc, used_qc) << "\n";
}
}
if(k == 0) LA = T - 1 + used_qc;
else if(Ap_i[i][k] == 1 && k != 0) LA = T + (AC % 2) + used_qc;
}
}
used_qc += N_sneeded_qcount[i];
}
File << "\n";
}
File << "circuit.barrier()\n";
File << CircuitMeasure();
File.close();
//f^-1 feature
string S;
cin >> S;
vector<int> query;
for(short i = 0; i < N_sFac.size(); i++) {
for(short j = 0; j < N_sFac_c[i]; j++) {
short T = ceil(log2(N_sFac[i])), num = 0;
for(short k = 0; k < T; k++) num += pow(2, T - k - 1)*(int(S[k]) - 48);
num++;
query.push_back(num);
S.erase(S.begin(), S.begin()+T);
}
}
long long int res = 1;
for(auto i : query) res *= i;
cout << res << "\n";
return 0;
}