/* Copyright (C) 2021 Gentoo-libre Install This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include "primes.h" #define DEFAULT_SIZE 40 //printf colour definitions #define KGREEN "\x1B[32m" #define KRESET "\x1B[0m" //powq(): power unsigned long long powq(int number, int power) { unsigned long long result = 1;//result int, 1 by default if (!power){return 1;}//if to the power of 0, return 1 while(power)//loop until all powers have been calculated { result *= number;//in the end result=number*number*number*etc until power is reached --power;//--power since a power has been calculated } return result; } void primeDec(char s[], int length) { if (s[0] == '\0'){printf("Error\n"); return;}//catch case of blank input if (s[0] == '0' && s[1] == '\0'){printf("Error\n"); return;}//catch case of 0 input if (s[0] == '1' && s[1] == '\0'){printf("We all know that 1 isn't a prime number\n"); return;}//catch case of 1 input int power = 0; //int to store the power. while(s[power] != '\0'){++power;}//increment power for however many non-null chars in the string. --power;//The correct power is actually one less than above returns int i = 0;//counter int long input = 0;//where the converted int is stored while (s[i] != '\0')//convert the string of decimal numbers into a long long int { if (s[i] >= '0' && s[i] <= '9'){input += ((s[i] - '0') * powq(10,power));}//integer = integer + ([char converted to number] * (10^[position of number in string])) ++i; --power;//Deincrement the power. E.g. ([charvalue]*(10^3))+([nextcharvalue]*(10^2)) etc } i=0; while(1) { if ((input % primes[i]) != 0) { printf("%ld / %d = %lf\n", input, primes[i], (double)input/primes[i]); if (i > 998){printf("Out of primes. Good job\n"); exit(1);} ++i;//move up to next prime } else { printf("%ld / %d = %ld round %s(works)%s\n", input, primes[i], input/primes[i], KGREEN, KRESET); input = input/primes[i];//input is now the new number //check if prime (linear search shouldn't take too long) int j = 0; for (; j < 998; ++j) { // if (primes[j] > input){printf("%s (works)%s", KGREEN, KRESET); break;} if (primes[j] > input){break;} else if (primes[j] == input) { printf("%sWe're done.%s Times those divisions (times by each divisor on the (works) lines, then the divisor on the last line, then the last prime).\n", KGREEN, KRESET); return;//the number was determined to be prime, so complete } } if (j > 998){printf("Out of primes. Good job\n"); exit(1);} } } } int main(int argc, char *argv[]) { char input[DEFAULT_SIZE];//input string is DEFAULT_SIZE in length if (!argv[1]){goto stdinMode;} if (argv[1]) { printf("Usage (stdin mode): %s\n", argv[0]); printf("Ctrl+D to exit\n"); printf("Shows working of prime decomposition, you gotta extract the answer yourself though.\n"); printf("License: GPLv3+\n"); return 0; } stdinMode: ; int i; nextnum: i=0; char *character = fgets(input, DEFAULT_SIZE, stdin); if (!character){exit(0);}//exit if EOF (fgets() returns -1 on EOF or error) character = strstr(input,"\n");//try to find the newline in the input so it can be overwritten if (!character){printf("Input too long\n"); while(getchar() != '\n'); goto nextnum;}//if more than 40 chars were read, input was too long character = '\0'; //overwrite newline with null char //strip out invalid chars from the input string int j;//another counter variable for (i=0; input[i] != '\0'; ++i) { if ((input[i] < '0')||(input[i] > '9'))//if input[i] is an invalid character { j=i; while(input[j] != '\0'){input[j++] = input[j+1];}//shift all characters above left, overwriting the character --i;//deincrement i, since the string was just shrunk by one and the one just above could indeed be a matching char } } primeDec(input, DEFAULT_SIZE-1); goto nextnum; return 0; }