Mercurial > repo
view interps/fukyorbrane/report.c @ 7687:3d363a26ff5d
<moon_> ` mv templates/terminalWrapper templates/termwrapperOut
author | HackBot |
---|---|
date | Tue, 03 May 2016 21:45:16 +0000 |
parents | 859f9b4339e6 |
children |
line wrap: on
line source
/* * Copyright (c) 2009, 2011 Gregor Richards * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ /* NOTE: I am aware of how ugly this code is. It was quick hack. */ #ifndef _BSD_SOURCE #define _BSD_SOURCE #endif #include <pthread.h> #include <fcntl.h> #include <signal.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/types.h> #include <sys/wait.h> #include <unistd.h> #include "helpers.h" #define MINTAPELEN 10 #define MAXTAPELEN 30 #define POLARITIES 4 #define RUNCOUNT (((MAXTAPELEN-MINTAPELEN) + 1) * POLARITIES) #define KEEP_PROGRAMS 47 char *fyb, *cachedir; int programCount; char **programs; char *scores; int breakdown; struct ProgramScore { int id; int pts; double prc; }; void *runnerThread(void *pvp) { int p = (int) (size_t) pvp; int row = p * programCount; pid_t pid; int i; int st; char *cacheFilename; FILE *cacheF; /* go through each program ... */ for (i = 0; i < programCount; i++) { if (p == i) continue; /* check the cache */ SF(cacheFilename, malloc, NULL, (strlen(cachedir) + strlen(programs[p]) + strlen(programs[i]) + 5)); sprintf(cacheFilename, "%s/:%s:%s:", cachedir, programs[p], programs[i]); cacheF = fopen(cacheFilename, "r"); st = -1; if (cacheF != NULL) { /* get the result out of the cache */ st = getc(cacheF); fclose(cacheF); if (st == EOF) st = -1; scores[row + i] = st; } if (st == -1) { /* and run p vs i */ SF(pid, fork, -1, ()); if (pid == 0) { close(0); close(1); close(2); dup2(breakdown, 1); execlp(fyb, fyb, programs[p], programs[i], NULL); exit(0); } /* wait for it */ waitpid(pid, &st, 0); /* then get the score */ if (WIFEXITED(st)) { st = WEXITSTATUS(st); } else { st = 0; } scores[row + i] = st; /* and cache it */ cacheF = fopen(cacheFilename, "w"); if (cacheF != NULL) { putc(st, cacheF); fclose(cacheF); } } free(cacheFilename); } return NULL; } int winner(int p1, int p2) { char win1, win2; win1 = scores[p1*programCount + p2]; win2 = scores[p2*programCount + p1]; if (win1 == 1 && win2 != 1) return p1; else if (win1 == 2 && win2 != 2) return p2; else if (win2 == 2 && win1 != 2) return p1; else if (win2 == 1 && win1 != 1) return p2; return -1; } int ptscompar(const void *lv, const void *rv) { const struct ProgramScore *l = *((const struct ProgramScore **) lv); const struct ProgramScore *r = *((const struct ProgramScore **) rv); if (l->pts < r->pts) { return -1; } else if (l->pts > r->pts) { return 1; } else { return 0; } } int prccompar(const void *lv, const void *rv) { const struct ProgramScore *l = *((const struct ProgramScore **) lv); const struct ProgramScore *r = *((const struct ProgramScore **) rv); if (l->prc < r->prc) { return -1; } else if (l->prc > r->prc) { return 1; } else { return 0; } } int main(int argc, char **argv) { pthread_t *threads; int i, j; int *plainScores; double *preciseScores; struct ProgramScore **allScores; char *scoreFilename; FILE *scoreF; if (argc < 4) { fprintf(stderr, "Use: report <fyb program> <cache dir> <fyb files>\n"); return 1; } fyb = argv[1]; cachedir = argv[2]; programCount = argc - 3; programs = argv + 3; signal(SIGCHLD, SIG_DFL); /* allocate space for the scores */ SF(scores, malloc, NULL, (programCount * programCount)); /* now run them in threads */ breakdown = open("breakdown.txt", O_WRONLY|O_CREAT|O_TRUNC, 0666); SF(threads, malloc, NULL, (programCount * sizeof(pthread_t))); for (i = 0; i < programCount; i++) { /*pthread_create(&threads[i], NULL, runnerThread, (void *) (size_t) i);*/ runnerThread((void *) (size_t) i); } close(breakdown); /* wait for the threads to finish * / for (i = 0; i < programCount; i++) { pthread_join(threads[i], NULL); } */ /* allocate the score buffers */ SF(allScores, malloc, NULL, (programCount * sizeof(struct ProgramScore *))); for (i = 0; i < programCount; i++) { SF(allScores[i], malloc, NULL, (sizeof(struct ProgramScore))); allScores[i]->id = i; } /* now calculate the plain score for each */ SF(plainScores, malloc, NULL, (programCount * sizeof(int))); for (i = 0; i < programCount; i++) { int score = 0; for (j = 0; j < programCount; j++) { int win; if (i == j) continue; win = winner(i, j); if (win == i) { score++; } else if (win == j) { score--; } } allScores[i]->pts = plainScores[i] = score; } /* and the precise scores for each */ SF(preciseScores, malloc, NULL, (programCount * sizeof(double))); for (i = 0; i < programCount; i++) { double score = 0; for (j = 0; j < programCount; j++) { double value; int win; if (i == j) continue; /* get the value of j */ value = (double) (plainScores[j] + programCount) / (double) (2*programCount-2); /* and add the value if correct */ win = winner(i, j); if (win == i) { score += value; } else if (win == 0) { score += value/2; } } allScores[i]->prc = preciseScores[i] = score * 200 / (programCount-1); /* save it to the cache */ SF(scoreFilename, malloc, NULL, (strlen(cachedir) + strlen(programs[i]) + 8)); sprintf(scoreFilename, "%s/%s.score", cachedir, programs[i]); scoreF = fopen(scoreFilename, "w"); if (scoreF != NULL) { fprintf(scoreF, "%.1f", preciseScores[i]); fclose(scoreF); } free(scoreFilename); } /* now print out the scores */ qsort(allScores, programCount, sizeof(struct ProgramScore *), prccompar); printf("Pos ID Score Points Program\n"); for (i = programCount - 1; i >= 0; i--) { struct ProgramScore *sc = allScores[i]; printf(" %2d %2d %6.2f %6.2f %s\n", programCount - i, (int) sc->id, sc->prc, sc->pts, programs[sc->id]); } printf("\n"); /* and the full scoreboard */ /* header */ printf(" | "); for (i = 0; i < programCount; i++) { if (i < 10) printf(" "); else printf("%1d ", (int) (i/10%10)); } printf("|\n | "); for (i = 0; i < programCount; i++) { printf("%1d ", (int) (i%10)); } printf("| score | pts | program\n"); /* scores */ for (i = 0; i < programCount; i++) { printf("%2d | ", (int) i); for (j = 0; j < programCount; j++) { int win; if (i == j) { printf(" "); continue; } win = winner(i, j); if (win == i) { printf("+ "); } else if (win == j) { printf("- "); } else { printf("0 "); } } printf("| %5.1f | %3d | %s\n", preciseScores[i], plainScores[i], programs[i]); } /* kill any poorly-performing programs */ if (programCount > KEEP_PROGRAMS) { for (i = 0; i < programCount - KEEP_PROGRAMS; i++) { char buf[1024]; snprintf(buf, 1024, "hg rm -f %s", programs[allScores[i]->id]); system(buf); system(buf + 3); } system("hg commit -m Trimming."); } return 0; }