H : ASCII Art

08Dec12

I recently participated in the Advent Programming Contest organised by the IEEE Student Branch Klagenfurt (with support from Alpen-Adria-Universität Klagenfurt and Universität Passau), achieving a rank of 11th (out of 118 participants); as submissions of solutions to that contest are now closed, I’m posting here the solutions I submitted to that contest.

Problem (H; easy difficulty):

ASCII Art

To put Santa and the Reindeer into ASCII, we are using the following encoding: The ascii sequence for Santa is

*<]:-))##

Rudolph, the red-nosed reindeer is

>:o)

All other reindeer look like this

>:*)

The mirrored versions of the sequences do not count.

Problem

Implement a program that reads lines from standard input and analyzes the string for the occurence of Santa, Rudolph and the other reindeer. The answer should list the detected elements, separated by a comma and space. If Rudolph is detected, the other reindeer should be named “other reindeer”. If there is no Rudolph, just output “reindeer”. Include the count before the (other) reindeer. There can be other elements in the string. The will be at most one Santa, at most one Rudolph and at most eight other reindeer. The order of appearance can be arbitrary, but always list in the order Santa, Rudoplh, reindeer. If there is no Santa in the string, the program should terminate after printing the result.

Example

Input

*<]:-))## >:o) >:*) >:*) >:*)
*<]:-))## >:*)
>:o) *<]:-))##
>:*) >:*) >:*) >:*) >:*) >:*) >:*) >:*)

Output

Santa, Rudolph, three other reindeer
Santa, one reindeer
Santa, Rudolph
eight reindeer

Solution (H.c):

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

typedef struct t_CharStackNode_struct
{
  struct t_CharStackNode_struct *m_down;
  char m_char;
}
t_CharStackNode;

typedef enum
{
  false = 0,
  true
}
bool;

static t_CharStackNode *g_charStack_top = NULL;
static size_t g_charStack_numberOfCharactersOnStack = 0;

void p_CharStack_Reset( void );
void p_CharStack_Input( FILE *p );
char *f_CharStack_String( void );

static bool f_CompareStrings( const char * const p_isThis, const char * const p_inThis, size_t p_startingAt )
{
  size_t i = 0;
  for( ; i < strlen( p_isThis ); i ++, p_startingAt ++ )
  {
    if( p_startingAt >= strlen( p_inThis ))
      return false;
    if( p_isThis[ i ] != p_inThis[ p_startingAt ] )
      return false;
  }
  return true;
}

#define M_COMPARE_STRINGS( p_functionName, p_stringConstant )                      \
  static bool f_ ## p_functionName( const char * const p_string, size_t *p_index ) \
  {                                                                                \
    if( f_CompareStrings( p_stringConstant, p_string, *p_index ))                  \
    {                                                                              \
      ( *p_index ) += strlen( p_stringConstant );                                  \
      return true;                                                                 \
    }                                                                              \
    return false;                                                                  \
  }

M_COMPARE_STRINGS( Santa, "*<]:-))##" )
M_COMPARE_STRINGS( Rudolph, ">:o)" )
M_COMPARE_STRINGS( OtherReindeer, ">:*)" )

int main( void )
{
  bool santa, rudolph;
  int otherReindeer;
  char *s;
  size_t i;
  static const char one[] = "one", two[] = "two", three[] = "three", four[] = "four", five[] = "five", six[] = "six", seven[] = "seven", eight[] = "eight";
  static const char * const numbers[] = { one, two, three, four, five, six, seven, eight };
  l_LOOP:
    santa = false;
    rudolph = false;
    otherReindeer = 0;
    p_CharStack_Input( stdin );
    s = f_CharStack_String();
    i = 0;
    while( i < strlen( s ))
    {
      bool incrementI = true;
      if( f_Santa( s, &i ))
      {
        santa = true;
        incrementI = false;
      }
      if( f_Rudolph( s, &i ))
      {
        rudolph = true;
        incrementI = false;
      }
      if( f_OtherReindeer( s, &i ))
      {
        otherReindeer ++;
        incrementI = false;
      }
      if( incrementI )
        i ++;
    }
    if( santa )
      printf( "Santa" );
    if( santa && rudolph )
      printf( ", " );
    if( rudolph )
      printf( "Rudolph" );
    if(( santa || rudolph ) && ( otherReindeer > 0 ))
      printf( ", " );
    if( otherReindeer > 0 )
      printf( "%s%s reindeer", numbers[ otherReindeer - 1 ], ( rudolph )?" other":"" );
    printf( "\n" );
    if( santa )
      goto l_LOOP;
  return 0;
}

static void p_CharStack_Delete( t_CharStackNode *p )
{
  if( p != NULL )
  {
    p_CharStack_Delete( p->m_down );
    free( p );
  }
}

void p_CharStack_Reset( void )
{
  p_CharStack_Delete( g_charStack_top );
  g_charStack_top = NULL;
  g_charStack_numberOfCharactersOnStack = 0;
}

void p_CharStack_Input( FILE *p )
{
  char c;
  t_CharStackNode *n;
  p_CharStack_Reset();
  do
  {
    fscanf( p, "%c", &c );
    if( c != '\n' )
    {
      n = ( t_CharStackNode* )malloc( sizeof( t_CharStackNode ));
      n->m_down = g_charStack_top;
      g_charStack_top = n;
      n->m_char = c;
      if( g_charStack_numberOfCharactersOnStack < ( size_t )-2 )
        g_charStack_numberOfCharactersOnStack ++;
    }
  }
  while( c != '\n' );
}

char *f_CharStack_String( void )
{
  char *s = ( char* )malloc( sizeof( char ) * ( g_charStack_numberOfCharactersOnStack + 1 ));
  size_t i = 0, k = g_charStack_numberOfCharactersOnStack - 1;
  t_CharStackNode *n = g_charStack_top;
  for( ; i < g_charStack_numberOfCharactersOnStack; i ++, k --, n = n->m_down )
    s[ k ] = n->m_char;
  s[ i ] = '\0';
  return s;
}

Testing:

gcc -std=c99 -Wall -lm H.c
mv a.out H
./H
*<]:-))## >:o) >:*) >:*) >:*)
Santa, Rudolph, three other reindeer
*<]:-))## >:*)
Santa, one reindeer
>:o) *<]:-))##
Santa, Rudolph
>:*) >:*) >:*) >:*) >:*) >:*) >:*) >:*)
eight reindeer
Advertisements


No Responses Yet to “H : ASCII Art”

  1. Leave a Comment

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s


%d bloggers like this: