# コピペ: general sum of squares of digits and repeat

This is a routine to sum the squares of the digits of a number, then repeat on the resulting sum, until a sum is repeated, generalized to numeric base 2 through (maybe) 36.

C

2020-09-14 21:59

` /* Routine to sum the squares of the digits of a number passed on the command line, ** then repeat on the sum ** until a repeat of a sum is found,  ** in multiple bases up to (probably) base 36. ** Inspired by a post by Lee Bradley to the Not Just Tiny C Facebook Group: ** https://www.facebook.com/groups/299317782048/permalink/10158931086097049/ ** http://primepuzzle.com/not.just.tiny.c/steinhaus.tc ** ** Joel Rees, Amagasaki, Japan, Sept. 2020 */   #include <stdio.h> #include <stdlib.h> #include <ctype.h>   /* int todigit( int ch ) {  ch = toupper( ch );    ch -= '0';    if ( ch < 0 )    {  ch = -1;    }    else if ( ch > 9 )    {  ch -= 'A' - '9' - 1; / * Because I'm an artist. * /    }    return ch; } */   char chconv( int digit ) {  digit += '0';    if ( digit > '9' )    {  digit += 'A' - '9' - 1;    } /*dbg* / printf( "digit: %d:%c\n", digit, digit ); */    return (char) digit; }   #define MAXCONV_DIGITS 64 /* for 64 bit int CPUs */  /* buffer must be long enough for long long in binary, plus termination! ** Make it MAXCONV_DIGITS + 1 long. */ char * outint( char buffer[], int d, int base ) {  char * convpt = buffer + MAXCONV_DIGITS;     * convpt = 0;    while ( ( convpt > buffer ) && ( d > 0 ) )    {  * --convpt = chconv( d % base );       d /= base;    }    return convpt; }   long base = 10;   int todigit( int ch ) {  char digitbuffer[ 2 ]; /* It's all we need. */    char * endpt = digitbuffer;    long val;     digitbuffer[ 0 ] = (char) ch;    digitbuffer[ 1 ] = 0;    val = strtol( digitbuffer, &endpt, base );    if ( endpt != digitbuffer + 1 )    {  val = -1;    }    return (int) val; }   int digsquaresum( char * digits ) {  int sum = 0; /* Even 16 bit int allows length > 655. */    int ch = 0;     while ( isalnum( ch = * digits++ ) )    {  int dig = todigit( ch );       sum += dig * dig;    }    return sum; }   #define SEQUENCEMAX 64   int sequence( char * start ) {  int sum, i;    int repeater = 0;    static int last[ SEQUENCEMAX + 1 ];    char newval[ MAXCONV_DIGITS + 1 ] = { 0 }; /* Note MAXCONV_DIGITS plus terminator! */     for ( i = 0; i <= SEQUENCEMAX; ++i )    {  last[ i ] = -1;    }    do     {  int i;       char * convpt = newval;        sum = digsquaresum( start );       for ( i = SEQUENCEMAX; i > 0; --i )       {  last[ i ] = last[ i - 1 ];       }       last[ 0 ] = sum;       for ( i = 0; ( i < SEQUENCEMAX ) && ( last[ i ] != -1 ); ++i )       {  int j;          for ( j = i + 1; ( j <= SEQUENCEMAX ) && ( last[ j ] != -1 ); ++j )          {  if ( last[ i ] == last[ j ] )             {  repeater = last[ i ];             }          }       }        convpt = outint( newval, sum, base );       puts( convpt );       start = convpt;    } while ( ( sum != 1 ) && ( repeater == 0 ) && ( last[ SEQUENCEMAX ] != 0 ) );    return repeater; }   int main( int argc, char * args[] ) {    if ( argc < 2 )    {  return EXIT_FAILURE;    }    else    {  if ( args[ 1 ][ 0 ] == '-' )       {  if ( args[ 1 ][ 1 ] != '?' )          {  base = (int) strtol( args[ 1 ] + 1, NULL, 10 );          }          if ( ( base < 2 ) || ( argc == 2 ) )          {  printf( "%s [-<base> ] <number>\n", args[ 0 ] );             puts( "\tbase unimplemented." );          }          if ( args[ 1 ][ 1 ] == '?' )          {  return EXIT_SUCCESS;          }          if ( ( base < 2 ) || ( argc == 2 ) )          {  return EXIT_FAILURE;          }          sequence( args[ 2 ] );       }       else       {  sequence( args[ 1 ] );       }    }     return EXIT_SUCCESS; }`