using System;
using System.Collections.Generic;
using System.Text;
namespace Bitpruegler.Classes.Maths
{
/// <summary>
/// Diese Klasse liefert Methoden, um Zahlen darauf zu überprüfen, ob sie
/// narzisstische Zahlen sind.
/// Narzisstische Zahlen sind solche Zahlen, die durch bestimmte Rechenvorschriften
/// sich selbst erzeugen können.
/// </summary>
public static class NarcissticNumbers
{
/// <summary>
/// Ermittelt die Länge einer Zahl (also die Anzahl der Ziffern)
/// </summary>
/// <param name="number">Die zu prüfende Zahl</param>
/// <returns>Die Länge der Zahl</returns>
private static int GetLength(long number)
{
int n = 0;
while (number > 0) { n++; number /= 10; }
return n;
} //private static int GetLength(long)
/// <summary>
/// Prüft die eingegebene Zahl darauf, ob sie eine Pluperfect digital invariant-Zahl ist.
/// Solche Zahlen heißen auch Armstrong-Zahlen.
/// PPDIs haben die Eigenschaft, dass sie sich selbst bilden, wenn man jede ihrer Ziffern
/// mit der Länge der Zahl (Anzahl der Ziffern) potenziert und die Ergebnisse summiert.
///
/// 153 ist eine solche Zahl, da:
/// 1^3 + 5^3 + 3^3 = 1 + 125 + 27 = 153 ist.
/// </summary>
/// <param name="number">Die zu prüfende Zahl</param>
/// <returns>True wenn die Zahl PPDI ist, sonst false</returns>
public static bool IsNarcissticPPDI(long number)
{
long temp = 0;
//Zahl zwischenspeichern
long buffer = number;
//Anzahl der Ziffern ermitteln
int n = GetLength(number);
while (number > 0)
{
//Eine Stelle extrahieren
long digit = number % 10;
//Zahl reduzieren
number /= 10;
//Mit der Länge der Zahl potenzieren und summieren
temp += Convert.ToInt64(Math.Pow(digit, n));
} //while
//Wenn buffer gleich temp ist, ist number eine PPDI
return buffer == temp;
} //public static bool IsNarcissticPPDI(long)
/// <summary>
/// Prüft die eingegebene Zahl darauf, ob sie eine narzisstische Zahl mit steigender
/// Pozenz ist.
/// Eine solche Zahl bildet sich selbst, wenn man die Stellen der Zahl mit einer stetig
/// steigenden Zahl, beginnend bei 1, potenziert und die Ergebnisse summiert.
///
/// 2427 ist eine solche Zahl, da
///
/// 2427 = 2^1 + 4^2 + 2^3 + 7^4 = 2 + 16 + 8 + 2401 = 2427 ist.
///
/// </summary>
/// <param name="number">Die zu prüfende Zahl</param>
/// <returns>True, wenn die eingegebene Zahl eine narzisstische
/// Zahl mit steigender Potenz ist, sonst false</returns>
public static bool IsNarcissticIncreasing(long number)
{
long temp = 0;
//Zahl zwischenspeichern
long buffer = number;
//Anzahl der Ziffern ermitteln
int n = GetLength(number);
while (number > 0)
{
//Eine Stelle extrahieren
long digit = number % 10;
//Zahl reduzieren
number /= 10;
//Mit der Länge potenzieren
temp += Convert.ToInt64(Math.Pow(digit, n));
//Länge dekrementieren
n--;
} //while
//Wenn buffer gleich temp ist, ist number eine narzisstische Zahl
return buffer == temp;
} //public static bool IsNarcissticIncreasing(long)
/// <summary>
/// Prüft die eingegebene Zahl darauf, ob sie eine narzisstische Zahl mit konstanter Basis ist.
/// Solche Zahlen sind Zahlen, die sich selbst bilden, wenn man als Basis die Anzahl der Ziffern
/// der Zahl nutzt und diese Basis mit den Ziffern potenziert und das Ergebnis aufsummiert.
///
/// 4624 ist eine solche Zahl, da
///
/// 4624 = 4^4 + 4^6 + 4^2 + 4^4 = 256 + 4096 + 16 + 256 = 4624
/// ist.
///
/// </summary>
/// <param name="number">Die zu prüfende Zahl</param>
/// <returns>True, wenn die eingegebene Zahl eine narzisstische Zahl mit
/// konstanter Basis ist, sonst false</returns>
public static bool IsNarcissticConstBase(long number)
{
long temp = 0;
//Zahl merken
long buffer = number;
//Anzahl der Ziffern als Basis ermitteln
int basis = GetLength(number);
while(number > 0)
{
//Eine Stelle extrahieren
long digit = number % 10;
//Zahl reduzieren
number /= 10;
//Basis mit der Stelle potenzieren und aufsummieren
temp += Convert.ToInt64(Math.Pow(basis, digit));
} //while
//Wenn buffer gleich temp ist, ist number eine narzisstische Zahl mit konstanter Basis
return buffer == temp;
} //public static bool IsNarcissticConstBase(long)
} //public static class NarcissticNumbers
} //namespace Bitpruegler.Classes.Maths
Verwendung:
/// <summary>
/// Prüft verschiedene Zahlen auf die Eigenschaft "narzisstische Zahl"
/// </summary>
static void TestNumbers()
{
long ppdi = 146511208;
long increasing = 2427;
long constBase = 4624;
Console.WriteLine("{0:N0} ist eine PPDI: {1}", ppdi, NarcissticNumbers.IsNarcissticPPDI(ppdi));
Console.WriteLine("{0:N0} ist eine narz. Zahl mit steigender Potenz: {1}", ppdi, NarcissticNumbers.IsNarcissticIncreasing(ppdi));
Console.WriteLine("{0:N0} ist eine narz. Zahl mit konstanter Basis: {1}\n", ppdi, NarcissticNumbers.IsNarcissticConstBase(ppdi));
Console.WriteLine("{0:N0} ist eine PPDI: {1}", increasing, NarcissticNumbers.IsNarcissticPPDI(increasing));
Console.WriteLine("{0:N0} ist eine narz. Zahl mit steigender Potenz: {1}", increasing, NarcissticNumbers.IsNarcissticIncreasing(increasing));
Console.WriteLine("{0:N0} ist eine narz. Zahl mit konstanter Basis: {1}\n", increasing, NarcissticNumbers.IsNarcissticConstBase(increasing));
Console.WriteLine("{0:N0} ist eine PPDI: {1}", constBase, NarcissticNumbers.IsNarcissticPPDI(constBase));
Console.WriteLine("{0:N0} ist eine narz. Zahl mit steigender Potenz: {1}", constBase, NarcissticNumbers.IsNarcissticIncreasing(constBase));
Console.WriteLine("{0:N0} ist eine narz. Zahl mit konstanter Basis: {1}\n", constBase, NarcissticNumbers.IsNarcissticConstBase(constBase));
} //static void TestNumbers()