I'm trying to work through pset1 in Harvard's CS50 class through edX/ iTunesU and I'm attempting to program Luhn's algorithm. The below code is very incomplete but I wanted to know how to use pow() within a for loop and utilizing i within pow(). Presumably, there is another way to program Luhn's algorithm without using pow(), but exploring this method has brought this question to my attention. Any suggestions?
#include <stdio.h>
#include <cs50.h>
#include <math.h>
int main(void) {
long long c = 1234123412341234;
long long temp_c = c;
long long temp_c_one = c;
long long c_one_x = 0;
int count = 0;
while (temp_c > 0LL) {
temp_c = temp_c / 10LL;
count++;
}
for (int i = 0; i < count; i++) {
c_one_x = (temp_c_one % (pow(10, (i + 1))) / (pow(10, i));
count--;
}
}
You can avoid the use of pow by having a counter which you multiply by 10 every loop iteration.
#include <stdio.h>
#include <cs50.h>
#include <math.h>
int main(void) {
long long c = 1234123412341234;
long long temp_c = c;
long long temp_c_one = c;
long long c_one_x = 0;
long long pwr = 1; // 10^0 = 1
int count = 0;
while (temp_c > 0LL) {
temp_c = temp_c / 10LL;
count++;
}
// TODO: Don't think you should decrement count in this loop
for (int i = 0; i < count; i++) {
c_one_x = (temp_c_one % (pwr * 10)) / pwr;
count--;
pwr *= 10;
}
}
However, I'm not convinced you have produced a good Luhns algorithm implementation, so my suggestion is:
// Better Luhn's algorithm
int luhn( long long cc) {
unsigned long check = 0;
unsigned int digit;
for (int i = 0; cc > 0; i++) {
digit = cc % 10;
// double every second digit
if (i % 2) {
digit *= 2;
digit = (digit >= 10) ? (digit + 1) % 10 : digit;
}
check += digit;
cc = cc/10; // next CC digit.
}
return check;
}
int main (void) {
long long c = 1234123412341234;
print "Result is : %d", luhn(c));
}
Related
I have a program that looks something like this. i would like to run my if else query by probability.
int main() {
int probability = 70; //<-- 70% probability to run if statement
for (int i = 0; i < 5e5; i++){
if (???){
...
}
else {
...
}
}
return 0;
}
As #user3386109 pointed out, if(rand() % 100 < chance) is probably more then sufficient. As explained in the C FAQ, when the random number generated is not a multiple of 100, here, this method causes some numbers to appear more than others. If it falls on the range where it makes a difference, the easiest thing is to draw another number.
#include <stdio.h>
#include <stdlib.h> /* rand() */
#include <time.h> /* clock() */
/** http://c-faq.com/lib/randrange.html */
static int rand_0_99(void) {
unsigned int x = (RAND_MAX + 1u) / 100;
unsigned int y = x * 100;
unsigned int r;
do r = rand();
while(r >= y);
return r / x;
}
int main(void) {
size_t i, cumulate = 0;
const size_t replicas = 1000000;
const int chance_100 = 70;
/* Seed the linear congruential generator with the time. */
srand((unsigned)clock());
for(i = 0; i < replicas; i++) {
const int decision = rand_0_99() < chance_100;
if(decision) cumulate++;
}
printf("P(r < %d/100) = %lu/%lu\n",
chance_100, (unsigned long)cumulate, (unsigned long)replicas);
return EXIT_SUCCESS;
}
This is overkill, but may be needed, especially when 100 is close to RAND_MAX.
Had no luck getting it to work properly with OpenMP.
Things to look out for when doing this with multithreading:
compare runs to the current longest runs in the right order i.e. {123,124,125} not {124,123,125} because some threads finish faster than others.
I have no idea how to transform the do-while loop I'm currently using into an equivalent OMP FOR loop
One idea I had is putting the results of each thread in a run into an array, sorting it and then comparing bit by bit, again, no luck on implementing that.
Here comes the current working (sequential) code:
#include <stdio.h>
#include <stdlib.h>
void main() {
unsigned __int64 a = 0; //running function value
unsigned __int64 r = 0; //current starting value
unsigned __int64 count = 0; //current tree length
unsigned __int64 champ_r = 0; //number with the longest tree
unsigned __int64 champ_count = 0; //number of steps in the longest treetree
do {
count = 0; //reset tree length
r++; //set up the next starting value
a = r;
do {
if (a % 2 != 0) {
a = a * 3 + 1;
count++;
}
if (a % 2 == 0) {
a = a / 2;
count++;
}
} while (a != 1);
if (champ_count <= count) {
champ_r = r;
champ_count = count;
printf("\nNumber of steps for %llu: %llu", champ_r, champ_count);
}
} while (1);
}
And yes, it just keeps running,...
Also, I'm using ULL's because why not, might as well run forever.
Good luck!
PS. Other improvements to speed up the code are always appreciated.
EDIT1: switched to unsigned __int64 instead of unsigned long long
EDIT2: This is where I'm currently at, works, but slow
#include <stdio.h>
#include <stdlib.h>
#include <omp.h>
void main() {
unsigned __int64 a = 0; //running function value
unsigned __int64 r = 1; //current starting value
unsigned __int64 count = 1; //current tree length
unsigned __int64 champ_r = 0; //number with the longest tree
unsigned __int64 champ_count = 0; //number of steps in the longest tree
do {
#pragma omp parallel private(count) private(a)
{
r++;
a = r;
count = 1;
#pragma omp for
for (int x = 2; x > 1; x++) {
if (a % 2 != 0) {
a = a * 3 + 1;
x = a - 1;
count++;
} else if (a % 2 == 0) {
a = a / 2;
x = a - 1;
count++;
}
}
#pragma omp critical
{
if (champ_count < count) {
champ_r = r;
champ_count = count;
printf("\nAnzahl der Schritte f\x81r %llu : %llu", champ_r, champ_count);
}
count = 1;
}
}
} while (1);
}
There are several fast algorithms to calculate prime numbers up to a given number n. But, what is the fastest implementation to list all the numbers r relatively prime to some number n in C? That is, find all the elements of the multiplicative group with n elements as efficiently as possible in C. In particular, I am interested in the case where n is a primorial.
The n primorial is like the factorial except only prime numbers are multiplied together and all other numbers are ignored. So, for example 12 primorial would be 12#=11*7*5*3*2.
My current implementation is very naive. I hard code the first 3 groups as arrays and use those to create the larger ones. Is there something faster?
#include "stdafx.h"
#include <stdio.h> /* printf, fgets */
#include <stdlib.h> /* atoi */
#include <math.h>
int IsPrime(unsigned int number)
{
if (number <= 1) return 0; // zero and one are not prime
unsigned int i;
unsigned int max=sqrt(number)+.5;
for (i = 2; i<= max; i++)
{
if (number % i == 0) return 0;
}
return 1;
}
unsigned long long primorial( int Primes[], int size)
{
unsigned long long answer = 1;
for (int k = 0;k < size;k++)
{
answer *= Primes[k];
}
return answer;
}
unsigned long long EulerPhi(int Primes[], int size)
{
unsigned long long answer = 1;
for (int k = 0;k < size;k++)
{
answer *= Primes[k]-1;
}
return answer;
}
int gcd( unsigned long long a, unsigned long long b)
{
while (b != 0)
{
a %= b;
a ^= b;
b ^= a;
a ^= b;
}
//Return whethere a is relatively prime to b
if (a > 1)
{
return false;
}
return true;
}
void gen( unsigned long long *Gx, unsigned int primor, int *G3)
{
//Get the magic numbers
register int Blocks = 30; //5 primorial=30.
unsigned long long indexTracker = 0;
//Find elements using G3
for (unsigned long long offset = 0; offset < primor; offset+=Blocks)
{
for (int j = 0; j < 8;j++) //The 8 comes from EulerPhi(2*3*5=30)
{
if (gcd(offset + G3[j], primor))
{
Gx[indexTracker] = offset + G3[j];
indexTracker++;
}
}
}
}
int main(int argc, char **argv)
{
//Hardcoded values
int G1[] = {1};
int G2[] = {1,5};
int G3[] = {1,7,11,13,17,19,23,29};
//Lazy input checking. The world might come to an end
//when unexpected parameters given. Its okey, we will live.
if (argc <= 1) {
printf("Nothing done.");
return 0;
}
//Convert argument to integer
unsigned int N = atoi(argv[1]);
//Known values
if (N <= 2 )
{
printf("{1}");
return 0;
}
else if (N<=4)
{
printf("{1,5}");
return 0;
}
else if (N <=6)
{
printf("{1,7,11,13,17,19,23,29}");
return 0;
}
//Hardcoded for simplicity, also this primorial is ginarmous as it is.
int Primes[50] = {0};
int counter = 0;
//Find all primes less than N.
for (int a = 2; a <= N; a++)
{
if (IsPrime(a))
{
Primes[counter] = a;
printf("\n Prime: : %i \n", a);
counter++;
}
}
//Get the group size
unsigned long long MAXELEMENT = primorial(Primes, counter);
unsigned long long Gsize = EulerPhi(Primes, counter);
printf("\n GSize: %llu \n", Gsize);
printf("\n GSize: %llu \n", Gsize);
//Create the list to hold the values
unsigned long long *GROUP = (unsigned long long *) calloc(Gsize, sizeof(unsigned long long));
//Populate the list
gen( GROUP, MAXELEMENT, G3);
//Print values
printf("{");
for (unsigned long long k = 0; k < Gsize;k++)
{
printf("%llu,", GROUP[k]);
}
printf("}");
return 0;
}
If you are looking for a faster prime number check, here is one that is reasonably fast and eliminates all calls to computationally intensive functions (e.g. sqrt, etc..)
int isprime (int v)
{
int i;
if (v < 0) v = -v; /* insure v non-negative */
if (v < 2 || !((unsigned)v & 1)) /* 0, 1 + even > 2 are not prime */
return 0;
for (i = 2; i * i <= v; i++)
if (v % i == 0)
return 0;
return 1;
}
(note: You can adjust the type as required if you are looking for numbers above the standard int range.)
Give it a try and let me know how it compares to the once you are currently using.
#include <stdio.h>
#include <time.h>
#include <math.h>
#include <stdlib.h>
#define MAXNUM 2000000000
#define MINNUM 1990000001
#define MAXTRIES 10
unsigned long long b, e, m, result;
int modulo(b, e, m)
{
result = 1;
while(e > 0)
{
if(e % 2 == 1)
{
result = (result * b);
}
b = (b * b) % m;
e = e / 2;
}
return result % m;
}
int isPrime(n)
{
unsigned long long a;
int i;
for(i = 1; i <= 10; i++)
{
a = rand() % (n - 1) + 1;
if(modulo(a, n - 1, n) != 1)
{
return 0;
}
}
return 1;
}
int main()
{
unsigned int prime = 0;
unsigned int flag = 0;
unsigned int tries;
unsigned int start;
long curtime;
unsigned long long p;
curtime = time(NULL);
srand((unsigned int) curtime);
printf("Checking range [1990000001, 2000000000] for prime numbers.\n");
if(MINNUM % 2 == 0)
{
start = MINNUM + 1;
}
else
{
start = MINNUM;
}
printf("Trying Fermat test with seed %ld \n\n",curtime);
prime = 0;
for(tries = 1; tries <= MAXTRIES; tries++)
{
clock_t tic = clock();
for(p = start; p <= MAXNUM; p += 2)
{
if(isPrime(p))
prime++;
}
clock_t toc = clock();
printf("Probabilistic algorithm: Found %ld primes in %f seconds.(tries = %d)\n", prime, (double)(toc - tic) / CLOCKS_PER_SEC,tries);
prime = 0;
}
return 0;
}
So the problem is that the algorithm finds in every try 5000000 prime numbers when it should find around 466646 with some deviation. Which means that in every try it should find a number of primes close to the one mentioned above.
It looks like the main problem is caused by integer overflows in the modulo() function. Specifically, result=(result*b) is going to overflow quite regularly. You need to store these variables in 64-bit unsigned integers, and calculate the modulus of this result every time.
This will work (with a few minor corrections elsewhere):
#include <inttypes.h>
#define MAXNUM 2000000000
#define MINNUM 1990000001
#define MAXTRIES 10
uint64_t modulo(uint64_t b, uint64_t e, uint64_t m){
uint64_t result=1;
while(e>0){
if(e%2==1){
result=(result*b)%m;
}
b=(b*b)%m;
e=e/2;
}
return result%m;
}
Result:
Checking range [1990000001, 2000000000] for prime numbers.
Trying Fermat test with seed 1416322197
Probabilistic algorithm: Found 466646 primes in 5.157485 seconds.(tries=1)
how do i store a huge number in a variable (i) and wont need to change much of the program ?
Is there a available datatype to store factorial of 100 for example ?
#include<stdio.h>
#include<conio.h>
void main()
{
long long int i = 1;
long long int sum = 0;
long long int j = 0;
long long int digit = 0;
for(j = 500; j >= 1; j--)
{
i = i * j;
}
printf("%lld", i);
while(i > 0)
{
digit = i%10;
i = i/10;
sum = sum + digit;
}
printf("\n%lld", sum);
getch();
}
There is no built-in language support for such large numbers. You have two options:
if you can, use existing library, like GMP
implement you own solution
If you decide to take the second path, you might want to consider storing digits (not necesserily decimal) in an array, and perform arithmetic operations using well known school algorithms. Keep in mind it will be (probably considerably) less efficient than heavily optimized library code.
#Marcin Łoś is on the money, no C solution without using a library or rolling your own functions.
Follows is a fun, but not imaginative solution where the large number is stored as a array of char (in reverse order).
#include <stdio.h>
#include <string.h>
#include <math.h>
void Mult(char *BigNum, unsigned Factor) {
unsigned Accumulator = 0;
char Digit;
while ((Digit = *BigNum) != '\0') {
Accumulator += ((unsigned)(Digit - '0')) * Factor;
*BigNum++ = Accumulator%10 + '0';
Accumulator /= 10;
}
while (Accumulator > 0) {
*BigNum++ = Accumulator%10 + '0';
Accumulator /= 10;
}
*BigNum = '\0';
}
int main(){
unsigned N = 500;
unsigned Factor;
char BigNum[(size_t) (N*log(N) + 2)]; // Form answer, in reverse order, as a string
strcpy(BigNum, "1");
for (Factor = 1; Factor <= N; Factor++) {
Mult(BigNum, Factor);
}
printf("%u! Length:%zu Reverse:\"%s\"\n", Factor - 1, strlen(BigNum), BigNum);
unsigned long Sum = 0;
size_t i;
for (i=0; BigNum[i]; i++) {
Sum += BigNum[i] - '0';
}
printf("Sum of digits:%lu\n", Sum);
return 0;
}
500! Length:1135 Reverse:"000...221"
Sum of digits:4599