K&R Solutions - 1.13, Part 2

Q: The same as part one, but vertical.

A:

#include <stdio.h>

int main(void) 
{
  int FREQUENCY_LENGTH = 10; 
  int frequencies[FREQUENCY_LENGTH];
  int i, j, c;
  int tally = 0;
  int highest = 0;

  // We're tallying in the exact same way.
  for (i = 0; i < FREQUENCY_LENGTH; ++i) {
    frequencies[i] = 0;
  }

  while ((c = getchar()) != EOF) {
    if (c == '.' || c == '\n' || c == '\t' || c == ' ' || c == ',') {
      if (tally > FREQUENCY_LENGTH) {
        tally = FREQUENCY_LENGTH - 1;
      }
      ++frequencies[tally];
      tally = 0;
    } else {
      ++tally;
    }
  }

  /* First, we need the height of the highest bar.
  *  At the top of the function, temp is set to zero. Normally a function
  *  wouldn't be this long, but we haven't got to that part fo the book yet.
  */
  for (i = 0; i < FREQUENCY_LENGTH; i++) {
    if (frequencies[i] > highest) {
      highest = frequencies[i];
    }
  }

  /* Now we keep drawing the bars untill our 'highest' variable, and everything
   * in our tallies is zeroed out.
   */
  while (highest) {
    // Remember there are no zero-length words so we skip 0. Feel free to play
    // around with this, because some junk data is getting stored in
    // frequencies[0]. Why?
    for(i = 1; i < FREQUENCY_LENGTH; i++) {
      if (frequencies[i] == highest) {
        printf(" | ");
        frequencies[i]--;
      } else {
        printf("   ");
      }
    }
    printf("\n");
    highest--;
  }

  /* Now we print a handy guide at the bottom.
   */
  for (i = 1; i < FREQUENCY_LENGTH; i++) {
    printf("---");
  }
  printf("-\n");
  for (i = 1; i < FREQUENCY_LENGTH; i++) {
    if (i == FREQUENCY_LENGTH - 1) {
      printf(" %d+", i);
    } else {
      printf(" %d ", i);
    }
  }
  printf("\n");

  return 0;
}
The worst of misery
Is when a nature framed for noblest things
Condemns itself in youth to petty joys,
And, sore athirst for air, breathes scanty life
Gasping from out the shallows.
Supercalifragilisticexpialidocious.

(ctrl+d)

       |                   
       |        |          
       |  |     |          
    |  |  |     |          
    |  |  |  |  |  |  |    
    |  |  |  |  |  |  |    
 |  |  |  |  |  |  |  |  | 
----------------------------
 1  2  3  4  5  6  7  8  9+ 

You can play around with this quite a bit. Removing one line and then changing one character, and we get a nice little graph:

       .                   
                .          
          .                
    .                      
             .     .  .    
                           
 .                       . 
----------------------------
 1  2  3  4  5  6  7  8  9+