123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143 |
- #include <inttypes.h>
- #include <math.h>
- #include <stdio.h>
- /*
- * Function Prototypes
- */
- int isPrime(uint64_t);
- int isNumeric(char);
- int isFullLength(char[]);
- uint64_t arrToNum(char[], int);
- void modBuff(char*, int);
- /*
- * Main Method
- */
- int main(int argc, char **argv) {
- /* Open the site as a file for reading the source */
- FILE *fptr = popen("wget --quiet -O - http://www-history.mcs.st-andrews.ac.uk/HistTopics/e_10000.html", "r");
-
- /* Variables --------------------------------------------------------- */
- int ctr = 1, itr; /* Two counter variables for the for loop and count */
- char buf[10]; /* A character buffer to store the individual digits */
- char cptr; /* A character to hold the next item in the stream */
- uint64_t num; /* An unsigned 64-bit integer to hold the number */
- /* ------------------------------------------------------------------- */
-
- /* Move the pointer to the numbers past the decimal point */
- while ((cptr = fgetc(fptr)) != '.');
-
- /* Put the first 10-digit number in the buffer */
- for (itr = 0; itr < 10; itr++) {
- /* Grab the next character */
- cptr = fgetc(fptr);
-
- /* Check to see if the character is numeric */
- if (isNumeric(cptr)) {
- /* Store it in the buffer if it is */
- buf[itr] = cptr;
- } else {
- /* Peel off any non-numeric characters */
- while (!isNumeric(cptr)) cptr = fgetc(fptr);
-
- /* Assign the character to the buffer if it's numeric */
- if (isNumeric(cptr)) buf[itr] = cptr;
- }
- }
-
- /* Iterate across the data and test the numbers */
- do {
- /* Check that the 10-digit number doesn't actually start with a 0,
- * and skip this iteration if it does. */
- if (isFullLength(buf)) {
- /* Convert the buffer into an integer */
- num = arrToNum(buf, 10);
-
- /* Print the number and increment the counter */
- printf("%02d.) %" PRIu64 "", ctr++, num);
-
- /* Check for primality of the number to exit the loop */
- if (isPrime(num)) {
- printf (" (1st 10-digit prime)\n");
- break;
- }
-
- /* Separate the numbers */
- printf("\n");
- }
-
- /* Grab the next character */
- cptr = fgetc(fptr);
-
- /* Peel off any non-numeric characters due to pre-formatted text */
- while (!isNumeric(cptr) && cptr != '<') cptr = fgetc(fptr);
-
- /* Check to make sure we're not at the end of the list */
- if (cptr == '<') break;
-
- /* Slide the unused numbers in the buffer down one step */
- modBuff(buf, 10);
-
- /* Put the next character at the end of the buffer */
- buf[9] = cptr;
- } while (isNumeric(cptr));
-
- /* Close the website pointer */
- pclose(fptr);
-
- /* Exit */
- return 0;
- }
- /*
- * isPrime(uint64_t)
- * Checks for primality of a number
- */
- int isPrime(uint64_t num) {
- if (num < 2) return 0;
- if (num == 2 || num == 3) return 1;
- if (num % 2 == 0) return 0;
- uint64_t sr = ceil(pow(num, 0.5));
- uint64_t ctr;
- for (ctr = 3; ctr <= sr; ctr += 2) if (num % ctr == 0) return 0;
- return 1;
- }
- /*
- * isNumeric(char)
- * Checks to make sure the character passed is a number
- */
- int isNumeric(char num) {
- return (num - '0' >= 0 && num - '0' <= 9);
- }
- /*
- * isFullLength(char[])
- * Simply checks to see that an n-digit number is, in fact, n-digits long
- */
- int isFullLength(char arr[]) {
- return (arr[0] - '0');
- }
- /*
- * arrToNum(char[], int)
- * Converts a character array to an integer
- */
- uint64_t arrToNum(char arr[], int len) {
- uint64_t res = 0;
- int ctr;
- for (ctr = 0; ctr < len; ctr++) res = (res * 10) + (arr[ctr] - '0');
- return res;
- }
- /*
- * modBuff(*char, int)
- * Slides the elements in the buffer down one slot
- */
- void modBuff(char *arr, int len) {
- int ctr;
- for (ctr = 0; ctr < (len - 1); ctr++) arr[ctr] = arr[ctr + 1];
- return;
- }
|