Skip to content

Instantly share code, notes, and snippets.

@VincentTam
Created May 16, 2015 13:47
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save VincentTam/02528f23419952bf1bf5 to your computer and use it in GitHub Desktop.
Save VincentTam/02528f23419952bf1bf5 to your computer and use it in GitHub Desktop.
Programs related to number theory written in C++ when I was a high school student. I don't guarantee that they're error-free.
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <cstring>
#include <string.h>
#include <vector>
#include <stdio.h>
#include <stdlib.h>
using namespace std;
int main() {
//Explain the statement of Euler's Criterion
string statement("This program helps user to understand Euler's Criterion:\n");
statement = statement + "For any odd prime 𝑝 and natural number 𝑎 such that (𝑎,𝑝) = 1,\n";
statement = statement + "Let (𝑎|𝑝) ≡ 𝑎^[(𝑝 − 1)/2] (mod 𝑝) be the Legendre symbol, then\n\n";
statement = statement + "⎧ (𝑎|𝑝) = 1 if 𝑎 is a quadratic residue modulo 𝑝\n⎨\n";
statement = statement + "⎩ (𝑎|𝑝) = −1 if 𝑎 is a quadratic non-residue modulo 𝑝\n\n";
//Obtain input
int a = int();
int p = int();
int root = 0;
cout << statement << "Enter the value of odd prime 𝑝: ";
cin >> p;
cout << "Enter the value of 𝑎 which is BETWEEN 1 AND 𝑝 − 1: ";
cin >> a;
std::stringstream ss;
//Check whether a suits the format
if (a % p == 0 || p < 0 || a < 0) {
cerr << "Enter two coprime positive integers for the values of 𝑎 and 𝑝." << endl;
return 1;
}
//Create a list of numbers {1,2,...,p - 1}
vector<int> list;
for (int i = 1; i < p; i++) {
list.push_back(i);
}
//Sort the numbers into 𝑏 𝑏′≡ 𝑎 (mod 𝑝)
string str = "";//Contains the thing to be print
string listbody = "\nResults: \n";
cout << listbody;
while (!list.empty()) {
int b = list.at(0);
int originalSize = list.size();//Helps check if 𝑝 is prime
for (int i = 0; i < list.size(); i++) {
int instantHalf = list.at(i);
int instantProduct = b * instantHalf;
int remainder = instantProduct % p;
if (remainder == a) {
if (instantHalf == b) {
root = b;
ss << b << "² ≡ " << instantProduct << " ≡ " << remainder << " (mod " << p <<")\n";
list.erase(list.begin());
} else {
ss << b << " × " << instantHalf << "≡ " << instantProduct << " ≡ " << remainder << " (mod " << p << ")\n";
list.erase(list.begin()+i);
list.erase(list.begin());
}
str = ss.str();
cout << str;
listbody += str;
ss.str("");
str.clear();
break;
}
}
//Terminate the program if 𝑝 is not prime to avoid infinite loop
if (originalSize == list.size()) {
cerr << "Enter an odd prime for the value of 𝑝." << endl;
return 1;
}
}
//Print out the finding
if (root > 0) {
root = p - root;//so that the smaller number is shown
ss << "\n∵ " << root << "² ≡ " << root*root << " ≡ " << a << " (mod " << p << ")\n∴ " << a << " is a quadratic residue modulo " << p << ".\n";
} else {
ss << "\n∵ From the above list, there does NOT exist an integer 𝑥 such that 𝑥² ≡ " << a << " (mod " << p << ")\n∴ " << a << " is a quadratic non-residue modulo " << p << ".\n";
}
string finding = ss.str();
ss.str("");
cout << finding;
//Print out the explanation
ss << "\nBy the L.H.S. of the above list,\n product of {1,2,...,𝑝 − 1}\n≡ (" << p << " − " << 1 << ")! (mod " << p << ")\n≡ −1 (mod " << p << ") (Wilson's Thm.)\n";
string explanationL = ss.str();
ss.str("");
cout << explanationL;
string explanationR = "\nBy the R.H.S. of the above list,\n";
if (root == 0) {
explanationR += " product of {1,2,...,𝑝 − 1}\n≡ 𝑎^[(𝑝 − 1)/2]\n";
} else {
ss << explanationR << "∵ " << root << " × " << p - root << " ≡ " << root << " × −" << root << " ≡ −𝑎 (mod 𝑝)\n∴ product of {1,2,...,𝑝 − 1}\n≡ −𝑎^[(𝑝 − 1)/2] (mod 𝑝)\n";
explanationR = ss.str();
ss.str("");
}
cout << explanationR;
string explanation = "\nAfter equating both sides,\n";
/**Temporary value of the Legendre Symbol (If 𝑎 is QNR mod 𝑝, it'll be multiplied by -1)*/
int legendre = 1;
if (root == 0) {
explanation += "𝑎^[(𝑝 − 1)/2]≡ −1(mod 𝑝)";
legendre = -1;
} else {
explanation += "∵ −𝑎^[(𝑝 − 1)/2]≡ −1(mod 𝑝)";
explanation += "∴ 𝑎^[(𝑝 − 1)/2]≡ 1(mod 𝑝)";
}
explanation += "\nBy the definition of Legendre symbol,";
explanation += "(𝑎|𝑝) ≡ 𝑎^[(𝑝 − 1)/2] (mod 𝑝) = ";
ss << legendre;
explanation += ss.str();
ss.str("");
cout << explanation << endl;
//Check if the user needs to save the list
cout << "Would you like to save the above list? (Enter 'y' if yes. Otherwise, enter nothing.)";
string input;
cin >> input;
if (input != "y") {
return 0;
}
//Check if the file exists
char fileName [80];
int n;
n = sprintf(fileName,"QR%dmod%d.txt",a,p);
ifstream fin(fileName);
if (fin) {
// file exists
cout << fileName << " already exists. Please refer to that." << endl;
fin.close();
return 0;
}
else {
// file does not exist
fin.close();
}
ofstream fout(fileName);// creates file for output and destroys file contents if the file already exists.
fout << statement << listbody << finding << explanationL << explanationR << explanation;//Write contents to the file.
fout.close();//Close the file
return 0;
}
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <cstring>
#include <string.h>
#include <vector>
#include <stdio.h>
#include <stdlib.h>
using namespace std;
int main() {
//Explain the statement of Euler's Criterion
string statement("This program helps user to understand Euler's Criterion:\n");
statement = statement + "For any odd prime p and natural number a such that (a,p) = 1,\n";
statement = statement + "Let (a|p) = a^[(p - 1)/2] (mod p) be the Legendre symbol, then\n\n";
statement = statement + "(a|p) = 1 if a is a quadratic residue modulo p\n";
statement = statement + "(a|p) = -1 if a is a quadratic non-residue modulo p\n\n";
//Obtain input
int a = int();
int p = int();
int root = 0;
cout << statement << "Enter the value of odd prime p: ";
cin >> p;
cout << "Enter the value of a which is BETWEEN 1 AND p - 1: ";
cin >> a;
std::stringstream ss;
//Check whether a suits the format
if (a % p == 0 || p < 0 || a < 0) {
cerr << "Enter two coprime positive integers for the values of a and p." << endl;
return 1;
}
//Create a list of numbers {1,2,...,p - 1}
vector<int> list;
for (int i = 1; i < p; i++) {
list.push_back(i);
}
//Sort the numbers into b b′= a (mod p)
string str = "";//Contains the thing to be print
string listbody = "\nResults: \n";
cout << listbody;
while (!list.empty()) {
int b = list.at(0);
int originalSize = list.size();//Helps check if p is prime
for (int i = 0; i < list.size(); i++) {
int instantHalf = list.at(i);
int instantProduct = b * instantHalf;
int remainder = instantProduct % p;
if (remainder == a) {
if (instantHalf == b) {
root = b;
ss << b << "^2 = " << instantProduct << " = " << remainder << " (mod " << p <<")\n";
list.erase(list.begin());
} else {
ss << b << " * " << instantHalf << "= " << instantProduct << " = " << remainder << " (mod " << p << ")\n";
list.erase(list.begin()+i);
list.erase(list.begin());
}
str = ss.str();
cout << str;
listbody += str;
ss.str("");
str.clear();
break;
}
}
//Terminate the program if p is not prime to avoid infinite loop
if (originalSize == list.size()) {
cerr << "Enter an odd prime for the value of p." << endl;
return 1;
}
}
//Print out the finding
if (root > 0) {
root = p - root;//so that the smaller number is shown
ss << "\nSince " << root << "^2 = " << root*root << " = " << a << " (mod " << p << ")\ni.e. " << a << " is a quadratic residue modulo " << p << ".\n";
} else {
ss << "\nSince from the above list, there does NOT exist an integer x such that x^2 = " << a << " (mod " << p << ")\ni.e. " << a << " is a quadratic non-residue modulo " << p << ".\n";
}
string finding = ss.str();
ss.str("");
cout << finding;
//Print out the explanation
ss << "\nBy the L.H.S. of the above list,\n product of {1,2,...,p - 1}\n= (" << p << " - " << 1 << ")! (mod " << p << ")\n= -1 (mod " << p << ") (Wilson's Thm.)\n";
string explanationL = ss.str();
ss.str("");
cout << explanationL;
string explanationR = "\nBy the R.H.S. of the above list,\n";
if (root == 0) {
explanationR += " product of {1,2,...,p - 1}\n= a^[(p - 1)/2]\n";
} else {
ss << explanationR << "Since " << root << " * " << p - root << " = " << root << " * -" << root << " = -a (mod p)\ni.e. product of {1,2,...,p - 1}\n= -a^[(p - 1)/2] (mod p)\n";
explanationR = ss.str();
ss.str("");
}
cout << explanationR;
string explanation = "\nAfter equating both sides,\n";
/**Temporary value of the Legendre Symbol (If a is QNR mod p, it'll be multiplied by -1)*/
int legendre = 1;
if (root == 0) {
explanation += "a^[(p - 1)/2]= -1(mod p)";
legendre = -1;
} else {
explanation += "Since -a^[(p - 1)/2]= -1(mod p)";
explanation += "i.e. a^[(p - 1)/2]= 1(mod p)";
}
explanation += "\nBy the definition of Legendre symbol,";
explanation += "(a|p) = a^[(p - 1)/2] (mod p) = ";
ss << legendre;
explanation += ss.str();
ss.str("");
cout << explanation << endl;
//Check if the user needs to save the list
cout << "Would you like to save the above list? (Enter 'y' if yes. Otherwise, enter nothing.)";
string input;
cin >> input;
if (input != "y") {
return 0;
}
//Check if the file exists
char fileName [80];
int n;
n = sprintf(fileName,"QR%dmod%d.txt",a,p);
ifstream fin(fileName);
if (fin) {
// file exists
cout << fileName << " already exists. Please refer to that." << endl;
fin.close();
return 0;
}
else {
// file does not exist
fin.close();
}
ofstream fout(fileName);// creates file for output and destroys file contents if the file already exists.
fout << statement << listbody << finding << explanationL << explanationR << explanation;//Write contents to the file.
fout.close();//Close the file
return 0;
}
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
using namespace std;
//Return the least +ve residue
int congruence(int number, int N);
int gcd(int a, int b);
void printS(int number, int prime);
int Partition(int low,int high,int arr[]);
void Quick_sort(int low,int high,int arr[]);
int main(void) {
int a,p;
cout << "This program helps user to understand Gauss's Lemma:" << endl;
cout << "Let p be an ODD prime and a be any integer." << endl;
cout << "Supose S = {a,2a,3a,...,[(p-1)/2]*a}" << endl;
cout << "and n be the number of elements in S that is greater than p/2" << endl;
cout << "Then (a|p) = (-1)^n, where (a|p) is the Legendre symbol." << endl;
cout << "Enter an ODD prime p: ";
cin >> p;
cout << "Enter an integer a: ";
cin >> a;
if (congruence(a,p) != a) {
cout << a << " = " << congruence(a,p) << " (mod " << p << ")" << endl;
a = congruence(a,p);
}
if (gcd(a,p) != 1) {
char quit;
cerr << "Enter an ODD prime for the value of p!" << endl;
cout << "Press any key to continue.";
cin >> quit;
return 1;
}
printS(a,p);
return 0;
}
int congruence(int number, int N) {
if (N >= 0) {
return number % N;
} else {
return congruence(-(number/N-1)*N+number,N);
}
}
int gcd(int a, int b) {
if (a % b == 0) {
return b;
} else {
return gcd(b,a % b);
}
}
void printS(int number, int prime) {
cout << "S = {" << number;
int *list = new int[(prime - 1) / 2];
list[0] = number;
for (int i = 2; i <= (prime - 1) / 2; i++) {
list[i - 1] = number * i;
cout << "," << list[i - 1];
}
cout << "}" << endl;
cout << "Product of all elements in S" << endl;
cout << "= " << list[0];
for (int i = 1; i < (prime - 1) / 2; i++) {
cout << " * " << list[i];
}
cout << "\n= (1 * " << list[0] << ")";
for (int i = 1; i < (prime - 1) / 2; i++) {
cout << " * (" << i + 1 << " * " << number << ")";
}
cout << "\n= " << (prime - 1) / 2 << "! * " << number << "^" << (prime - 1) / 2 << endl;
cout << "= [(" << prime << " - 1) / 2]! * " << number << "^[(" << prime << " - 1) / 2]" << endl;
cout << "= [(p - 1) / 2]! * a^[(p - 1) / 2]" << endl;
cout << "= [(p - 1) / 2]! * (a|p) (mod p) (1)" << endl;
cout << "Figure out [(p - 1) / 2]! (mod p):" << endl;
cout << "Replace each element in S by its least +ve residue." << endl;
cout << "S' = {" << number;
for (int i = 2; i <= (prime - 1) / 2; i++) {
list[i - 1] = congruence(list[i - 1],prime);
cout << "," << list[i - 1];
}
cout << "}" << endl;
cout << "It's trivial that product of all elements in S = that in S' (mod p)" << endl;
cout << "i.e. Product of all elements in S' = [(p - 1) / 2]! * (a|p) (mod p) (2)" << endl;
cout << "Rearrange them in acsending order: " << endl;
Quick_sort(0,(prime - 1) / 2 - 1,list);
cout << "S' = {" << list[0];
for (int i = 1; i < (prime - 1) / 2; i++) {
cout << "," << list[i];
}
cout << "}" << endl;
int n = 0;
cout << "Replace every element b in S' that is greater than p/2 by p - b." << endl;
cout << "S\" = {" << list[0];
for (int i = 2; i <= (prime - 1) / 2; i++) {
if (list[i - 1] > prime / 2) {
list[i - 1] = prime - list[i - 1];
n++;
}
cout << "," << list[i - 1];
}
cout << "}" << endl;
cout << "The above list is actually a list of all natural numbers within " << "(p - 1) / 2 = (" << prime << " - 1) / 2 = " << (prime - 1)/2 << "." << endl;
cout << "n = " << n << endl;
cout << " Product of all elements in S\"" << endl;
cout << "= [(p - 1) / 2]! (3a)" << endl;
cout << "= " << (prime - 1)/2 << "!" << endl;
cout << "= " << list[0];
for (int i = 1; i < (prime - 1) / 2; i++) {
cout << " * " << list [i];
}
cout << "\n= " << list[0];
for (int i = 1; i < (prime - 1) / 2 - n; i++) {
cout << " * " << list [i];
}
for (int i = (prime - 1) / 2 - n; i < (prime - 1) / 2; i++) {
list[i] = prime - list [i];
cout << " * (" << prime << " - " << list [i] << ")";
}
cout << " (Write the product in terms of elements in S')" << endl;
cout << "= " << list[0];
for (int i = 1; i < (prime - 1) / 2 - n; i++) {
cout << " * " << list [i];
}
for (int i = (prime - 1) / 2 - n; i < (prime - 1) / 2; i++) {
cout << " * (- " << list [i] << ")";
}
cout << " (mod " << prime << ")\n= (-1)^" << n;
for (int i = 0; i < (prime - 1) / 2; i++) {
cout << " * " << list [i];
}
cout << " (mod " << prime << ")\n= (-1)^" << n << " * product of all elements in S' (mod " << prime << ")" << endl;
cout << "= (-1)^n * [(p - 1) / 2]! * (a|p) (mod p) (3b) (from (2))" << endl;
cout << "Since (3a) and (3b) represent the same thing mod p," << endl;
cout << "[(p - 1) / 2]! = (-1)^n * [(p - 1) / 2]! * (a|p) (mod p)" << endl;
cout << "(a|p) = (-1)^n" << endl;
}
int Partition(int low,int high,int arr[])
{ int i,high_vac,low_vac,pivot/*,itr*/;
pivot=arr[low];
while(high>low)
{ high_vac=arr[high];
while(pivot<high_vac)
{
if(high<=low) break;
high--;
high_vac=arr[high];
}
arr[low]=high_vac;
low_vac=arr[low];
while(pivot>low_vac)
{
if(high<=low) break;
low++;
low_vac=arr[low];
}
arr[high]=low_vac;
}
arr[low]=pivot;
return low;
}
void Quick_sort(int low,int high,int arr[])
{
int Piv_index,i;
if(low<high)
{
Piv_index=Partition(low,high,arr);
Quick_sort(low,Piv_index-1,arr);
Quick_sort(Piv_index+1,high,arr);
}
}
#include <iostream>
#include <fstream>
#include <math.h>
#include <time.h>
#include <assert.h>
#include <gmpxx.h>
#include <stdio.h>
#include <stdlib.h>
using namespace std;
int main() {
time_t start;//Record the time at the beginning
int numPrime;//Number of primes wanted
int primePerRow = 10;//Number of primes printed in each line
cout << "Enter the number of primes: ";
cin >> numPrime;
cout << "Enter the number of primes in each line: ";
cin >> primePerRow;
time (&start);//Record the time at the beginning
assert (numPrime > 0 & primePerRow > 1);//Abort the program if input isn't +ve
time_t end;//Record the time at the end
double timeElasped;//Total time elapsed
mpz_t* primeList = new mpz_t[numPrime];//Array of primes
//Initialize the first 2 elements with the first 2 primes
mpz_init_set_str(primeList[0],"2",10);
mpz_init_set_str(primeList[1],"3",10);
//Initialize the other elements of primeList to avoid segmentation fault
for (int i = 2; i < numPrime; i++) {
mpz_init(primeList[i]);
}
int sizePrimeList = 2;//Number of non-zero elements of primeList
//Print out what we have at first
cout << "The list of primes:" << endl;
cout << primeList[0] << "," << primeList[1];
mpz_t zero,two;
mpz_init_set_str(zero,"0",10);
mpz_init_set_str(two,"2",10);
mpz_t number;
mpz_t sqrtNumber;
mpz_init_set_str(number,"5",10);//Test primality of numbers starting from 5
mpz_init(sqrtNumber);
while (sizePrimeList < numPrime) {
mpz_sqrt(sqrtNumber,number);
bool isPrime = true;//Decide primality of number
for (int i = 0; mpz_cmp(primeList[i],sqrtNumber) < 1; i++) {
if (mpz_congruent_p(number,zero,primeList[i]) != 0) {
//number has a prime divisor
isPrime = false;
break;
}
}
if (isPrime) {
mpz_set(primeList[sizePrimeList],number);//Index in array is zero-based
sizePrimeList++;//One more element is added to primeList
if (sizePrimeList % primePerRow == 1) {
cout << endl;
} else {
cout << ",";
}
cout << number;
}
mpz_add(number,number,two);//Don't need to test even numbers
}
mpz_sub(number,number,two);//2 is added to number when it exits the while loop
char count [80];
char duration [80];
int s;
s = gmp_sprintf(count,"\n\nThere are %d primes between 1 and %Zd.",sizePrimeList,number);
cout << count << endl;
time (&end);//Record the time at the end
timeElasped = difftime (end,start);//Calculate the total time elapsed
s = gmp_sprintf(duration,"It took %f seconds to generate the list of primes.\n", timeElasped);
cout << duration << endl;
//Check if the user needs to save the list
cout << "Would you like to save the above list? (Enter 'y' if yes. Otherwise, enter nothing.)";
char input;
cin >> input;
if (input != 'y') {
return 0;
delete [] primeList;
primeList = NULL;
}
//Check if the file exists
char fileName [80];
int n;
n = gmp_sprintf(fileName,"PrimeList%Zd.txt",number);
ifstream fin(fileName);
if (fin) {
// file exists
cout << fileName << " already exists. Please refer to that." << endl;
fin.close();
return 0;
delete [] primeList;
primeList = NULL;
}
else {
// file does not exist
fin.close();
}
ofstream fout(fileName);// creates file for output and destroys file
//Print out the content
fout << "The list of primes:";
for (int i = 0; i < numPrime; i++) {
if (i % primePerRow == 0) {
fout << endl;
} else {
fout << ",";
}
fout << primeList[i];
}
fout << count << endl;
fout << duration;
//Clean up work
delete [] primeList;//When done, free memory pointed to by primeList
primeList = NULL;//Clear primeList to prevent using invalid memory reference
return 0;
}
#include <iostream>
#include <fstream>
#include <math.h>
#include <time.h>
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
using namespace std;
int main() {
time_t start,end;//Record the time at the beginning and the end
double timeElasped;//Total time elapsed
int* primeList = NULL; //Pointer to int, initialize to nothing
int numPrime;//Number of primes wanted
int primePerRow = 10;//Number of primes printed in each line
cout << "Enter the number of primes wanted: ";
cin >> numPrime;
cout << "Enter the number of primes in each line: ";
cin >> primePerRow;
time (&start);//Record the time at the beginning
assert (numPrime > 0 & primePerRow > 1);//Abort the program if input isn't +ve
primeList = new int[numPrime];//Array of primes
//Initialize the first 2 elements with the first 2 primes
primeList[0] = 2;
primeList[1] = 3;
int sizePrimeList = 2;//Number of non-zero elements of primeList
//Print out what we have at first
cout << "The list of primes:" << endl;
cout << primeList[0] << "," << primeList[1];
int number = 5;//Test primality of numbers starting from 5
while (sizePrimeList < numPrime) {
bool isPrime = true;//Decide primality of number
for (int i = 0; primeList[i] <= sqrt(number); i++) {
if (number % primeList[i] == 0) {
//number has a prime divisor
isPrime = false;
break;
}
}
if (isPrime) {
primeList[sizePrimeList] = number;//Index in array is zero-based
sizePrimeList++;//One more element is added to primeList
if (sizePrimeList % primePerRow == 1) {
cout << endl;
} else {
cout << ",";
}
cout << number;
}
number += 2;//Don't need to test even numbers
}
char count [80];
char duration [80];
int s;
s = sprintf(count,"\n\nThere are %d primes between 1 and %d.",sizePrimeList,(number-2));
cout << count << endl;
time (&end);//Record the time at the end
timeElasped = difftime (end,start);//Calculate the total time elapsed
s = sprintf(duration,"It took %f seconds to generate the list of primes.\n", timeElasped);
cout << duration << endl;
//Check if the user needs to save the list
cout << "Would you like to save the above list? (Enter 'y' if yes. Otherwise, enter nothing.)";
char input;
cin >> input;
if (input != 'y') {
return 0;
delete [] primeList;
primeList = NULL;
}
//Check if the file exists
char fileName [80];
int n;
n = sprintf(fileName,"PrimeList%d.txt",(number-2));
ifstream fin(fileName);
if (fin) {
// file exists
cout << fileName << " already exists. Please refer to that." << endl;
fin.close();
return 0;
delete [] primeList;
primeList = NULL;
}
else {
// file does not exist
fin.close();
}
ofstream fout(fileName);// creates file for output and destroys file
//Print out the content
fout << "The list of primes:";
for (int i = 0; i < numPrime; i++) {
if (i % primePerRow == 0) {
fout << endl;
} else {
fout << ",";
}
fout << primeList[i];
}
fout << count << endl;
fout << duration;
//Clean up work
delete [] primeList;//When done, free memory pointed to by primeList
primeList = NULL;//Clear primeList to prevent using invalid memory reference
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment