Scramble a String

Difficulty: Hard

Most functions are nice to strings. They manipulate the characters in a useful or clever way, returning an important value or an updated version of the text. But not every string function needs to be so kind, such as the one you write for this Exercise.

It’s called the scramble() function. It consumes a string and rearranges the characters in random order. Here’s a sample run:

Original: Onomatapoeia
Scrambled: epaOiaaonmto

The scramble() function effectively rearranged all the letters in Onomatopoeia into epaOiaaonmto. This result could be useful to someone somewhere, but you don’t need to care as you attempt to code the scramble() function on your own.

To be kind to you, here is the skeleton you can use to start your coding efforts:

void scramble(char *p,int len)
{
}

int main()
{
    char word[] = "Onomatapoeia";

    /* seed the randomizer */
    srand( (unsigned)time(NULL) );

    /* scramble the string */
    printf("Original: %s\n",word);
    scramble(word,strlen(word));
    printf("Scrambled: %s\n",word);

    return(0);
}

The scramble() function accepts the string’s address and its length. Your task is to code the function’s guts, somehow magically rearranging the characters in a random manner. Remember: The function doesn’t return a string; the passed string is modified through pointers. And don’t forget to include the proper header files!

Please try this Exercise on your own before you check out my solution.

5 thoughts on “Scramble a String

  1. This is basically an anagram generator isn’t it?

    Within a loop of whatever length you feel like using you could generate 2 random ints between 0 and the length of the string -1, and then swap the 2 characters at those indexes in-place. (You could check the 2 random numbers aren’t the same if you wanted, using a while loop and only incrementing the counter if you actually do a swap.)

    You can use XOR swapping on chars, eg:

    int a = 45; // 00101101
    int b = 99; // 01100011
    a = a ^ b; // 01001110
    b = a ^ b; // 00101101
    a = a ^ b; // 01100011

    There is always a chance, however small, that the anagram would come out very similar or even identical to the original word. You could run it through a word distance algorithm to check if it’s sufficiently mixed up, and keep going if not.

  2. I just learned of a GNU C library function, strfry(). It also scrambles strings, though it’s not available in all C libraries. I’ll put up a post about it in the future.

  3. (Hi Dan, could you please delete the previous comment. I messed it up. Sorry!)

    I wasn’t going to bother coding the idea I came up with but I thought I might as well.

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <time.h>
    
    void scramble(char *p, int len)
    {
        int i = 0;
    
        while(i < len)
        {
            int c1 = (rand() % (len));
            int c2 = (rand() % (len));
    
            if(c1 != c2)
            {
                p[c1] = p[c1] ^ p[c2];
                p[c2] = p[c1] ^ p[c2];
                p[c1] = p[c1] ^ p[c2];
    
                i++;
            }
        }
    }
    
    int main()
    {
        char word[] = "Onomatapoeia";
    
        /* seed the randomizer */
        srand( (unsigned)time(NULL) );
    
        /* scramble the string */
        printf("Original: %s\n", word);
        scramble(word, strlen(word));
        printf("Scrambled: %s\n", word);
    
        return(0);
    }

    I found using len as the number of swaps works fine.

Leave a Reply