Challenge: tightest code to find-replace a string

Discussion in 'C Programming' started by DFS, Jun 6, 2014.

  1. If I were given such an instruction in the context of a secretarial
    job, that would provide a great deal of information. You gave no
    such context. I answered as a software developer, which you already
    know is what I am.
    Ok, so we seem to be in agreement, now that you've provided some
    more context.

    But if we're talking about doing search-and-replace within a string
    *as a programming problem*, the requirements can and should be
    defined unambiguously. If I'm writing an implementation of sed,
    for example, I'll be working from a specification that leaves no
    doubt what should happen if there's an overlap.
     
    Keith Thompson, Jun 12, 2014
    #81
    1. Advertisements

  2. Often there's someone who stands between the client and the programmer,
    turning business requirements into some sort of formal specification.
    You can argue about the wisdom of that paradigm of software development.
    But often there isn't.

    If you're writing an implementation of sed, you have to be compatible.
    Not so for the first sed author.
     
    Malcolm McLean, Jun 13, 2014
    #82
    1. Advertisements

  3. DFS

    BartC Guest

    In the case of this thread, the OP is the first author of the challenge, and
    everyone else needs to write compatible implementations.
     
    BartC, Jun 13, 2014
    #83
  4. "DFS" wrote in message
    FWIW, check out this thread:

    https://groups.google.com/forum/#!topic/comp.lang.c/cUeUlQd38-o/overview


    Here was my submission:

    https://groups.google.com/forum/#!original/comp.lang.c/cUeUlQd38-o/VlU8pTgRk8EJ

    http://pastebin.com/f62c80892

    This transforms tab characters into spaces.

    ____________________________________________________
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>




    #define TAB_MAX 1024U
    #define TAB_DEFAULT 1U




    typedef char static_assert[
    TAB_MAX > 0 && TAB_DEFAULT > 0 ? 1 : -1
    ];




    struct detab {
    FILE* in_file;
    FILE* out_file;
    unsigned long int tabs[TAB_MAX + 1];
    };




    int
    detab_startup(
    struct detab* const self,
    int argc,
    char** argv
    ) {
    if (argc > 1) {
    size_t i, size = 0;
    char* stop = NULL;
    char* cur = argc == 2 ? argv[1] : argv[2];
    while (*cur && size < TAB_MAX) {
    self->tabs[size] = strtoul(cur, &stop, 10);
    if (! self->tabs[size]) self->tabs[size] = TAB_DEFAULT;
    ++size;
    if (! *stop) break;
    cur = stop + 1;
    }
    for (i = size; i < TAB_MAX + 1; ++i) {
    self->tabs = TAB_DEFAULT;
    }
    if (argc > 2) {
    self->in_file = fopen(argv[1], "rt");
    if (! self->in_file) {
    fprintf(stderr, "could not open the [in] file!\n");
    return 0;
    }
    } else {
    self->in_file = stdin;
    }
    self->out_file = stdout;
    return 1;
    } else {
    fprintf(stderr, "invalid argument(s)!\n");
    }
    return 0;
    }


    int
    detab_shutdown(
    struct detab* const self
    ) {
    if (self->in_file != stdin && fclose(self->in_file)) {
    fprintf(stderr, "there was an error closing the [in] file!\n");
    return 0;
    }
    return 1;
    }


    int
    detab(
    struct detab* const self
    ) {
    int c;
    unsigned long int i = 1;
    unsigned long int col = 0;
    unsigned long int tab = 0;

    while((c = getc(self->in_file)) != EOF) {
    switch (c) {
    case '\t':
    do {
    if (putc(' ', self->out_file) == EOF) {
    goto bail_out;
    }
    ++i;
    } while (tab < TAB_MAX && ++col % self->tabs[tab]);
    if (tab < TAB_MAX) ++tab;
    break;
    case '\n':
    i = 0;
    col = -1;
    tab = 0;
    default:
    ++i;
    if (tab < TAB_MAX && ! (i % self->tabs[tab])) {
    ++tab;
    }
    col = (col + 1) % self->tabs[tab];
    if (putc(c, self->out_file) == EOF) {
    goto bail_out;
    }
    }
    }
    bail_out:;
    if (ferror(self->in_file)) {
    fprintf(stderr, "there was an error reading from the [in] file!\n");
    return 0;
    }
    if (ferror(self->out_file)) {
    fprintf(stderr, "there was an error writing to the [out] file!\n");
    return 0;
    }
    return 1;
    }




    int main(
    int argc,
    char** argv
    ) {
    int status = EXIT_FAILURE;
    struct detab self = { NULL };
    if (detab_startup(&self, argc, argv)) {
    status = EXIT_SUCCESS;
    if (! detab(&self)) {
    status = EXIT_FAILURE;
    }
    if (! detab_shutdown(&self)) {
    status = EXIT_FAILURE;
    }
    }
    return status;
    }
    ____________________________________________________


    ;^)
     
    Chris M. Thomasson, Jun 14, 2014
    #84
  5. DFS

    Stefan Ram Guest

    You might have guessed this, but it should be added here
    that this function returns -1 to indicate end-of-input.
     
    Stefan Ram, Jun 15, 2014
    #85
  6. DFS

    Stefan Ram Guest

    See also Ā»string rewritingĀ«, for example:

    http://mathworld.wolfram.com/StringRewritingSystem.html
     
    Stefan Ram, Jun 15, 2014
    #86
    1. Advertisements

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.