C# :: Aufgabe #165

4 Lösungen Lösungen öffentlich

Existiert die Kaprekar-Konstante?

Anfänger - C# von hollst - 23.02.2017 um 13:29 Uhr
Man weise numerisch nach, ob die Behauptung des indischen Mathematikers Kaprekar richtig ist.

Kaprekar hat folgendes behauptet (1949):

1.) Man nehme eine vierstellige Dezimalzahl D, wobei nicht alle vier Stellen identisch sein dürfen
(also 1111, 2222 etc. sind nicht erlaubt, aber z. B. 0001 ist erlaubt).
2.) D überführe man in zwei Zahle D1 und D2, indem bei D1 die Digits in absteigender und bei D2 in aufsteigender Reihenfolge
angeordnet werden (also z. B. D = 1724 -> D1 = 7421 und D2 = 1247; oder D = 1 -> D1 = 1000 und D2 = 1).
3.) Man subtrahiere nun D2 von D1; mit dem Ergebnis (Dneu = D1 - D2) wiederhole man Pkt. 2 durch Ersetzen von D durch Dneu solange,
bis sich nichts mehr ändert.

Die unglaubliche Behauptung ist, dass bei diesem Algorithmus stets das gleiche Ergebnis herauskommt (die sogenannte Kaprekar-Konstante),
egal, mit welchem D man beginnt.

Frage: Wie lautet die Kaprekar-Konstante?

Lösungen:

vote_ok
von Mexx (2370 Punkte) - 24.02.2017 um 18:09 Uhr
Quellcode ausblenden C#-Code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace A165_KaprekarKonstante
{
    class Program
    {
        static void Main(string[] args)
        {
            string input = string.Empty;
            int zahl;
            do
            {
                Console.WriteLine("Geben Sie eine beliebige vierstellige Zahl ein, welche keine Schnapszahl ist!\n" + 
                    "Mit exit schließen Sie das Programm");
                input = Console.ReadLine();

                //Eingabe Prüfen
                if (input.Length != 4 || !int.TryParse(input, out zahl))
                {
                    Console.WriteLine("Fehlerhafte Eingabe! Versuchen Sie es erneut\n\n");
                    continue;
                }

                //Kaprekarkonstante errechnen
                int kaprekarKonstante = KaprekarKonstanteErmitteln(zahl);
                string output;

                if (kaprekarKonstante == 0)
                    output = "\nDas Ergebnis der berechnung ist 0... Haben Sie eine Schnapszahl eingegeben?!\n\n";
                else
                    output = string.Format("\nDie Kaprekar-Konstane lautet: {0}\n\n", kaprekarKonstante);
                Console.WriteLine(output);

            } while (input != "exit");
        }

        /// <summary>
        /// Hilfsvariable für die Funktion KaprekarKonstanteErmitteln
        /// </summary>
        static int memory = 0;

        /// <summary>
        /// Ermittelt die Kaprekar-Konstante für die übergebene vierstellige Zahl
        /// </summary>
        /// <param name="zahl">Zahl für die die Kaprekarkonstante ermittelt werden soll</param>
        /// <returns>Die Kaprekar-Konstante oder Null, falls eine Schnapszahl eingegeben wurde</returns>
        private static int KaprekarKonstanteErmitteln(int zahl)
        {
            //Zahl zurückgeben, falls sich durch die letzte Berechnung keine Änderung ergeben hat
            if (zahl == memory)
                return zahl;

            #region Größte Zahl bilden
            //Zahl als Byte-Liste mit den binären Werten des Zeichens speichern
            List<byte> digits = ASCIIEncoding.UTF8.GetBytes(zahl.ToString()).ToList();
            string d1 = string.Empty;

            //Liste digits mit Nullen füllen, falls Zahl weniger als vier Stellen hat
            while (digits.Count < 4)
                digits.Add(ASCIIEncoding.UTF8.GetBytes("0")[0]);

            //Größtmögliche Zahl bilden
            while (digits.Count > 0)
            {
                //Zeichen mit dem aktuell größten Wert ermitteln und an d1 anhängen
                d1 += ASCIIEncoding.UTF8.GetString(new byte[] { digits.Max() });

                //Zuletzt ermitteltes Zeichen aus der Liste löschen
                byte currentDigit = digits.Max();
                for (int i = 0; i < digits.Count; i++)
                {
                    if (digits[i] == currentDigit)
                    {
                        digits.RemoveAt(i);
                        break;
                    }
                }
            }
            #endregion

            #region Kleinste Zahl bilden
            //Zahl als Byte-Liste mit den binären Werten des Zeichens speichern
            digits = ASCIIEncoding.UTF8.GetBytes(zahl.ToString()).ToList();
            string d2 = string.Empty;

            //Liste digits mit Nullen füllen, falls Zahl weniger als vier Stellen hat
            while (digits.Count < 4)
                digits.Add(ASCIIEncoding.UTF8.GetBytes("0")[0]);

            //Kleinstmögliche Zahl bilden
            while (digits.Count > 0)
            {
                //Zeichen mit dem aktuell kleinsten Wert ermitteln und an d2 anhängen
                d2 += ASCIIEncoding.UTF8.GetString(new byte[] { digits.Min() });

                //Zuletzt ermitteltes Zeichen aus der Liste löschen
                byte currentDigit = digits.Min();
                for (int i = 0; i < digits.Count; i++)
                {
                    if (digits[i] == currentDigit)
                    {
                        digits.RemoveAt(i);
                        break;
                    }
                }
            }
            #endregion

            //Berechnen
            int iD1 = int.Parse(d1);
            int iD2 = int.Parse(d2);
            int iNeu = iD1 - iD2;

            //Zuletzt berechnete Zahl zwischenspeichern und Funktion mit dieser erneut aufrufen
            memory = zahl;
            KaprekarKonstanteErmitteln(iNeu);

            //Errechnete Kaprekar-Konstante zurückgeben
            return memory;
        }
    }
}
vote_ok
von hollst (13980 Punkte) - 26.02.2017 um 15:05 Uhr
Quellcode ausblenden C#-Code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Globalization;

namespace kaprekar  {
    class Program    {
        static void Main()        {
            String LZ = " ";
            ulong digits = 4;
            String input = String.Empty;
            List<ulong> constanten = new List<ulong>();
            double BASIS = 10; 
            ulong imax = (ulong)Math.Pow(BASIS, digits);

            ((imax - 1).ToString("n0") + LZ + ulong.MaxValue.ToString("n0")).Message();

            for (ulong i = 1; i < imax; i++)            {                
                input = i.ToString();               
                String sD1 = input.Sort(true, digits);
                String sD2 = input.Sort(false, digits);
                NumberStyles style = NumberStyles.Integer;
                ulong D, D1, D2;
                List<ulong> LD = new List<ulong>();
                int circle = 0;
                int steps = 0;
                while (true)                {               
                    D1 = ulong.Parse(sD1, style);
                    D2 = ulong.Parse(sD2, style);    
                    D = D1 - D2;
                    if (LD.Contains(D))                    {
                        circle = LD.Count - LD.IndexOf(D);
                        if (circle == 1)                        {
                            if (!constanten.Contains(D))                            {
                                ("add " + D.ToString("n0") + LZ + D.ToString("X") + 
                                    "  steps: " + steps.ToString()).Message();
                                constanten.Add(D);
                            }                            
                        }
                        break;
                    }
                    else
                        if (D != 0)
                            LD.Add(D);
                        else
                            break;
                    String sD = D.ToString();
                    sD1 = sD.Sort(true, digits);
                    sD2 = sD.Sort(false, digits);
                    steps++;
                };
            }
            "Kaprekar-Konstanten:".Message();
            for(var i = 0; i < constanten.Count; i++)
                (constanten[i].ToString("n0") + LZ + constanten[i].ToString("X")).Message();
            "ready".EndMessage();
        }
    }

    public static class MyKaprekar    {
        public static string Sort(this string s, Boolean bo_downward, ulong digits)        {
            while ((ulong)s.Length < digits)
                s = "0" + s;
            String result = string.Empty;
            Char[] c = s.ToCharArray();
            Array.Sort(c);
            for (var i = 0; i < c.Length; i++)
                if (!bo_downward)
                    result += c[i].ToString();
                else
                    result += c[c.Length - 1 - i].ToString();           
            return result;            
        }

        public static void Message(this string s)        {
            Console.WriteLine(s);
        }

        public static void EndMessage(this string s)        {
            s.Message(); Console.ReadKey();
        }
    }
}
vote_ok
von Umfegumfe (50 Punkte) - 27.02.2017 um 09:44 Uhr
Quellcode ausblenden C#-Code
namespace Kaprekar
{
    class Program
    {
        static void Main(string[] args)
        {
            int d = GetKaprekarStart();
            int kaprekar = GetKaprekarNumber(d);
            Console.WriteLine("Die vierstellige Kaprekar-Zahl lautet {0}!", kaprekar);
            Console.WriteLine("Bitte Taste drücken!");
            Console.ReadKey();
        }

        static int GetKaprekarNumber(int startNumber)
        {
            int[] digits = NumberToFourDigitArray(startNumber);
            int[] sortedDigits = sortedFourDigitArray(digits);
            int[] sortedDigitsInverted = invertDigitArray(digits);
            int d1 = digitArrayToInt(sortedDigitsInverted);
            int d2 = digitArrayToInt(sortedDigits);
            int d = d1 - d2;
            Console.WriteLine("Zwischenschritt: d={0}, d1={1}, d2={2}, d1-d2={3}...", startNumber, d1, d2, d);
            if (d == startNumber) return d;
            return GetKaprekarNumber(d);
        }

        static int GetKaprekarStart()
        {
            while (true)
            {
                Console.Write("Bitte vierstellige Startzahl eingeben: ");
                string s = Console.ReadLine();
                int number = Convert.ToInt32(s);
                if (number > 0 && number < 10000)
                {
                    if (IsNumberValidForKaprekar(number)) return number;
                }
                Console.WriteLine("Keine gültige Startzahl, bitte wiederholen!");
            }
        }

        static bool IsNumberValidForKaprekar(int number)
        {
            int[] kaprekarDigits = NumberToFourDigitArray(number);
            int start = kaprekarDigits[0];
            for (int i = 1; i < kaprekarDigits.Length; i++)
            {
                if (kaprekarDigits[i] != start) return true;
            }
            return false;
        }

        static int[] NumberToFourDigitArray(int number)
        {
            int[] retVal = new int[4];
            for (int i = 0; i < 4; i++)
            {
                retVal[i] = number % 10;
                number = number / 10;
            }
            return retVal;
        }

        static int[] sortedFourDigitArray(int[] digits)
        {
            bool sorted;
            do
            {
                sorted = true;
                for (int i = 0; i < digits.Length - 1; i++)
                {
                    if (digits[i] > digits[i + 1])
                    {
                        int temp = digits[i];
                        digits[i] = digits[i + 1];
                        digits[i + 1] = temp;
                        sorted = false;
                    }
                }
            } while (!sorted);
            return digits;
        }

        static int[] invertDigitArray(int[] digits)
        {
            int[] retVal = new int[digits.Length];
            for (int i = 0; i < digits.Length; i++)
            {
                retVal[i] = digits[digits.Length - i - 1];
            }
            return retVal;
        }

        static int digitArrayToInt(int[] digits)
        {
            int retVal = 0;
            int multiplier = 1;
            int[] invertedDigits = invertDigitArray(digits);
            for (int i = 0; i < invertedDigits.Length; i++)
            {
                retVal = retVal + invertedDigits[i] * multiplier;
                multiplier = multiplier * 10;
            }
            return retVal;
        }
    }
}
vote_ok
von golileo (20 Punkte) - 04.05.2017 um 15:20 Uhr
Quellcode ausblenden C#-Code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace KapKon
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Geben Sie eine vierstellige Zahl ein, welche nicht vier identische Stellen hat\n" +
                   "Mit exit schließen Sie das Programm");
            String d = Console.ReadLine();
            int number;
            while((d.Length != 4 || !(int.TryParse(d, out number)) || (d.Distinct().Count() == 1))||d == "exit")
            {
                
                if (d == "exit")
                {
                    System.Environment.Exit(1);
                }
                else
                {
                    Console.WriteLine("Fehlerhafte Eingabe! Versuchen Sie es erneut\n\n");
                    d = Console.ReadLine();
                }
            }
            String dnew = "";
            dnew = doWork(d);
            while (dnew.CompareTo(d) != 0)
            {
                d = "" + dnew;
                dnew = doWork(dnew);
                //Console.WriteLine(check);
            }
            Console.WriteLine("Die Kaprekar-Zahl lautet {0}.", d);
            Console.ReadKey();
        }

        public static String doWork(String _d)
        {
            String d1 = descOrder(_d);
            String d2 = ascOrder(_d);
            String _dnew = SubstractStrings(d2.PadLeft(4,'0'),d1.PadRight(4,'0'));
            Console.WriteLine(d1 + " - " + d2 + "="+_dnew);
            return _dnew;
        }

        public static String SubstractStrings(String _d1, String _d2)
        {
            String dnew = ""+((Int32.Parse(_d2)) -(Int32.Parse(_d1)));
            return dnew; 
        }
       
         public static String descOrder(String _d)
        {
            Char[] splittedString = new Char[4];
            splittedString = _d.ToCharArray();
            if (_d.Distinct().Count() != 1)
            {
                Array.Sort<Char>(splittedString);
                Array.Reverse(splittedString);
            }
            String reverseD = new String(splittedString);
            return reverseD;
        }

        public static String ascOrder(String _d)
        {
            Char[] splittedString = new Char[4];
            splittedString = _d.ToCharArray();
            Array.Sort(splittedString);
            String ascD = new String(splittedString);
            return ascD;
        }
    }
}
1810822

Du scheinst einen AdBlocker zu nutzen. Ich würde mich freuen, wenn du ihn auf dieser Seite deaktivierst und dich davon überzeugst, dass die Werbung hier nicht störend ist.