p0022_s0.c

problem 22 · 60 lines

/* Solution to Euler Problem 22: Names Scores. */
#include "runner.h"



/* Alphabetical word value: sum of letter positions (A=1 .. Z=26), skipping quotes/spaces. */
static int word_to_num(const char *word) {
    int sum = 0;
    for (const char *c = word; *c; c++) {
        if (*c == '"' || *c == ' ') continue;
        sum += (*c - 64);
    }
    return sum;
}

/* qsort comparator: lexicographic order on the raw quoted tokens. */
static int cmp_str(const void *a, const void *b) {
    return strcmp(*(const char **)a, *(const char **)b);
}

/* Sort the names, then sum each name's word value weighted by its 1-based rank; O(n log n). */
const char *solve(int argc, char *argv[]) {
    static char _answer[32];
    if (argc < 2) { snprintf(_answer, sizeof _answer, "%lld", (long long)(-1)); return _answer; }
    const char *file_url = argv[1];

    char *text = get_text_file(file_url);
    if (!text) { snprintf(_answer, sizeof _answer, "%lld", (long long)(-1)); return _answer; }

    /* Count commas to estimate number of names */
    int count = 1;
    for (char *p = text; *p; p++) {
        if (*p == ',') count++;
    }

    char **names = malloc((size_t)count * sizeof(char *));
    if (!names) { free(text); { snprintf(_answer, sizeof _answer, "%lld", (long long)(-1)); return _answer; } }

    /* Split by comma */
    int n = 0;
    char *token = strtok(text, ",");
    while (token) {
        names[n++] = token;
        token = strtok(NULL, ",");
    }

    /* Sort alphabetically */
    qsort(names, (size_t)n, sizeof(char *), cmp_str);

    long long total = 0;
    for (int i = 0; i < n; i++) {
        long long score = (long long)(i + 1) * word_to_num(names[i]);
        total += score;
    }

    free(names);
    free(text);
    { snprintf(_answer, sizeof _answer, "%lld", (long long)(total)); return _answer; }
}