“8/10 Palindromes”

10Jul18

The following is my solution to the “8/10 Palindromes” problem posed by Programming Praxis; I’d usually post my solution as a comment on that ‘site, but I learned after I posted as a comment on that ‘site my solution to the “Emirps” problem posed by that ‘site that that ‘site doesn’t support images in comments.

My solution is known to run on an Apple Power Mac G4 (AGP Graphics) (450MHz processor, 1GB memory) on both Mac OS 9.2.2 (International English) (my solution interpreted using Leonardo IDE 3.4.1) and Mac OS X 10.4.11 (my solution compiled using the command line: make).

(I’m just trying to solve the problems posed by the aforementioned ‘site whilst I try to get a job (and I’ve solved this problem in particular to test my understanding of: compiling a project using the command line; compiling a project using a makefile; and compiling a project wherein a function is defined – not just declared – in a header file, and wherein that function is subsequently invoked in multiple source code files; understanding that might be necessary if I’m to release an executable of my SDL2 joystick interrogator utility, or of my entry for Ludum Dare 5, for the Raspberry Pi); I’m well-aware that my solutions to the problems posed by the aforementioned ‘site are far from the best – but, in my defence, I don’t have any traditional qualifications in computer science :/ )

int to string.h:

#include <stdlib.h>
#include <limits.h>

typedef unsigned long
#ifndef LEONARDO
long
#endif
t_UnsignedLongInt;

static size_t f_NumberOfDigits( unsigned int p_int, const unsigned int p_base )
{
  if( p_int == 0 )
    return 1;
  else
  {
    size_t number_of_digits = 0;

    while( p_int > 0 )
    {
      number_of_digits ++;
      p_int /= p_base;
    }
    return number_of_digits;
  }
}

const char * const f_IntToString( unsigned int p_int, const unsigned int p_base )
{
  static char *string = NULL;
  t_UnsignedLongInt divisor = 1;
  size_t i = 0;

  if( p_base == 0 )
  {
    if( string != NULL )
      free( string );
    string = NULL;
    return NULL;
  }
  if( string == NULL )
  {
    const size_t octal = f_NumberOfDigits( UINT_MAX, 8 ) + 1;
    const size_t denary = f_NumberOfDigits( UINT_MAX, 10 ) + 1;
    size_t string_length;

    if( octal > denary )
      string_length = octal;
    else
      string_length = denary;
    string = ( char* )malloc( sizeof( char ) * string_length );
  }
  if( p_int == 0 )
  {
    string[ 0 ] = '0';
    string[ 1 ] = '\0';
    return string;
  }
  while( p_int / divisor > 0 )
    divisor *= p_base;
  divisor /= p_base;
  while( divisor > 0 )
  {
    const unsigned int digit = p_int / divisor;

    p_int -= ( digit * divisor );
    divisor /= p_base;
    string[ i ++ ] = '0' + digit;
  }
  string[ i ] = '\0';
  return string;
}

int to octal string.c:

const char * const f_IntToString( unsigned int p_int, const unsigned int p_base );

const char * const f_IntToOctalString( const unsigned int p )
{
  return f_IntToString( p, 8 );
}

int to denary string.c:

const char * const f_IntToString( unsigned int p_int, const unsigned int p_base );

const char * const f_IntToDenaryString( const unsigned int p )
{
  return f_IntToString( p, 10 );
}

July 10th, 2018.c:

#include "int to string.h"
#include "seal_bool.h" /* <http://GitHub.com/sealfin/C-and-C-Plus-Plus/blob/master/seal_bool.h> */
#include <string.h>
#include <ctype.h>
#include <stdio.h>

