Last active
August 2, 2022 09:49
-
-
Save webprogramozo/13b53f04b47ebdcba3a62883202f4630 to your computer and use it in GitHub Desktop.
IntegraThor - command line definite integral calculator (oldie school project from 2014)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <stdlib.h> | |
#include <string.h> | |
#include <math.h> | |
int getline(char *s, int n){ | |
int c; | |
char *t=s; | |
while(n-- > 0 && (c=getchar())!=EOF && c!='\n') *t++ = c; | |
*t='\0'; | |
while(c!=EOF&&c!='\n') | |
c=getchar(); | |
return(t-s); | |
} | |
typedef struct item{ | |
struct item *next_item; | |
struct item *sub_items; | |
int tipus; | |
double doublevalue; | |
} item; | |
int calculate(item *start, double x, double *eredmeny); | |
item* create_item(int tipus, double doublevalue){ | |
item* temp = malloc(sizeof(item)); | |
temp->next_item = NULL; | |
temp->sub_items = NULL; | |
temp->tipus = tipus; | |
temp->doublevalue = doublevalue; | |
return temp; | |
} | |
int PARSERS_zarojel(char *szoveg, int *hozza, int *ugras, double *doublevalue, int *melysegvaltozas, int *isoperator){ | |
if(strchr(szoveg, '(') == szoveg){ | |
*hozza = 1; | |
*ugras = 1; | |
*doublevalue = 0.0; | |
*melysegvaltozas = 1; | |
*isoperator = 0; | |
return 1; | |
}else return 0; | |
} | |
int CALCULATORS_zarojel(double prev_value, item *thisitem, double next_value, double x, double *doublevalue){ | |
int rv = calculate(thisitem, x, doublevalue); | |
return rv; | |
} | |
int PARSERS_zarojelbezar(char *szoveg, int *hozza, int *ugras, double *doublevalue, int *melysegvaltozas, int *isoperator){ | |
if(strchr(szoveg, ')') == szoveg){ | |
*hozza = 0; | |
*ugras = 1; | |
*doublevalue = 0.0; | |
*melysegvaltozas = -1; | |
*isoperator = 0; | |
return 1; | |
}else return 0; | |
} | |
int CALCULATORS_zarojelbezar(double prev_value, item *thisitem, double next_value, double x, double *doublevalue){ | |
return 0; | |
} | |
int PARSERS_sinusfuggveny(char *szoveg, int *hozza, int *ugras, double *doublevalue, int *melysegvaltozas, int *isoperator){ | |
char* s = {"sin("}; | |
if(strstr(szoveg, s) == szoveg){ | |
*hozza = 1; | |
*ugras = 4; | |
*doublevalue = 0.0; | |
*melysegvaltozas = 1; | |
*isoperator = 0; | |
return 1; | |
}else return 0; | |
} | |
int CALCULATORS_sinusfuggveny(double prev_value, item *thisitem, double next_value, double x, double *doublevalue){ | |
int ret = calculate(thisitem, x, doublevalue); | |
*doublevalue = sin(*doublevalue); | |
return ret; | |
} | |
int PARSERS_cosinusfuggveny(char *szoveg, int *hozza, int *ugras, double *doublevalue, int *melysegvaltozas, int *isoperator){ | |
char* s = {"cos("}; | |
if(strstr(szoveg, s) == szoveg){ | |
*hozza = 1; | |
*ugras = 4; | |
*doublevalue = 0.0; | |
*melysegvaltozas = 1; | |
*isoperator = 0; | |
return 1; | |
}else return 0; | |
} | |
int CALCULATORS_cosinusfuggveny(double prev_value, item *thisitem, double next_value, double x, double *doublevalue){ | |
int ret = calculate(thisitem, x, doublevalue); | |
*doublevalue = sin(*doublevalue); | |
return ret; | |
} | |
int PARSERS_tangensfuggveny(char *szoveg, int *hozza, int *ugras, double *doublevalue, int *melysegvaltozas, int *isoperator){ | |
char* s = {"tan("}; | |
if(strstr(szoveg, s) == szoveg){ | |
*hozza = 1; | |
*ugras = 4; | |
*doublevalue = 0.0; | |
*melysegvaltozas = 1; | |
*isoperator = 0; | |
return 1; | |
}else return 0; | |
} | |
int CALCULATORS_tangensfuggveny(double prev_value, item *thisitem, double next_value, double x, double *doublevalue){ | |
int ret = calculate(thisitem, x, doublevalue); | |
*doublevalue = sin(*doublevalue); | |
return ret; | |
} | |
int PARSERS_x(char *szoveg, int *hozza, int *ugras, double *doublevalue, int *melysegvaltozas, int *isoperator){ | |
if(strchr(szoveg, 'x') == szoveg){ | |
*hozza = 1; | |
*ugras = 1; | |
*doublevalue = 0.0; | |
*melysegvaltozas = 0; | |
*isoperator = 0; | |
return 1; | |
}else return 0; | |
} | |
int CALCULATORS_x(double prev_value, item *thisitem, double next_value, double x, double *doublevalue){ | |
*doublevalue = x; | |
return 1; | |
} | |
int PARSERS_szam(char *szoveg, int *hozza, int *ugras, double *doublevalue, int *melysegvaltozas, int *isoperator){ | |
int pont = 0,indent = 0; | |
double eredmeny = 0; | |
*ugras = 0; | |
while(!pont && *szoveg != '\0' && ( (*szoveg - '0')>=0 && (*szoveg - '0')<10 || *szoveg == '.')){ | |
(*ugras)++; | |
if(*szoveg == '.'){ | |
pont = 1; | |
}else{ | |
eredmeny *= 10; | |
eredmeny += *szoveg - '0'; | |
} | |
szoveg++; | |
} | |
if(0 == (*ugras))return 0; | |
while(*szoveg != '\0' && (*szoveg - '0')>=0 && (*szoveg - '0')<10){ | |
(*ugras)++; | |
eredmeny *= 10; | |
eredmeny += *szoveg - '0'; | |
indent++; | |
szoveg++; | |
} | |
*doublevalue = eredmeny / pow(10, indent); | |
*melysegvaltozas = 0; | |
*isoperator = 0; | |
*hozza = 1; | |
return 1; | |
} | |
int CALCULATORS_szam(double prev_value, item *thisitem, double next_value, double x, double *doublevalue){ | |
*doublevalue = thisitem->doublevalue; | |
return 1; | |
} | |
int PARSERS_pi(char *szoveg, int *hozza, int *ugras, double *doublevalue, int *melysegvaltozas, int *isoperator){ | |
if(strstr(szoveg, "pi") == szoveg){ | |
*hozza = 1; | |
*ugras = 2; | |
*doublevalue = M_PI; | |
*melysegvaltozas = 0; | |
*isoperator = 0; | |
return 1; | |
}else return 0; | |
} | |
int CALCULATORS_pi(double prev_value, item *thisitem, double next_value, double x, double *doublevalue){ | |
*doublevalue = M_PI; | |
return 1; | |
} | |
int PARSERS_osszeadas(char *szoveg, int *hozza, int *ugras, double *doublevalue, int *melysegvaltozas, int *isoperator){ | |
if(strchr(szoveg, '+') == szoveg){ | |
*hozza = 1; | |
*ugras = 1; | |
*doublevalue = 0; | |
*melysegvaltozas = 0; | |
*isoperator = 1; | |
return 1; | |
}else return 0; | |
} | |
int CALCULATORS_osszeadas(double prev_value, item *thisitem, double next_value, double x, double *doublevalue){ | |
*doublevalue = prev_value + next_value; | |
return 1; | |
} | |
int PARSERS_kivonas(char *szoveg, int *hozza, int *ugras, double *doublevalue, int *melysegvaltozas, int *isoperator){ | |
if(strchr(szoveg, '-') == szoveg){ | |
*hozza = 1; | |
*ugras = 1; | |
*doublevalue = 0; | |
*melysegvaltozas = 0; | |
*isoperator = 1; | |
return 1; | |
}else return 0; | |
} | |
int CALCULATORS_kivonas(double prev_value, item *thisitem, double next_value, double x, double *doublevalue){ | |
*doublevalue = prev_value - next_value; | |
return 1; | |
} | |
int PARSERS_szorzas(char *szoveg, int *hozza, int *ugras, double *doublevalue, int *melysegvaltozas, int *isoperator){ | |
if(strchr(szoveg, '*') == szoveg){ | |
*hozza = 1; | |
*ugras = 1; | |
*doublevalue = 0; | |
*melysegvaltozas = 0; | |
*isoperator = 1; | |
return 1; | |
}else return 0; | |
} | |
int CALCULATORS_szorzas(double prev_value, item *thisitem, double next_value, double x, double *doublevalue){ | |
*doublevalue = prev_value * next_value; | |
return 1; | |
} | |
int PARSERS_osztas(char *szoveg, int *hozza, int *ugras, double *doublevalue, int *melysegvaltozas, int *isoperator){ | |
if(strchr(szoveg, '/') == szoveg){ | |
*hozza = 1; | |
*ugras = 1; | |
*doublevalue = 0; | |
*melysegvaltozas = 0; | |
*isoperator = 1; | |
return 1; | |
}else return 0; | |
} | |
int CALCULATORS_osztas(double prev_value, item *thisitem, double next_value, double x, double *doublevalue){ | |
if(next_value == 0){ | |
return 0; | |
} | |
*doublevalue = prev_value / next_value; | |
return 1; | |
} | |
int PARSERS_hatvanyozas(char *szoveg, int *hozza, int *ugras, double *doublevalue, int *melysegvaltozas, int *isoperator){ | |
if(strchr(szoveg, '^') == szoveg){ | |
*hozza = 1; | |
*ugras = 1; | |
*doublevalue = 0; | |
*melysegvaltozas = 0; | |
*isoperator = 1; | |
return 1; | |
}else return 0; | |
} | |
int CALCULATORS_hatvanyozas(double prev_value, item *thisitem, double next_value, double x, double *doublevalue){ | |
*doublevalue = pow(prev_value,next_value); | |
return 1; | |
} | |
item* add_next_item(item *target, item *toinsert){ | |
return target->next_item = toinsert; | |
} | |
void zarojelez(item *ennek_a_nextjet){ | |
item *eztathelyez = ennek_a_nextjet->next_item; | |
add_next_item(ennek_a_nextjet, create_item(0, 0)); | |
ennek_a_nextjet->next_item->sub_items = create_item(0, 0); | |
ennek_a_nextjet->next_item->sub_items->next_item = eztathelyez; | |
ennek_a_nextjet->next_item->next_item = eztathelyez->next_item->next_item->next_item; | |
eztathelyez->next_item->next_item = NULL; | |
} | |
char* parseExpression(char *keplet, item *hova){ | |
//valid? => szöveg, hozzáadjuk-e, karakterekben mért ugrás, modifier, doublevalue | |
int (*parsers[])(char *, int *, int*, double*, int*, int*) = { | |
PARSERS_zarojel, | |
PARSERS_zarojelbezar, | |
PARSERS_sinusfuggveny, | |
PARSERS_cosinusfuggveny, | |
PARSERS_tangensfuggveny, | |
PARSERS_x, | |
PARSERS_szam, // #6 | |
PARSERS_osszeadas, // #7 | |
PARSERS_kivonas, | |
PARSERS_szorzas, //#9 | |
PARSERS_osztas, | |
PARSERS_hatvanyozas, | |
PARSERS_pi | |
}; | |
int arraylenght = sizeof(parsers)/sizeof(parsers[0]); | |
int hozza, ugras, melysegvaltozas, x, isoperator, lastisoperator = 1; | |
int failed = 0; | |
double doublevalue; | |
item* current = hova->sub_items = create_item(0, 0); | |
while(!failed && *keplet != '\0'){ | |
x = 0;failed = 1; | |
//printf("\nUJZAROJEL: a szoveg itt tart: '%c'\n", *keplet); | |
while(x<arraylenght && failed){ | |
failed = 1 - parsers[x](keplet, &hozza, &ugras, &doublevalue, &melysegvaltozas, &isoperator); | |
//printf("keplet: %d, failed: %d\n", keplet, failed); | |
if(!failed){ | |
//printf("keplet ugratasa (%d) %d -> ", ugras, keplet); | |
keplet += ugras; | |
//printf("%d\n", keplet); | |
if(hozza){ | |
if(!isoperator && !lastisoperator){ | |
//printf("+1 szorzas %d %d %d\n", isoperator, lastisoperator, x); | |
current = add_next_item(current, create_item(9, 0)); | |
//ha ket erteket kepviselo reszlet van egymas utan, akkor kozejuk megy egy szorzasjel, pl 2x = 2*x | |
} | |
current = add_next_item(current, create_item(x, doublevalue)); | |
if(melysegvaltozas == 1){ | |
keplet = parseExpression(keplet, current); | |
} | |
} | |
if(melysegvaltozas == -1){ | |
failed = 1; | |
x = arraylenght; | |
} | |
} | |
x++; | |
} | |
lastisoperator = isoperator; | |
} | |
//printf("ZAROJEL VEGE!\n\n"); | |
current = hova->sub_items; | |
while(current->next_item!=NULL && current->next_item->next_item!=NULL && current->next_item->next_item->next_item!=NULL){ | |
if(current->next_item->next_item->tipus == 11){ | |
zarojelez(current); | |
} | |
current = current->next_item->next_item; | |
} | |
current = hova->sub_items; | |
while(current->next_item!=NULL && current->next_item->next_item!=NULL && current->next_item->next_item->next_item!=NULL){ | |
if(current->next_item->next_item->tipus == 10 ||current->next_item->next_item->tipus == 9){ | |
zarojelez(current); | |
} | |
current = current->next_item->next_item; | |
} | |
return keplet; | |
} | |
item* debug_write_item(item *that, int indent){ | |
while(indent-- > 0)printf(" "); | |
printf("", item->tipus); | |
} | |
void debug_write(item *root, int indent){ | |
} | |
int calculate(item *start, double x, double *eredmeny){ | |
//int CALCULATORS_hatvanyozas(double prev_value, item *thisitem, double next_value, double x, double *doublevalue){ | |
int (*calculators[])(double, item *, double, double, double*) = { | |
CALCULATORS_zarojel, | |
CALCULATORS_zarojelbezar, | |
CALCULATORS_sinusfuggveny, | |
CALCULATORS_cosinusfuggveny, | |
CALCULATORS_tangensfuggveny, | |
CALCULATORS_x, | |
CALCULATORS_szam, // #6 | |
CALCULATORS_osszeadas, // #7 | |
CALCULATORS_kivonas, | |
CALCULATORS_szorzas, //#9 | |
CALCULATORS_osztas, | |
CALCULATORS_hatvanyozas, | |
CALCULATORS_pi | |
}; | |
item *current = start->sub_items; | |
if(current->next_item == NULL)return 0; | |
current = current->next_item; | |
double ered,temp; | |
if(!calculators[current->tipus](0, current, 0, x, &ered)){ // indito baloldali ertek beallitasa | |
return 0; | |
} | |
while(current->next_item != NULL && current->next_item->next_item != NULL){ | |
if(!calculators[current->next_item->next_item->tipus](0, current->next_item->next_item, 0, x, &temp)){ //jobboldal kiszamolasa | |
return 0; | |
} | |
if(!calculators[current->next_item->tipus](ered, current->next_item, temp, x, &ered)){ //jobboldal kiszamolasa | |
return 0; | |
} | |
current = current->next_item->next_item; | |
} | |
if(current->next_item != NULL)return 0; // a vegere ketto elem maradt, egy szam es egy operator, es az operatoroknak ketto ertekre van szukseguk | |
//printf("partial: %f\n", ered); | |
*eredmeny = ered; | |
return 1; | |
} | |
void kiir(item *mit, int indent){ | |
int oi; | |
while(mit->next_item != NULL){ | |
oi = indent; | |
mit = mit->next_item; | |
while(oi--)printf(" "); | |
printf("tipus: %d ertek: %f\n", mit->tipus, mit->doublevalue); | |
if(mit->sub_items != NULL)kiir(mit->sub_items, indent+1); | |
} | |
} | |
int main(int argc, char **argv) | |
{ | |
item* root = create_item(0, 0); | |
char* keplet = malloc(sizeof(char)*1025); | |
char* iksz = malloc(sizeof(char)*20); | |
printf("Kerem a kifejezest: "); | |
getline(keplet, 1024); | |
printf("Kerem az x erteket: "); | |
getline(iksz, 19); | |
double x = atof(iksz); | |
parseExpression(keplet, root); | |
kiir(root->sub_items, 0); | |
double eredmeny = 0; | |
calculate(root, x, &eredmeny); | |
printf("%f\n", eredmeny); | |
getchar(); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment