Skip to content

Instantly share code, notes, and snippets.

@webprogramozo
Last active August 2, 2022 09:49
Show Gist options
  • Save webprogramozo/13b53f04b47ebdcba3a62883202f4630 to your computer and use it in GitHub Desktop.
Save webprogramozo/13b53f04b47ebdcba3a62883202f4630 to your computer and use it in GitHub Desktop.
IntegraThor - command line definite integral calculator (oldie school project from 2014)
#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