delphidabbler / code-snippets

Collections of reusable code snippets, mainly in Pascal.
MIT License
27 stars 2 forks source link

Add function to test for narcissistic numbers to csdb #18

Open delphidabbler opened 1 year ago

delphidabbler commented 1 year ago

Following definition of narcissistic numbers (of any base > 1) from Wikipedia:

Screenshot_20230721-074955_Chrome

delphidabbler commented 1 year ago
function IsNarcissistic(const N: Cardinal; const B: Byte): Boolean;
begin
  if N < B then
    Exit(True); // trivial narcissistic numbers
  // number of digits in N 
  var K: Cardinal := Math.Floor(Math.LogN(B, N)) + 1;
  var Sum: Cardinal := 0;
  var BToPowerI := 1; // B to power I in 0..K-1
  for var I := 0 to K - 1 do
  begin
    var BToPowerIPlus1 := BToPowerI * B; // B to power I+1
    // calculate Ith digit
    var D := ((N mod BToPowerIPlus1) - (N mod BToPowerI)) div BToPowerI;
    // add D to power K to sum
    Inc(Sum, PowNZN(D, K));
    BToPowerI := BToPowerIPlus1;
  end;
  Result := N = Sum;
end;
delphidabbler commented 1 year ago

If we use DigitPowerSum from issue #17 we can reduce the function to:

function IsNarcissistic(const N: Cardinal; const B: Byte): Boolean;
begin
  if N < B then
    Exit(True); // trivial narcissistic numbers
  // number of digits in N 
  var K: Cardinal := Math.Floor(Math.LogN(B, N)) + 1;
  var Sum := DigitPowerSum(N, B, K);
  Result := N = Sum;
end;

The downside of this shortened version is that K gets calculated twice, once in DigitPowerSum and again in the above function.