DZone Snippets is a public source code repository. Easily build up your personal collection of code snippets, categorize them with tags / keywords, and share them with the world

Roger has posted 34 posts at DZone. View Full User Profile

USACO Calfflac Problem

01.19.2011
| 914 views |
  • submit to reddit
        // Find any largest palindrome in a string no more than 20,000 characters long.
// The file has one or more lines. No line is longer than 80 characters (not counting newline)
// 
// Ignore punctuation, whitespace, numbers, and case when testing for palindromes, but
// keep these extra characters around so you can print them out as the answer.
//
// The largest palindrome is guaranteed to be at most 2,000 characters long before
// whitespace and punctuation are removed.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#include <ctype.h>

#define MAX_STRING 20001
#define MAX_LINE   81
#define MAX_PAL    2001

typedef struct {
    int begin;
    int end;
} palindex;

int getNextAlpha(char* string, int index) {
    int end = strlen(string);
    while (index++ <= end) {
        if (isalpha(string[index])) {
            return index;
        }
    }
    return end;
}

int getPrevAlpha(char* string, int index) {
    while (index-- >= 0) {
        if (isalpha(string[index])) {
            return index;
        }
    }
    return 0;
}

bool charsAreEqual(char first, char second) {
    return (tolower(first) == tolower(second));
}

int countAlphas(char* string) {
    int x, count = 0;
    for (x = 0; x < strlen(string); x++) {
        if (isalpha(string[x])) {
            count++;
        }
    }
    return count;
}

int countAlphasBetween(char* string, int index1, int index2) {
    int count = 0, x;
    for (x = index1; x <= index2; x++) {
        if (isalpha(string[x])) {
            count++;
        }
    }
    return count;
}

palindex getLargestPal(char* string, int index1, int index2) {
    int length = strlen(string);
    palindex curPal;
    curPal.begin = 0;
    curPal.end = 0;
    int sizeCur = 0, tempidx1 = 0, tempidx2 = 0;

    /* while we haven't exhausted the entire string */
    while (index1 >= 0 && index2 < length) {
        if (charsAreEqual(string[index1], string[index2])) {
            tempidx1 = index1;
            tempidx2 = index2;
            /* crawl each direction and see how big a palindrome you can get */
            while (charsAreEqual(string[getPrevAlpha(string, tempidx1)], string[getNextAlpha(string, tempidx2)]) && (index1 >= 0 && index2 < length)) {
                tempidx1 = getPrevAlpha(string, tempidx1);
                tempidx2 = getNextAlpha(string, tempidx2);
            }   
            if (countAlphasBetween(string, tempidx1, tempidx2) > sizeCur) {
                curPal.begin = tempidx1;
                curPal.end = tempidx2;
                sizeCur = countAlphasBetween(string, curPal.begin, curPal.end);
            }
            index1 = getNextAlpha(string, index1);
            index2 = getNextAlpha(string, index2);
        } else {
            while ((index2 < length) && (!charsAreEqual(string[index1], string[index2]))) {
                index1 = getNextAlpha(string, index1);
                index2 = getNextAlpha(string, index2);
            }
        }
    }

    return curPal;
}

int main(void) {
    FILE *fin, *fout;
    fin = fopen("calfflac.in", "r");
    fout = fopen("calfflac.out", "w");

    char *inText, *totalText, *longPal;
    palindex dice1, dice2;
    inText = malloc(MAX_LINE);
    totalText = malloc(MAX_STRING);
    longPal = malloc(MAX_PAL);
    memset(totalText, 0, MAX_STRING);
    memset(longPal, 0, MAX_PAL);

    while (fgets(inText, MAX_LINE, fin) != NULL) {
        strcat(totalText, inText);
    }

    dice1 = getLargestPal(totalText, 0, 1);
    dice2 = getLargestPal(totalText, 0, 2);
    int sizePal1 = countAlphasBetween(totalText, dice1.begin, dice1.end);
    int sizePal2 = countAlphasBetween(totalText, dice2.begin, dice2.end);

    if (sizePal2 > sizePal1) {
        dice1 = dice2;
    } else if (sizePal2 == sizePal1) { /* swap them if dice2 begins before dice1 */
        if (dice2.begin < dice1.begin) {
            dice1 = dice2;
        }
    }

    strncpy(longPal, &totalText[dice1.begin], (dice1.end - dice1.begin + 1));

    if (NULL != longPal) {
        fprintf(fout, "%d\n%s\n", countAlphas(longPal), longPal);
    }


    return EXIT_SUCCESS;
}
    
    Tags:
  • C