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
公開期間
無期限
  1. /* Routine to sum the squares of the digits of a number passed on the command line,
  2. ** then repeat on the sum
  3. ** until a repeat of a sum is found,
  4. ** in multiple bases up to (probably) base 36.
  5. ** Inspired by a post by Lee Bradley to the Not Just Tiny C Facebook Group:
  6. ** https://www.facebook.com/groups/299317782048/permalink/10158931086097049/
  7. ** http://primepuzzle.com/not.just.tiny.c/steinhaus.tc
  8. **
  9. ** Joel Rees, Amagasaki, Japan, Sept. 2020
  10. */
  11. #include <stdio.h>
  12. #include <stdlib.h>
  13. #include <ctype.h>
  14. /*
  15. int todigit( int ch )
  16. { ch = toupper( ch );
  17. ch -= '0';
  18. if ( ch < 0 )
  19. { ch = -1;
  20. }
  21. else if ( ch > 9 )
  22. { ch -= 'A' - '9' - 1; / * Because I'm an artist. * /
  23. }
  24. return ch;
  25. }
  26. */
  27. char chconv( int digit )
  28. { digit += '0';
  29. if ( digit > '9' )
  30. { digit += 'A' - '9' - 1;
  31. }
  32. /*dbg* / printf( "digit: %d:%c\n", digit, digit ); */
  33. return (char) digit;
  34. }
  35. #define MAXCONV_DIGITS 64 /* for 64 bit int CPUs */
  36. /* buffer must be long enough for long long in binary, plus termination!
  37. ** Make it MAXCONV_DIGITS + 1 long.
  38. */
  39. char * outint( char buffer[], int d, int base )
  40. { char * convpt = buffer + MAXCONV_DIGITS;
  41. * convpt = 0;
  42. while ( ( convpt > buffer ) && ( d > 0 ) )
  43. { * --convpt = chconv( d % base );
  44. d /= base;
  45. }
  46. return convpt;
  47. }
  48. long base = 10;
  49. int todigit( int ch )
  50. { char digitbuffer[ 2 ]; /* It's all we need. */
  51. char * endpt = digitbuffer;
  52. long val;
  53. digitbuffer[ 0 ] = (char) ch;
  54. digitbuffer[ 1 ] = 0;
  55. val = strtol( digitbuffer, &endpt, base );
  56. if ( endpt != digitbuffer + 1 )
  57. { val = -1;
  58. }
  59. return (int) val;
  60. }
  61. int digsquaresum( char * digits )
  62. { int sum = 0; /* Even 16 bit int allows length > 655. */
  63. int ch = 0;
  64. while ( isalnum( ch = * digits++ ) )
  65. { int dig = todigit( ch );
  66. sum += dig * dig;
  67. }
  68. return sum;
  69. }
  70. #define SEQUENCEMAX 64
  71. int sequence( char * start )
  72. { int sum, i;
  73. int repeater = 0;
  74. static int last[ SEQUENCEMAX + 1 ];
  75. char newval[ MAXCONV_DIGITS + 1 ] = { 0 }; /* Note MAXCONV_DIGITS plus terminator! */
  76. for ( i = 0; i <= SEQUENCEMAX; ++i )
  77. { last[ i ] = -1;
  78. }
  79. do
  80. { int i;
  81. char * convpt = newval;
  82. sum = digsquaresum( start );
  83. for ( i = SEQUENCEMAX; i > 0; --i )
  84. { last[ i ] = last[ i - 1 ];
  85. }
  86. last[ 0 ] = sum;
  87. for ( i = 0; ( i < SEQUENCEMAX ) && ( last[ i ] != -1 ); ++i )
  88. { int j;
  89. for ( j = i + 1; ( j <= SEQUENCEMAX ) && ( last[ j ] != -1 ); ++j )
  90. { if ( last[ i ] == last[ j ] )
  91. { repeater = last[ i ];
  92. }
  93. }
  94. }
  95. convpt = outint( newval, sum, base );
  96. puts( convpt );
  97. start = convpt;
  98. } while ( ( sum != 1 ) && ( repeater == 0 ) && ( last[ SEQUENCEMAX ] != 0 ) );
  99. return repeater;
  100. }
  101. int main( int argc, char * args[] )
  102. {
  103. if ( argc < 2 )
  104. { return EXIT_FAILURE;
  105. }
  106. else
  107. { if ( args[ 1 ][ 0 ] == '-' )
  108. { if ( args[ 1 ][ 1 ] != '?' )
  109. { base = (int) strtol( args[ 1 ] + 1, NULL, 10 );
  110. }
  111. if ( ( base < 2 ) || ( argc == 2 ) )
  112. { printf( "%s [-<base> ] <number>\n", args[ 0 ] );
  113. puts( "\tbase unimplemented." );
  114. }
  115. if ( args[ 1 ][ 1 ] == '?' )
  116. { return EXIT_SUCCESS;
  117. }
  118. if ( ( base < 2 ) || ( argc == 2 ) )
  119. { return EXIT_FAILURE;
  120. }
  121. sequence( args[ 2 ] );
  122. }
  123. else
  124. { sequence( args[ 1 ] );
  125. }
  126. }
  127. return EXIT_SUCCESS;
  128. }
ダウンロード 印刷用表示

このコピペの URL

JavaScript での埋め込み

iframe での埋め込み

元のテキスト