Oscillation – Solution

For my solution to this month’s Oscillation Exercise I created a toggle variable. This variable switches between 1 and -1. It sets the direction for the cascading values.

Here is my solution:

#include <stdio.h>
  
int main()
{
    int count,value,direction;

    value = count = 0;
    direction = 1;

    while(count<20)
    {
        printf("%3d",value);
        value += direction;
        if( value==5 || value==-5)
            direction *= -1;
        count++;
    }
    putchar('\n');

    return(0);
}

Variable value is the number output, swinging back and forth between -5 and 5; count is the number of values to generate; and direction is either 1 or -1, which flips when value reaches 5 or -5.

Variable direction is initially set to 1 (positive) in Line 8. The statement value+=direction (Line 13) increments or decrements variable value. The if statement at Lines 14 and 15 toggles direction when value hits 5 or -5. The math is direction*=-1, which flips the variable between 1 and -1, back and forth.

This example is just one of many types of toggles you can program in C. Also popular are bitwise toggles, where individual bits in a value represent certain conditions in a program. Such code tests the bits to determine whether a setting is on or off. I enjoy twiddling bits, mostly because of my Assembly language background. Because bit-twiddling involves using bitwise-logical operators, some C programmers prefer instead to use char variables set to 1 or 0.

If you conjured a similar solution, great! Many potential resolutions of this puzzle exist, including those that would use sin() or some other math.h function to output similar results.

5 thoughts on “Oscillation – Solution

  1. (Second attempt – Dan, could you please delete the previous mess, thanks!)

    I made a slight change to your code to output a primitive graph of the values:

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

    int main()
    {
        int count, value, direction;

        value = count = 0;
        direction = 1;

        while(count < 40)
        {
            printf("%*c\n", value + 6, '*');
            value += direction;

            if( abs(value) == 5)
            {
                direction *= -1;
            }

            count++;
        }

        return(0);
    }

    I won't paste the output here as it will probably get messed up as HTML and end up looking like a polka dot jellyfish.

    As I said in my comment on your previous post, I'd like to do a horizontal version of this or a sine wave but can't be bothered! I don't know of any way of printing at a specified position so the only way I could think of was using a 2D char array, setting the individual chars, and then printing it out at the end. Would be interested to hear if anyone has any better solution.

  2. Neat trick with the %*c placeholder. I might have to explain that in a future post. Thanks!

  3. The * acts like a placeholder just like %c etc, so the corresponding variable or expression replaces it in the output. Deserves a blog post though.

    Every time I need to use it I realise I have forgotten how and have to Google it yet again. A comprehensive list of all the options (like – for left aligning) would be useful.

  4. The thought of drawing a graph horizontally has been bugging me so I sat down and did it just to get it out of my mind. Here it is:

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

    int main()
    {
        int count, value, direction;

        const int minmax = 8; // eg 5 goes from -5 to 0
        const int columns = 80;

        value = count = 0;
        direction = 1;

        // create 2D graph array
        // [(minmax * 2) + 1] allows 1 row per value, including 0
        // [columns + 1] allows for \0 string terminator
        char graph[(minmax * 2) + 1][columns + 1];

        // initialize array with spaces and \0
        for(int r = 0; r <= (minmax * 2); r++)
        {
            for(int c = 0; c < columns; c++)
            {
                graph[r][c] = ‘ ‘;
            }

            graph[r][columns] = ‘\0’;
        }

        while(count < columns)
        {
            graph[value + minmax][count] = ‘*’;

            value += direction;

            if(abs(value) == minmax)
            {
                direction *= -1;
            }

            count++;
        }

        for(int r = 0; r <= (minmax * 2); r++)
        {
            printf(“%s\n”, graph[r]);
        }

        return(0);
    }

    Of course you could do the same thing with a sine wave or anything else.

    Now I can forget all about it 🙂

  5. Very cool!

    I have some posts from long ago that go over the printf() formatting characters. I didn’t cover the *. In fact, in my own code, I often use an sprintf() function to concoct the width/precision placeholder. That’s way too much effort. Thanks again!

Leave a Reply