@@ -77,10 +77,12 @@ TestMathsCatSnippets = class(TTestCase)
77
77
procedure TestWeightedArithMean_Integer ;
78
78
procedure TestWeightedArithMean_Cardinal ;
79
79
procedure TestWeightedArithMean_Double ;
80
- procedure TestDigitCountBase ;
80
+ procedure TestDigitCountBase ; // required by DigitsOf, IsNarcissistic
81
81
procedure TestDigitSumBase ;
82
82
procedure TestDigitsOf ;
83
- procedure TestDigitPowerSum ;
83
+ procedure TestDigitPowerSum ; // required by IsNarcissistic
84
+ procedure TestIsPalindromic ;
85
+ procedure TestIsNarcissistic ;
84
86
end ;
85
87
86
88
implementation
@@ -564,6 +566,141 @@ procedure TestMathsCatSnippets.TestGCD2;
564
566
CheckEquals(10 , GCD2(10 , -10 ), ' GCD2(10, -10)' );
565
567
end ;
566
568
569
+ procedure TestMathsCatSnippets.TestIsNarcissistic ;
570
+ const
571
+ NarcNumsBase10: array [1 ..25 ] of Integer = (
572
+ // Source: https://rosettacode.org/wiki/Narcissistic_decimal_number
573
+ 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 153 , 370 , 371 , 407 , 1634 , 8208 , 9474 , 54748 ,
574
+ 92727 , 93084 , 548834 , 1741725 , 4210818 , 9800817 , 9926315
575
+ );
576
+ // Following all sourced from https://en.wikipedia.org/wiki/Narcissistic_number
577
+ // and bases converted to decimal
578
+ NarcNumsBase2: array [1 ..2 ] of Integer = (0 , 1 );
579
+ NarcNumsBase3: array [1 ..6 ] of Integer = (0 , 1 , 2 , 5 , 8 , 17 );
580
+ NarcNumsBase4: array [1 ..12 ] of Integer = (
581
+ 0 , 1 , 2 , 3 , 28 , 29 , 35 , 43 , 55 , 62 , 83 , 243
582
+ );
583
+ NarcNumsBase5: array [1 ..16 ] of Integer = (
584
+ 0 , 1 , 2 , 3 , 4 , 13 , 18 , 28 , 118 , 289 , 353 , 419 , 4890 , 4891 , 9113 , 1874374
585
+ );
586
+ NarcNumsBase6: array [1 ..18 ] of Integer = (
587
+ 0 , 1 , 2 , 3 , 4 , 5 , 99 , 190 , 2292 , 2293 , 2324 , 3432 , 3433 , 6197 , 36140 ,
588
+ 269458 , 391907 , 10067135
589
+ );
590
+ NarcNumsBase7: array [1 ..28 ] of Integer = (
591
+ 0 , 1 , 2 , 3 , 4 , 5 , 6 , 10 , 25 , 32 , 45 , 133 , 134 , 152 , 250 , 3190 , 3222 , 3612 ,
592
+ 3613 , 4183 , 9286 , 35411 , 191334 , 193393 , 376889 , 535069 , 794376 , 8094840
593
+ );
594
+ NarcNumsBase8: array [1 ..23 ] of Integer = (
595
+ 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 20 , 52 , 92 , 133 , 307 , 432 , 433 , 16819 , 17864 , 17865 ,
596
+ 24583 , 25639 , 212419 , 906298 , 906426
597
+ );
598
+ NarcNumsBase13: array [1 ..26 ] of Integer = (
599
+ 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 , 11 , 12 , 17 , 45 , 85 , 98 , 136 , 160 , 793 ,
600
+ 794 , 854 , 1968 , 8194 , 62481 , 167544
601
+ );
602
+ NarcNumsBase16: array [1 ..51 ] of Integer = (
603
+ $0 , $1 , $2 , $3 , $4 , $5 , $6 , $7 , $8 , $9 , $A, $B, $C, $D, $E, $F, $156 , $173 ,
604
+ $208 , $248 , $285 , $4A5, $5B0, $5B1, $60B, $64B, $8C0, $8C1, $99A, $AA9,
605
+ $AC3, $CA8, $E69, $EA0, $EA1, $B8D2, $13579 , $2B702, $2B722, $5A07C, $5A47C,
606
+ $C00E0, $C00E1, $C04E0, $C04E1, $C60E7, $C64E7, $C80E0, $C80E1, $C84E0,
607
+ $C84E1
608
+ );
609
+ var
610
+ X: Integer;
611
+ Base: Byte;
612
+ begin
613
+ // Base 2
614
+ for X in NarcNumsBase2 do
615
+ CheckTrue(IsNarcissistic(X, 2 ), Format(' %d base 2' , [X]));
616
+ // Base 3
617
+ for X in NarcNumsBase3 do
618
+ CheckTrue(IsNarcissistic(X, 3 ), Format(' %d base 3' , [X]));
619
+ // Base 4
620
+ for X in NarcNumsBase4 do
621
+ CheckTrue(IsNarcissistic(X, 4 ), Format(' %d base 4' , [X]));
622
+ // Base 5
623
+ for X in NarcNumsBase5 do
624
+ CheckTrue(IsNarcissistic(X, 5 ), Format(' %d base 5' , [X]));
625
+ // Base 6
626
+ for X in NarcNumsBase6 do
627
+ CheckTrue(IsNarcissistic(X, 6 ), Format(' %d base 6' , [X]));
628
+ // Base 7
629
+ for X in NarcNumsBase7 do
630
+ CheckTrue(IsNarcissistic(X, 7 ), Format(' %d base 7' , [X]));
631
+ // Base 8
632
+ for X in NarcNumsBase8 do
633
+ CheckTrue(IsNarcissistic(X, 8 ), Format(' %d base 8' , [X]));
634
+ // Base 10
635
+ for X in NarcNumsBase10 do
636
+ // uses default base
637
+ CheckTrue(IsNarcissistic(X), Format(' %d base 10' , [X]));
638
+ // Base 13
639
+ for X in NarcNumsBase13 do
640
+ CheckTrue(IsNarcissistic(X, 13 ), Format(' %d base 13' , [X]));
641
+ // Base 16
642
+ for X in NarcNumsBase16 do
643
+ CheckTrue(IsNarcissistic(X, 16 ), Format(' %d base 16' , [X]));
644
+ // Check some known falsities
645
+ CheckFalse(IsNarcissistic($C04E2, 16 ), ' False #1' );
646
+ CheckFalse(IsNarcissistic(906299 , 8 ), ' False #2' );
647
+ CheckFalse(IsNarcissistic(501 ), ' False #3' );
648
+ CheckFalse(IsNarcissistic(2 , 2 ), ' False #4' );
649
+ // Bases 2..255: All single digits in the base are narcissistic
650
+ for Base := 2 to 255 do
651
+ for X := 0 to Base - 1 do
652
+ CheckTrue(IsNarcissistic(X, Base), Format(' Single digit%d base: %d' , [X, Base]));
653
+ end ;
654
+
655
+ procedure TestMathsCatSnippets.TestIsPalindromic ;
656
+ const
657
+ // All palindromic numbers base 10 less than 200
658
+ // Source: https://oeis.org/A002113
659
+ PalBase10LessThan256: set of Byte = [
660
+ 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 11 , 22 , 33 , 44 , 55 , 66 , 77 , 88 , 99 , 101 , 111 ,
661
+ 121 , 131 , 141 , 151 , 161 , 171 , 181 , 191 , 202 , 212 , 222 , 232 , 242 , 252
662
+ ];
663
+ // All palindromic numbers base 2 less than 200 decimal
664
+ // Source: https://oeis.org/A006995
665
+ PalBase2LessThan256: set of Byte = [
666
+ 0 , 1 , 3 , 5 , 7 , 9 , 15 , 17 , 21 , 27 , 31 , 33 , 45 , 51 , 63 , 65 , 73 , 85 , 93 , 99 ,
667
+ 107 , 119 , 127 , 129 , 153 , 165 , 189 , 195 , 219 , 231 , 255
668
+ ];
669
+ // Bases for which 105 decimal is palindromic
670
+ // Source: https://en.wikipedia.org/wiki/Palindromic_number#Other_bases
671
+ Pal105Bases: set of Byte = [4 , 8 , 14 , 20 , 34 , 104 ];
672
+ var
673
+ X, B: Byte;
674
+ begin
675
+ CheckTrue(IsPalindromic(243999 , 8 ), ' 734437 octal' );
676
+ CheckTrue(IsPalindromic(30495 , 8 ), ' 73437 octal' );
677
+ CheckFalse(IsPalindromic(30943 , 8 ), ' 74337 octal' );
678
+ CheckTrue(IsPalindromic($FFFFFFFF, 16 ), ' FFFFFFFF hex' );
679
+ CheckTrue(IsPalindromic($FFFFFFFF, 2 ), ' 11111111111111111111111111111111 bin' );
680
+ CheckTrue(IsPalindromic($FFF11FFF, 16 ), ' FFF11FFF hex' );
681
+ CheckFalse(IsPalindromic($FFF11FFF, 2 ), ' 11111111111100010001111111111111 bin' );
682
+ CheckTrue(IsPalindromic(341 , 2 ), ' 101010101 bin' );
683
+ CheckTrue(IsPalindromic(2081023 , 128 ), ' 127|1|127 base 128' );
684
+ CheckFalse(IsPalindromic(2081024 , 128 ), ' 127|2|0 base 128' );
685
+ CheckTrue(IsPalindromic(145787541 ), ' 145787541 base 10 (default)' );
686
+ CheckTrue(IsPalindromic(1 , 25 ), ' 1 base 25' );
687
+ CheckFalse(IsPalindromic(66 , 4 ), ' 1002 base 4' );
688
+ CheckTrue(IsPalindromic(66 , 21 ), ' 33 base 21' );
689
+ for B in Pal105Bases do
690
+ CheckTrue(IsPalindromic(105 , B), Format(' 105 in base %d' , [B]));
691
+ for X := 0 to 255 do
692
+ begin
693
+ if X in PalBase10LessThan256 then
694
+ CheckTrue(IsPalindromic(X), Format(' %d in base 10' , [X]))
695
+ else
696
+ CheckFalse(IsPalindromic(X), Format(' %d in base 10' , [X]));
697
+ if X in PalBase2LessThan256 then
698
+ CheckTrue(IsPalindromic(X, 2 ), Format(' %d in base 2' , [X]))
699
+ else
700
+ CheckFalse(IsPalindromic(X, 2 ), Format(' %d in base 2' , [X]));
701
+ end ;
702
+ end ;
703
+
567
704
procedure TestMathsCatSnippets.TestIsPrime ;
568
705
var
569
706
AllValues: array [1 ..542 ] of Boolean;
0 commit comments