int main() { FILE *fin = fopen("gift1.in", "r"); FILE *fout = fopen("gift1.out", "w"); int number; char *name[10]; fscanf(fin, "%d", &number); int i; for(i = 0; i<number; i++){ name[i] = (char *)malloc(15 * sizeof(char)); fscanf(fin, "%s", name[i]); mapInsert(name[i]); } char giverName[15]; int j = 0; while(fscanf(fin, "%s", giverName) > 0){ //printf("---%s---\n", giverName); //printf("Number %d round: ", ++j); char *receiveName[10]; int moneyToGive; int person; fscanf(fin, "%d %d", &moneyToGive, &person); if(person == 0) continue; //printf("%s gives %d to %d person\n", giverName, moneyToGive, person); int i; for(i = 0; i < person; i++){ receiveName[i] = (char *)malloc(14 * sizeof(char)); fscanf(fin, "%s", receiveName[i]); struct map *cur; cur = mapSearch(receiveName[i]); add(cur, moneyToGive/person); ///printf("%s receive %d\n", receiveName[i], moneyToGive/person); free(receiveName[i]); } //printf("%s gives %d to\n", giverName, moneyToGive); minus(mapSearch(giverName), moneyToGive); moneyToGive = moneyToGive - moneyToGive / person * person; add(mapSearch(giverName), moneyToGive); } struct map *temp = head; while(temp){ fprintf(fout, "%s %d\n", temp->name, temp->money); temp = temp->next; } fclose(fin); fclose(fout); }
static void insert(struct map *m, const char *key, const char *value) { struct map_op op; op.op = MAP_INSERT; op.key.p = atomString(key); op.value = atomString(value); mapSearch(m,&op); }
static void test() { struct map *m = mapCreate(); insert(m,"1st","Hello"); insert(m,"2nd","World"); struct map_op op; op.op = MAP_TRAVERSE; op.value = NULL; const char *v =NULL; while ((v=mapSearch(m,&op))!=NULL) { printf("%s : %s\n",(const char *)(op.key.p),v); } mapRelease(m); }
static void como_execute(ComoFrame *frame, ComoFrame *callingframe) { size_t i; for(i = 0; i < O_AVAL(frame->code)->size; i++) { ComoOpCode *opcode = ((ComoOpCode *)(O_PTVAL(O_AVAL(frame->code)->table[i]))); switch(opcode->op_code) { default: { como_error_noreturn("Invalid OpCode got %d", opcode->op_code); } case POSTFIX_INC: { Object *value = NULL; value = mapSearchEx(frame->cf_symtab, O_SVAL(opcode->operand)->value); if(value == NULL) { como_error_noreturn("undefined variable '%s'", O_SVAL(opcode->operand)->value); } else { if(O_TYPE(value) != IS_LONG) { como_error_noreturn("unsupported value for POSTFIX_INC"); } else { long oldvalue = O_LVAL(value); O_LVAL(value) = oldvalue + 1; push(frame, newLong(oldvalue)); } } break; } case POSTFIX_DEC: { Object *value = NULL; value = mapSearchEx(frame->cf_symtab, O_SVAL(opcode->operand)->value); if(value == NULL) { como_error_noreturn("undefined variable '%s'", O_SVAL(opcode->operand)->value); } else { if(O_TYPE(value) != IS_LONG) { como_error_noreturn("unsupported value for POSTFIX_DEC"); } else { long oldvalue = O_LVAL(value); O_LVAL(value) = oldvalue - 1; push(frame, newLong(oldvalue)); } } break; } case IS_LESS_THAN: { Object *right = pop(frame); Object *left = pop(frame); assert(right); assert(left); if(objectValueIsLessThan(left, right)) { push(frame, newLong(1L)); } else { push(frame, newLong(0L)); } break; } case IADD: { Object *right = pop(frame); Object *left = pop(frame); assert(right); assert(left); if(O_TYPE(left) == IS_LONG && O_TYPE(right) == IS_LONG) { long value = O_LVAL(left) + O_LVAL(right); push(frame, newLong(value)); } else { char *left_str = objectToString(left); char *right_str = objectToString(right); Object *s1 = newString(left_str); Object *s2 = newString(right_str); Object *value = stringCat(s1, s2); push(frame, value); objectDestroy(s1); objectDestroy(s2); free(left_str); free(right_str); } break; } case IMINUS: { Object *right = pop(frame); Object *left = pop(frame); assert(right); assert(left); if(O_TYPE(left) != IS_LONG && O_TYPE(right) != IS_LONG) { como_error_noreturn("unsupported value for IMINUS"); } else { push(frame, newLong(O_LVAL(left) - O_LVAL(right))); } break; } case IS_LESS_THAN_OR_EQUAL: { Object *right = pop(frame); Object *left = pop(frame); assert(right); assert(left); if(objectValueCompare(left, right) || objectValueIsLessThan(left, right)) { push(frame, newLong(1L)); } else { push(frame, newLong(0L)); } break; } case JZ: { Object *cond = pop(frame); if(O_TYPE(cond) == IS_LONG && O_LVAL(cond) == 0) { i = (size_t)O_LVAL(opcode->operand); continue; } break; } case JMP: { i = O_LVAL(opcode->operand); continue; } case LABEL: { break; } case HALT: { break; } case IS_NOT_EQUAL: { Object *right = pop(frame); Object *left = pop(frame); if(!objectValueCompare(left, right)) { push(frame, newLong(1L)); } else { push(frame, newLong(0L)); } break; } case LOAD_CONST: { como_debug("LOAD_CONST"); push(frame, opcode->operand); break; } case STORE_NAME: { Object *value = pop(frame); mapInsertEx(frame->cf_symtab, O_SVAL(opcode->operand)->value, value); break; } /* This is where recursion was broken, don't do *ex */ case LOAD_NAME: { Object *value = NULL; value = mapSearch(frame->cf_symtab, O_SVAL(opcode->operand)->value); if(value) { goto load_name_leave; } else { value = mapSearch(global_frame->cf_symtab, O_SVAL(opcode->operand)->value); } if(value == NULL) { como_error_noreturn("undefined variable '%s'", O_SVAL(opcode->operand)->value); } load_name_leave: push(frame, value); break; } case CALL_FUNCTION: { Object *fn = pop(frame); Object *argcount = pop(frame); long i = O_LVAL(argcount); ComoFrame *fnframe; if(O_TYPE(fn) != IS_POINTER) { como_error_noreturn("name '%s' is not callable", O_SVAL(opcode->operand)->value); } fnframe = (ComoFrame *)O_PTVAL(fn); if(O_LVAL(argcount) != (long)(O_AVAL(fnframe->namedparameters)->size)) { como_error_noreturn("callable '%s' expects %ld arguments, but %ld were given", O_SVAL(opcode->operand)->value, (long)(O_AVAL(fnframe->namedparameters)->size), O_LVAL(argcount)); } //como_debug("calling '%s'", O_SVAL(opcode->operand)->value); // DOING THIS ACTUALLY DEFINES THE NAME AT RUNTIME // which could not be equal to that actual function body // declared // name = my_function // name() // that call will have "name" for value __FUNCTION__ // even though the real function is my_function // must define it at COMPILE time // mapInsertEx(fnframe->cf_symtab, "__FUNCTION__", // newString(O_SVAL(opcode->operand)->value)); while(i--) { como_debug("getting %ldth argument for function call '%s'", i, O_SVAL(opcode->operand)->value); Object *argname = O_AVAL(fnframe->namedparameters)->table[i]; Object *argvalue = pop(frame); mapInsert(fnframe->cf_symtab, O_SVAL(argname)->value, argvalue); char *argvaluestr = objectToString(argvalue); como_debug("%ldth argument: '%s' has value: %s", i, O_SVAL(argname)->value, argvaluestr); free(argvaluestr); } //ComoFrame *prev = frame; //fnframe->next = prev; como_execute(fnframe, NULL); push(frame, pop(fnframe)); //fnframe->next = NULL; break; } case IS_EQUAL: { Object *right = pop(frame); Object *left = pop(frame); push(frame, newLong((long)objectValueCompare(left, right))); break; } case ITIMES: { Object *right = pop(frame); Object *left = pop(frame); assert(right); assert(left); if(O_TYPE(right) != IS_LONG && O_TYPE(left) != IS_LONG) { como_error_noreturn("invalid operands for ITIMES"); } como_debug("ITIMES: %d, %d", O_TYPE(left), O_TYPE(right)); long value = O_LVAL(left) * O_LVAL(right); push(frame, newLong(value)); break; } case IRETURN: { /* If there wasn't a return statement found in func body* * The compiler will insert a 1 as the operand if * the AST had an expression for the return statement, * otherwise, it will be 0 * The actual value to be returned is popped from the stack */ if(! (O_LVAL(opcode->operand))) { push(frame, newLong(0L)); } return; } case IPRINT: { Object *value = pop(frame); size_t len = 0; char *sval = objectToStringLength(value, &len); fprintf(stdout, "%s\n", sval); fflush(stdout); free(sval); break; } } } }
int main(int argc, char **argv){ //check usage if(argc != 4){ fprintf(stderr, "usage: \"./pagerank\" damping_factor diffPR maxIterations"); return EXIT_FAILURE; } //initialise i/o FILE *fin = fopen("collection.txt","r"); FILE *fout = fopen("pagerankList.txt","w"); double d, diffPR; int maxIterations; slist urls = newList((void*)strdup, free); d = atof(argv[1]); diffPR = atof(argv[2]); maxIterations = atoi(argv[3]); //read collection.txt char buffer[BUFF_SIZE]; while(fscanf(fin, "%s", buffer) != EOF){ assert(buffer[0]); listEnter(urls, buffer); } int len = listLength(urls); Url *aurls = malloc(len * sizeof(url)); Graph g = newGraph(len); Hashmap m = newHashmap((len*3)/2); //convert llist to array for faster reading int i; for(i = 0; i < len; i++){ aurls[i] = malloc(sizeof(url)); aurls[i]->name = (char*)readList(urls); aurls[i]->pRank = (1/(double)len); aurls[i]->notActuallyZero = 1; mapInsert(m, aurls[i]->name, i); listNext(urls); } listReset(urls); //build graph for(i = 0; i < len; i++){ strcpy(buffer, aurls[i]->name); strcat(buffer, ".txt"); FILE *webpage = fopen(buffer, "r"); char *seen = calloc(len, sizeof(char)); int nOutgoingLinks = 0; fscanf(webpage, "#start Section-1"); while (fscanf(webpage, "%s", buffer) != EOF){ if(!strcmp(buffer, "#end")){ break; } int j = mapSearch(m, buffer); if(j != -1 && j != i && !seen[j]){ insertEdge(g,j,i); seen[j] = 1; nOutgoingLinks++; } } if(!nOutgoingLinks){ int j; for(j = 0; j < len; j++){ if(j != i) { insertEdge(g, j, i); } } nOutgoingLinks = len - 1; aurls[i]->notActuallyZero = 0; } aurls[i]->outdeg = nOutgoingLinks; fclose(webpage); free(seen); } dropMap(m); //calculate pagerank double diff = diffPR, *newPRanks = malloc(len * sizeof(double)); for(i = 0; i < maxIterations && diff > diffPR - EPS; i++){ diff = 0; int j; for(j = 0; j < len; j++){ double sum = 0; slist inUrls; for(inUrls = GetAdjacencies(g, j); hasNext(inUrls); listNext(inUrls)){ int val = *(int*)readList(inUrls); sum += aurls[val]->pRank / aurls[val]->outdeg; } listReset(inUrls); sum *= d; sum += (1 - d)/len; diff += fabs(aurls[j]->pRank - sum); newPRanks[j] = sum; } for(j = 0; j < len; j++) { aurls[j]->pRank = newPRanks[j]; } } free(newPRanks); mergesort((void**)aurls, len, urlComp, 1); print(aurls, fout, len); for(i = 0; i < len; i++){ free(aurls[i]); } free(aurls); fclose(fin); fclose(fout); freeList(urls); dropGraph(g); return EXIT_SUCCESS; }