bool f_StringToInt( const char * const p_input, unsigned int * const p_output )
/*
Returns true if:
* p_input points to a string comprised of – and only of – one or more digits in the range [ 0, 9 ];
* and the number represented by the string pointed to by p_input is in the range [ 0, UINT_MAX ].
*/
{
  size_t i = 0;
  bool any_digits_encountered = false;
  t_UnsignedLongInt number = 0;

  for( ; i < strlen( p_input ); i ++ )
  {
    const char c = p_input[ i ];

    if( isdigit( c ))
    {
      any_digits_encountered = true;
      number *= 10;
      if( number > UINT_MAX )
        return false;
      number += ( c - '0' );
      if( number > UINT_MAX )
        return false;
    }
    else
      return false;
  }
  if( !any_digits_encountered )
    return false;
  *p_output = number;
  return true;
}

bool f_IsPalindrome( const char * const p )
{
  size_t i = 0, k = strlen( p ) - 1;

  while( i < k )
  {
    if( p[ i ] != p[ k ] )
      return false;
    i ++;
    k --;
  }
  return true;
}

const char * const f_IntToOctalString( const unsigned int p );
const char * const f_IntToDenaryString( const unsigned int p );

int main( const int argc, const char * const argv[] )
{
  const size_t index = 
  #ifdef LEONARDO
  0
  #else
  1
  #endif
  ;
  bool error_occurred = argc - 1 != index;
  unsigned int limit;

  if( !error_occurred )
    error_occurred = !f_StringToInt( argv[ index ], &limit );
  #ifndef LEONARDO
  printf( "\n" );
  #endif
  if( !error_occurred )
  {
    t_UnsignedLongInt i = 0;
    unsigned int number_of_palindromes = 0, *palindromes;

    for( ; i <= limit; i ++ )
      if( f_IsPalindrome( f_IntToOctalString( i )))
        if( f_IsPalindrome( f_IntToDenaryString( i )))
        {
          if( number_of_palindromes == 0 )
            palindromes = ( unsigned int* )malloc( sizeof( unsigned int ));
          else
            palindromes = ( unsigned int* )realloc( palindromes, sizeof( unsigned int ) * ( number_of_palindromes + 1 ));
          palindromes[ number_of_palindromes ++ ] = i;
        }
    printf( "The integer" );
    if( number_of_palindromes > 1 )
      printf( "s" );
    printf( " in the range [ 0, %u ] that ", ( unsigned int )limit );
    if( number_of_palindromes > 1 )
      printf( "are" );
    else
      printf( "is a" );
    printf( " palindrome" );
    if( number_of_palindromes > 1 )
      printf( "s" );
    printf( " in both octal and denary " );
    if( number_of_palindromes > 1 )
      printf( "are" );
    else
      printf( "is" );
    printf( ": " );
    for( i = 0; i < number_of_palindromes; i ++ )
    {
      if( i > 0 )
      {
        if( number_of_palindromes != 2 )
          printf( "," );
        printf( " " );
        if( i + 1 == number_of_palindromes )
          printf( "and " );
      }
      printf( "%u", palindromes[ i ] );
    }
    printf( ".\n" );
    free( palindromes );
    f_IntToString( 0, 0 );
  }
  else
    printf( "This program must be passed, via the command line, a denary integer in the range [ 0, %u ]; this program will then print (in denary) the integers from zero to (and including) that integer that are palindromes in both octal and denary.\n", ( unsigned int )UINT_MAX );
  #ifndef LEONARDO
  printf( "\n" );
  #endif
  if( !error_occurred )
    exit( EXIT_SUCCESS );
  else
    exit( EXIT_FAILURE );
}

Makefile:

main: int\ to\ string.h int\ to\ octal\ string.c int\ to\ denary\ string.c seal_bool.h July\ 10th,\ 2018.c
	gcc -c int\ to\ octal\ string.c
	gcc -c int\ to\ denary\ string.c
	gcc int\ to\ octal\ string.o int\ to\ denary\ string.o July\ 10th,\ 2018.c -o July\ 10th,\ 2018


No Responses Yet to ““8/10 Palindromes””

  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 )

Google photo

You are commenting using your Google 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 )

Connecting to %s


%d bloggers like this: