Checking a variable meanwhile calling the functions needed - c

So im fairly new to programming and I ran into something which I cannot figure out.
I'll demonstrate my problem.
int main(void){
int number;
if(number == 1){
number1();
}else if(number == 2){
number2();
}else if(number == 3){
number3();
}else if(number == 4){
number4();
}else if(number == 5){
number5();
}else if(number == 6){
number6();
}else if(number == 7){
number7();
}else if(number == 8){
number8();
}else if(number == 9){
number9();
}else if(number == 0){
number0();
} else if (number >= 10 && <= 19){
number1();
number2(25);
}
}
void number1(int Q){
VGA_box(X + 5 + Q, 20, X+7 + Q, 60, white);
}
void number2(int Q){
VGA_box(X + Q, 20, X+ 20 + Q, 22, white);
VGA_box(X + 18 + Q, 22, X+ 20 + Q, 38, white);
VGA_box(X + Q, 38, X+ 20 + Q, 40, white);
VGA_box(X + Q, 40, X+ 2 + Q, 58, white);
VGA_box(X + Q, 58, X+ 20 + Q, 60, white);
}
Please ignore the functions VGA_box(), since this is just a function to write a line/box.
I'm making a little game and I would like to add a scoreboard, but here is my problem:
Since I'm drawing the numbers (so they look better IMO), I have to call functions, functions which represent a number. So if number = 1, function number1(); is called.
Is there an easy way to call the functions number2(), number5() and number9() if the number is 259? Or lets say; 632. The only possible way I can figure out is to use a lot of if-statements but that will take me a while to do.
Is it possible to use a for-loop which keeps track of what the number is and calls the functions which needed?
Thank you in advance.

You can use an array of pointers to function and a recursive function to reverse the value:
#include <stdio.h>
static void func0(void) { printf("0\n"); }
static void func1(void) { printf("1\n"); }
static void func2(void) { printf("2\n"); }
static void func3(void) { printf("3\n"); }
static void (*func[])(void) = {func0, func1, func2, func3};
static void exec(int value)
{
if (value) {
exec(value / 10);
func[value % 10]();
}
}
int main(void)
{
exec(123);
return 0;
}
Output:
1
2
3
As pointed out by #user3078414 in comments this fails when exec(012) is passed (the first 0 is not evaluated in the recursive function), in addition, 012 is interpreted as an octal (not as a decimal).
An alternative using strings:
#include <stdio.h>
static void func0(void) { printf("0\n"); }
static void func1(void) { printf("1\n"); }
static void func2(void) { printf("2\n"); }
static void func3(void) { printf("3\n"); }
static void (*func[])(void) = {func0, func1, func2, func3};
int main(void)
{
char *ptr = "012";
while (*ptr) {
func[*ptr - '0']();
ptr++;
}
return 0;
}

It seems like functions number1(), number2(), etc are quite similar. I'd be against creating different functions; I'd rather create one single function (let's say number()) which receives the whole number "632" from your example, and loops digit by digit.
Creating one single function is easier to handle by you. Just check that the resulting function is not too big, but it's quite likely that functions number1(), number2(), etc have a lot of code in common. If that's the case, reducing redundancy and repetition in code is highly recommended!
Let me know if I'm right with this.
Cheers!

Create function drawDigit(int digit) where digit is a single digit number between 0 and 9.
You can use function pointers to select which number function to call, but if that is too complex, you can use the if/else method for now.
Convert score to string:
int score = 259;
char digits[SIZE]; // Size must be large enough to hold all digits and nul character ('\0')
int numDigits = snprintf(digits, SIZE, "%d", score); // snprintf is from "stdio.h"
// digits contains now 4 character string "259" with nul character at the end
Loop over string to draw all digits:
for(int i = 0; i < numDigits; ++i) {
int digit = digits[i] - '0'; // Convert character digit to numeric digit
drawDigit(digit);
}
You probably need extra a parameter to drawDigit function to adjust the horizontal placement, but I'll leave that exercise to the reader.

Function pointers and switch/case are not the solution !
The problem is not if-statement or even the functions. Since your algorithms to draw scores are very different in each function then you can not stop using lots of conditions, so you have to some where call them by lots of if statements.
The solution is to find an uniform algorithm to draw scores on the screen for every number. For example write 10 functions to draw digits between [0..9], then use this functions to draw numbers with arbitrary length numbers.

You can use pointer to function, e.g:
#include <stdio.h>
typedef void (*typ_callback)(int);
static void number1(int Q);
static void number2(int Q);
typ_callback my_table[] = { NULL, number1, number2 };
int main(void)
{
size_t number;
printf("Entern the number of callback: ");
scanf("%zu", &number);
if (number <= (sizeof(my_table)/sizeof(my_table[0])))
{
if (my_table[number] != NULL)
{
my_table[number](number);
}
}
else
{
fprintf(stderr, "Wrong number\n");
}
return 0;
}
static void number1(int Q)
{
printf("You called %s function with passing value %d\n", __func__, Q);
}
static void number2(int Q)
{
printf("You called %s function with passing value %d\n", __func__, Q);
}

Related

what thing i should change from this code

I want to make a program to count the sum of digits in a string but only using stdio.h
but the program needs to count until its less than 10
so the example you input 56 it would be 5+6=11 then 1+1=2 and so on
here's my code. For now I'm just confused how to check if its whether more than 9 or not
#include<stdio.h>
int plus(int n);
int main(void)
{
int n, digit, test;
scanf("%d", &n);
test = plus(n);
while(test != 0)
{
if(test > 9)
plus(test);
else
break;
}
printf("%d", test);
}
int plus(int n)
{
int digit=0,test=0;
while(n != 0)
{
digit = n%10;
test = test + digit;
n = n/10;
}
return test;
}
You are not storing the value returned by plus function in the while body.
You can change the condition in while to check whether it is greater than 9 or not, and assign test as test = plus(test);
So, your while will look like this.
while(test > 9)
{
test=plus(test);
}
You need to recursively call the function plus() until the value returned by it becomes less than 10. Like shown below:
int main(void)
{
int n=56;
while(n> 10)
{
n = plus(n);
}
printf("%d", n);
}

Tic tac toe game in C stuck in a loop when finding a random number for the opponent

I started C and I am trying to write a tic tac toe with an opponent which searches a random number between 1 to 9 and then fill the slot with “O”. However, when the random number detects an occupied slot, it will continue to fill other empty slots without giving the player the turn. How do I resolve this?
I made two arrays, one for the game screen, one for the memory of the slots.
I’m sorry I couldn’t chuck out the code since I thought it’s all important and is there any better way to do this? Sorry for my writing style if it is a bit confusing, and I think there are unimportant variables.
Here is my code:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
char values[3][4] = { // screen board
{46, 46, 46,'\n'},
{46, 46, 46,'\n'},
{46, 46, 46,'\n'}
};
double memory[3][4] = { // memory board to put values
{0, 0, 0,'\n'},
{0, 0, 0,'\n'},
{0, 0, 0,'\n'}
};
int player(int i, char values[3][4]) {
int input;
printf("enter position: ");
scanf("%i", &input);
int x = (((input) / 3.3) - 3) * -1; // important math to convert to num
int y = (input + 2) % 3; // important math to convert to num
if (memory[x][y] == 0) {
values[x][y] = 'X';
memory[x][y] = 1;
printf("%s", values);
getchar();
return 0;
getchar();
} else {
printf("Wrong!, choose another line\n");
printf("%s", values);
getchar();
player(i, values);
}
}
int opponent(char values[3][4]) { //function opponent
int count = 0;
srand(time(NULL));
int random = (rand() % 9) + 1; // create random number
for (count = 0; count < 9; count++) {
int x = (((random) / 3.3) - 3) * -1;
int y = (random + 2) % 3;
if (memory[x][y] == 0) { // if memory is empty, do the following, loop stucks here
values[x][y] = 'O';
memory[x][y] = 2;
printf("Opponent Move\n");
printf("%s", values);
count++;
return 0;
} else { // if memory is not 0, do this. Error starts here
getchar();
printf("Move is %i", random);
opponent(values); // it calls itself to do a loop,
}
}
}
int main() {
int input;
int i = 2;;
for (i = 2; i < 9; i++) {
player(i, values); //Player goes first
getchar();
opponent(values);
}
}
Instead of having two independent values and memory, use an enum array to represent the game map.
enum Square { VACANT, X, O } squares[3][3], move = X;
It is initialised according to The initialization of static variables in C.
You probably need a function to decide if a player has won,
/* Checks if the player who's move it was won. */
static int is_win(void) {
return (squares[0][0]==move && squares[0][1]==move && squares[0][2]==move)||
(squares[1][0]==move && squares[1][1]==move && squares[1][2]==move)||
(squares[2][0]==move && squares[2][1]==move && squares[2][2]==move);
/* Etc. */
}
As well as a function for printing the board,
static const char letters[] = { '/', 'X', 'O' };
static void print_board(void) {
printf("%c %c %c\n%c %c %c\n%c %c %c\n",
letters[squares[0][0]], letters[squares[0][1]], letters[squares[0][2]],
letters[squares[1][0]], letters[squares[1][1]], letters[squares[1][2]],
letters[squares[2][0]], letters[squares[2][1]], letters[squares[2][2]]);
}
The code as you have it shadows the global state with parameters to the functions. This is very confusing. Think about whether you need the parameter to do the function's job. When one has complicated states that are defined in multiple files, it's probably best to have a agglomeration game object, but for simple games I think it's fine to have a global state.
Instead of playing until 7 moves, use a simple state machine to keep track of the game state. One can typedef the functions (How do function pointers in C work?) player and opponent and put them in a static array to simplify greatly the game loop. Consider,
/* Move returns whether we should continue. */
typedef int (*Move)(void);
/* Implements Move. */
static int player(void) {
printf("player:\n");
/* FIXME: player move. */
return is_win() ? 0 : (move = O, 1);
}
/* Implements Move. */
static int opponent(void) {
printf("opp:\n");
/* FIXME: Chose randomly from all of it's allowed moves? */
return is_win() ? 0 : (move = X, 1);
}
static const Move states[] = { 0, &player, &opponent };
Then your main is just,
int main(void) {
while(states[move]()) print_board();
printf("%c wins.\n", letters[move]);
return 0;
}
Edit: Definitely have a state where it's a tie, perhaps when there are no moves left.

My binary is outputting in reverse order

I'm writing a program that takes a users input of characters, singles each character, converts each to binary, and also counts the amount of '1's in each binary. So far, I have a working code. However, the output of each binary is in reverse order. Like this:
The character A = 10000010 1's = 2
When what I want/need is:
The character A = 01000001 1's = 2
I am required to use the amount of functions I already have and have been told that fixing this will be as simple as doing recursion on my binaryPrinter function. I'm confused about where I would do that within my function and what arguments I would send through. Any help would be fantastic, thanks.
p.s. I'm required to use recursion in the binaryPrinter function to loop the program which apparently is going to solve my backwards binary problems if I place it in the right part of the binaryPrinter function.
#include <stdio.h>
#include <stdlib.h>
void binaryPrinter(int digitsLeft, int value, int * numberOfOnes);
void print(char c);
int charToInt(char C)
{
int c;
c=C;
return (int) c;
}
int main ()
{
char value;
int result = 1;
while (result != EOF)
{
result = scanf("%c", &value);
if (result != EOF)
{
print(value);
}
}
}
void print(char c)
{
int digits=8, value=c;
int ones=0;
printf("The character %c = ", c);
binaryPrinter(digits, value, &ones );
printf(" 1's = %d\n", ones);
}
void binaryPrinter(int digitsLeft, int value, int * numberOfOnes)
{
for (digitsLeft=8; digitsLeft>0; digitsLeft--)
{
if( value & 1 )
{
printf("1");
*numberOfOnes=*numberOfOnes+1;
}
else
{
printf("0");
}
value = value >> 1;
}
}
Here's the recursive version. Notice that it recurses before printing anything, so it prints as it's returning from processing each digit, which prints them in the proper order.
void binaryPrinter(int digitsLeft, int value, int * numberOfOnes)
{
if (digitsLeft > 1) {
binaryPrinter(digitsLeft - 1, value >> 1, numberOfOnes);
}
if (value & 1) {
printf("1");
(*numberOfOnes)++;
} else {
printf("0");
}
}
Change the loop to
for (digitsLeft=1; digitsLeft<=8; digitsLeft++)
Well, you are looking at the digits in reverse order:
if (value & 1) --> take the right-most digit
value = value >> 1; --> shift to the right
so if you have
12345678
(yes, that's not bits, this is just to illustrate the positioning) for inputs, you're doing:
8,7,6,5,4,3,2,1
for output. You need to reverse the logic by working from the left (highest) bits in your original string and work yourway down to the least significant bits.

Star printing in C the hard way

I've started exercising some C and found this nice exercise where I have to print a triangle via input.
for the input 6 it will print
*
**
***
****
*****
******
*****
****
***
**
*
Now, looking at it I thought, well, that's not such a hard task. So I decided to try and write it using recursion, no loops and only 2 variables.
the function should looks like this:
void PrintTriangle(int iMainNumber, int iCurrNumber)
{
//Logic goes here
}
A few hours later I realized this is a lot harder than I thought, since I need to pass enough information for the function to be able to "remember" how much triangles it should print.
So now I decided to ask you if that is even possible.
(remember, no loops, no other functions, only recursion).
EDIT:
This isn't homework, this is out of sheer curiosity. However I probably can't validate for you.
I've managed to get halfway through with this
void PrintTriangle(int iMainNumber, int iCurrNumber)
{
if (iMainNumber == 0)
{
printf("\r\n");
}
else if (iMainNumber == iCurrNumber)
{
printf("\r\n");
PrintTriangle(iMainNumber - 1, 0);
}
else
{
printf("%s", MYCHAR);
PrintTriangle(iMainNumber, iCurrNumber + 1);
}
}
I got stuck trying to create the opposite function, I believe that if I could do it, I would be able to use the fact that iMainNumber and iCurrNumber are positive or negative to navigate through the functions flow.
In other words, when the parameters are negative I would print a descending star in the length of the input minus one, and when the parameters are positive I would print the ascending star in the length of the input.
I've thought about Using a flag, but not instead of 2 integers.
Maybe if I'd add another flag and have 2 integers and a flag then I could solve it, but as I said, I tried to limit myself to 2 integers.
What I'm starting to think is that there is no way to pass the information required to print an ascending star in this method without using more than 2 integers and recursion.
But I'm still not so sure about that, hence the question.
I came up with:
void PrintTriangle(int size, int indent)
{
switch(size) {
case 0:
if (indent > 1) PrintTriangle(size, indent-1);
putchar('*');
break;
case 1:
PrintTriangle(size-1, indent+1);
putchar('\n');
break;
default:
PrintTriangle(1, indent);
PrintTriangle(size-1, indent+1);
PrintTriangle(1, indent);
break; }
}
int main()
{
PrintTriangle(6, 0);
return 0;
}
as a quick first attempt. Seems to do the job.
size is the size of the triangle to print, and indent is the number of extra stars to print before each row of the triangle. size==0 means just print indent stars and no newline (used to print the indent before the triangle)
If you want something a bit more compact, you could rewrite this as:
void PrintTriangle(int size, int indent)
{
if (size <= 0) {
if (indent > 1) PrintTriangle(size, indent-1);
putchar('*');
} else {
if (size > 1) PrintTriangle(1, indent);
PrintTriangle(size-1, indent+1);
if (size > 1) PrintTriangle(1, indent);
else putchar('\n'); }
}
Anything done with loops can be done with recursion with the same number of variables. You just have to tease out what is the state, and pass that updated state in a recursive call, instead of looping.
So let's do it iterativey, first. The input is size, the size of the triangle. Let's have two state variables, lineNumber from 1 to size*2-1 and columnNumber from 1 to size. Note that:
columnsForLine = lineNumber <= size ? lineNumber : size*2 - lineNumber
The iterative version would be like this:
int lineNumber = 1;
int columnNumber = 1;
int size = 6;
while (lineNumber <= size*2-1) {
printf("*");
int columnsForLine = lineNumber <= size ? lineNumber : size*2 - lineNumber;
if (columnNumber == columnsForLine) {
printf("\n");
columnNumber = 1;
lineNumber += 1;
}
else {
columnNumber += 1;
}
}
That does indeed work. Now how to do it recursively? Just tease out where state is being updated and do that as a recursive call:
void recstars(int size, int lineNumber, int columnNumber) {
if (!(lineNumber <= size*2 - 1)) {
return;
}
printf("*");
int columnsForLine = lineNumber <= size ? lineNumber : size*2 - lineNumber;
if (columnNumber == columnsForLine) {
printf("\n");
recstars(size, lineNumber + 1, 1);
}
else {
recstars(size, lineNumber, columnNumber + 1);
}
}
recstars(6, 1, 1);
And voila. Works for any size, e.g. 13.
Note that the code is basically the same, it's just a matter of doing the control flow differently. Also note that this is tail-recursive, meaning a smart compiler would be able to execute the recursive calls without growing the stack for each call.
Hmm if you only want to use 2 variables though, including the input, will be a bit trickier... you can always cheat and stuff all 3 integers into one integer, then unpack it & re-pack it each time. e.g.
void recstars(int state) {
int size = state / 10000;
int lineNumber = (state - size*10000) / 100;
int columnNumber = state - size*10000 - lineNumber*100;
if (!(lineNumber <= size*2 - 1)) {
return;
}
printf("*");
int columnsForLine = lineNumber <= size ? lineNumber : size*2 - lineNumber;
if (columnNumber == columnsForLine) {
printf("\n");
recstars(size*10000 + (lineNumber+1)*100 + 1);
}
else {
recstars(size*10000 + lineNumber*100 + (columnNumber+1));
}
}
recstars(6*10000 + 1*100 + 1);
Seems to work. Is that legit, you think?
Otherwise, the tricky part isn't the recursion, it's just getting the job done with only 2 ints for state. Can you do it iteratively with only 2 integers?
Using 2 parameters as OP suggested
void PrintTriangle(int iMainNumber, int iCurrNumber) {
if (iMainNumber < 0) { // Row (use negative iMainNumber)
printf("%c", '*');
PrintTriangle(iMainNumber + 1, 0);
if (iMainNumber == -1)
printf("\n");
} else if (iMainNumber > 0) {
if (iCurrNumber < iMainNumber) { // Preceding short lines
if (iCurrNumber > 1)
PrintTriangle(iMainNumber, iCurrNumber - 1);
PrintTriangle(-iCurrNumber, 0);
} else if (iCurrNumber == iMainNumber) {
PrintTriangle(iMainNumber, iCurrNumber - 1); // left
PrintTriangle(iMainNumber, iCurrNumber + 1); // Right
} else { // Subsequent short lines
if ((iCurrNumber - iMainNumber) < iMainNumber)
PrintTriangle(iMainNumber, iCurrNumber + 1);
PrintTriangle(-(iCurrNumber - iMainNumber), 0);
}
}
}
int main() {
PrintTriangle(3,3);
PrintTriangle(6,6);
return 0;
}
From what I have read, most suggestions have already pointed out to pass in any state you need.
However, you really don't need that many branching statements. Most of what you need, you can derive arithmetically. You can calculate the total number of recursions and derive the number of stars from the current recursion count. Also, by separating the portion of the initial invocation from the recursion, you can make usage much simpler.
Just saw that you do not want more than two integers. Consider the below and see if you really want to maintain that preference. If so, you can put the calculation of the total in the recursive portion. I think it would be less readable.
void _print_stars(int height, int total, int current)
{
int stars = current <= height ? current : 2 * height - current;
for (int i = 0; i < stars; i++) { printf("*"); }
printf("\n");
if (current != total)
{
_print_stars(height, total, current + 1);
}
}
void print_stars(int height)
{
int total_recursions = 2 * height - 1;
_print_stars(height, total_recursions, 1);
}
Pure recursion, no loops, calling program 'main()' passes only one parameter:
void PrintTheClms(int width, int stars) {
printf("*");
if stars < width then {
PrintTheClms(width, stars+1);
}
}
void PrintStars(int width) {
PrintTheClms(width, 1);
printf("\n");
}
void PrintTheRows(int size, int indent) {
PrintStars(indent);
if indent < size then {
PrintTheRows(size, indent+1);
PrintStars(indent);
}
}
void PrintTriangle(int size) {
if size > 0 then {
PrintTheRows(size, 1);
}
}
int main() {
PrintTriangle(6);
PrintTriangle(11);
// etc.
return 0;
}
Very simple -- no else clauses, no case constructs, no direction flag. Lots of procs and lots of calls, though.

Optimizing I/O(Output) in C code + a loop

I have a code which reads around (10^5) int(s) from stdin and then after performing ## i output them on stdout. I have taken care of the INPUT part by using "setvbuf" & reading lines using "fgets_unlocked()" and then parsing them to get the required int(s).
I have 2 issues which i am not able to come over with:
1.) As i am printing int(s) 5 million on stdout its taking lot of time : IS THERE ANY WAY TO REDUCE THIS( i tried using fwrite() but the o/p prints unprintable characters due to the reason using fread to read into int buffer)
2.) After parsing the input for the int(s) say 'x' i actually find the no of divisors by doing %(mod) for the no in a loop.(See in the code below): Maybe this is also a reason for my code being times out:
Any suggestions on this to improved.
Many thanks
This is actually a problem from http://www.codechef.com/problems/PD13
# include <stdio.h>
# define SIZE 32*1024
char buf[SIZE];
main(void)
{
int i=0,chk =0;
unsigned int j =0 ,div =0;
int a =0,num =0;
char ch;
setvbuf(stdin,(char*)NULL,_IOFBF,0);
scanf("%d",&chk);
while(getchar_unlocked() != '\n');
while((a = fread_unlocked(buf,1,SIZE,stdin)) >0)
{
for(i=0;i<a;i++)
{
if(buf[i] != '\n')
{
num = (buf[i] - '0')+(10*num);
}
else
if(buf[i] == '\n')
{
div = 1;
for(j=2;j<=(num/2);j++)
{
if((num%j) == 0) // Prob 2
{
div +=j;
}
}
num = 0;
printf("%d\n",div); // problem 1
}
}
}
return 0;
}
You can print far faster than printf.
Look into itoa(), or write your own simple function that converts integers to ascii very quickly.
Here's a quick-n-dirty version of itoa that should work fast for your purposes:
char* custom_itoa(int i)
{
static char output[24]; // 64-bit MAX_INT is 20 digits
char* p = &output[23];
for(*p--=0;i/=10;*p--=i%10+0x30);
return ++p;
}
note that this function has some serious built in limits, including:
it doesn't handle negative numbers
it doesn't currently handle numbers greater than 23-characters in decimal form.
it is inherently thread-dangerous. Do not attempt in a multi-threaded environment.
the return value will be corrupted as soon as the function is called again.
I wrote this purely for speed, not for safety or convenience.
Version 2 based on suggestion by #UmNyobe and #wildplasser(see above comments)
The code execution took 0.12 seconds and 3.2 MB of memory on the online judge.
I myself checked with 2*10^5 int(input) in the range from 1 to 5*10^5 and the execution took:
real 0m0.443s
user 0m0.408s
sys 0m0.024s
**Please see if some more optimization can be done.
enter code here
/** Solution for the sum of the proper divisor problem from codechef **/
/** # author dZONE **/
# include <stdio.h>
# include <math.h>
# include <stdlib.h>
# include <error.h>
# define SIZE 200000
inline int readnum(void);
void count(int num);
int pft[]={2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97,101,103,107,109,113,127,131,137,139,149,151,157,163,167,173,179,181,191,193,197,199,211,223,227,229,233,239,241,251,257,263,269,271,277,281,283,293,307,311,313,317,331,337,347,349,353,359,367,373,379,383,389,397,401,409,419,421,431,433,439,443,449,457,461,463,467,479,487,491,499,503,509,521,523,541,547,557,563,569,571,577,587,593,599,601,607,613,617,619,631,641,643,647,653,659,661,673,677,683,691,701,709};
unsigned long long int sum[SIZE];
int k = 0;
inline int readnum(void)
{
int num = 0;
char ch;
while((ch = getchar_unlocked()) != '\n')
{
if(ch >=48 && ch <=57)
{
num = ch -'0' + 10*num;
}
}
if(num ==0)
{
return -1;
}
return num;
}
void count(int num)
{
unsigned int i = 0;
unsigned long long tmp =0,pfac =1;
int flag = 0;
tmp = num;
sum[k] = 1;
for(i=0;i<127;i++)
{
if((tmp % pft[i]) == 0)
{
flag =1; // For Prime numbers not in pft table
pfac =1;
while(tmp % pft[i] == 0)
{
tmp =tmp /pft[i];
pfac *= pft[i];
}
pfac *= pft[i];
sum[k] *= (pfac-1)/(pft[i]-1);
}
}
if(flag ==0)
{
sum[k] = 1;
++k;
return;
}
if(tmp != 1) // For numbers with some prime factors in the pft table+some prime > 705
{
sum[k] *=((tmp*tmp) -1)/(tmp -1);
}
sum[k] -=num;
++k;
return;
}
int main(void)
{
int i=0,terms =0,num = 0;
setvbuf(stdin,(char*)NULL,_IOFBF,0);
scanf("%d",&terms);
while(getchar_unlocked() != '\n');
while(terms--)
{
num = readnum();
if(num ==1)
{
continue;
}
if(num == -1)
{
perror("\n ERROR\n");
return 0;
}
count(num);
}
i =0;
while(i<k)
{
printf("%lld\n",sum[i]);
++i;
}
return 0;
}
//Prob 2 Is your biggesr issue right now.... You just want to find the number of divisors?
My first suggestion will be to cache your result to some degree... but this requires potentially twice the amount of storage you have at the beginning :/.
What you can do is generate a list of prime numbers before hand (using the sieve algorithm). It will be ideal to know the biggest number N in your list and generate all primes till his square root. Now for each number in your list, you want to find his representation as product of factors, ie
n = a1^p1 * a1^p2 *... *an^pn
Then the sum of divisors will be.
((a1^(p1+1) - 1)/(a1 - 1))*((a2^(p2+1) - 1)/(a2-1))*...*((an^(pn+1) - 1)/(an-1))
To understand you have (for n = 8) 1+ 2 + 4 + 8 = 15 = (16 - 1)/(2 - 1)
It will drastically improve the speed but integer factorization (what you are really doing) is really costly...
Edit:
In your link the maximum is 5000000 so you have at most 700 primes
Simple decomposition algorithm
void primedecomp(int number, const int* primetable, int* primecount,
int pos,int tablelen){
while(pos < tablelen && number % primetable[pos] !=0 )
pos++;
if(pos == tablelen)
return
while(number % primetable[pos] ==0 ){
number = number / primetable[pos];
primecount[pos]++;
}
//number has been modified
//too lazy to write a loop, so recursive call
primedecomp(number,primetable,primecount, pos+1,tablelen);
}
EDIT : rather than counting, compute a^(n+1) using primepow = a; primepow = a*primepow;
It will be much cleaner in C++ or java where you have hashmap. At the end
primecount contains the pi values I was talking about above.
Even if it looks scary, you will create the primetable only once. Now this algorithm
run in worst case in O(tablelen) which is O(square root(Nmax)). your initial
loop ran in O(Nmax).

Resources