C# :: Aufgabe #232

6 Lösungen Lösungen öffentlich

Teufelskreis einer selbstbezüglichen Aussage

Anfänger - C# von hollst - 17.12.2018 um 18:46 Uhr
Die folgende Aussage sei gegeben als String:

"Dieser Satz hat vierzig Buchstaben sowie einen Punkt."


Die Aussage ist natürlich falsch, denn der Satz hat tatsächlich fünfundvierzig Buchstaben.

Ersetzen wir nun in der Aussage das Wort "vierzig" durch "fünfundvierzig" bleibt die Aussage aber trotzdem falsch,

denn der neue Satz hat zweiundfünfzig Buchstaben. Schöner Teufelskreis, oder?


Schreibe ein Programm mit dem überprüft wird, ob es überhaupt eine (ausgeschriebene) Zahl gibt, die oben zu einer wahren Aussage führt.

Viel Spaß!

Lösungen:

3 Kommentare
vote_ok
von Exception (3770 Punkte) - 23.12.2018 um 10:29 Uhr
- Es wurden die Werte 1 ... 100 geprüft, siehe Anlage "numbers.txt".
- An gültigen Sätzen gibt es exakt einen: 53.

Quellcode ausblenden C#-Code
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;

namespace Teufelskreis_232
{
    class Program
    {
        private static string Sentence;
        private static Dictionary<int, string> Numbers;


        static void Main(string[] args)
        {
            try
            {
                Program.Sentence = "Dieser Satz hat # Buchstaben sowie einen Punkt.";
                Program.Numbers = new Dictionary<int, string>();

                Program.getMapping(args[0]);
                List<string> validSentences = Program.validateSentences();
                Program.printResults(validSentences);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }

            Console.ReadLine();
        }

        /// <summary>
        /// Gibt das Ergebnis / die Ergebnisse aus.
        /// </summary>
        /// <param name="validSentences">Liste aller gültigen Sätze</param>
        private static void printResults(List<string> validSentences)
        {
            if (validSentences.Count > 0)
            {
                Console.WriteLine("Es wurden {0} gültige Sätze gefunden.", validSentences.Count);

                foreach (string sentence in validSentences)
                {
                    Console.WriteLine();
                    Console.Write("\"");
                    Console.Write(sentence);
                    Console.Write("\"");
                }
            }
            else
            {
                Console.WriteLine("Es wurden keine gültige Sätze gefunden!");
            }
        }

        /// <summary>
        /// Prüft die Gültigkeit mit den einzelnen Werten.
        /// ACHTUNG:
        /// - Auch wenn die Reihenfolge von Satz + Zahl im Bezug auf die Länge egal ist, so wird hier noch eine Ersetzung vorgenommen, 
        ///   damit die Ausgabe später schön ist.
        /// </summary>
        /// <returns>Die gültigen Sätze</returns>
        private static List<string> validateSentences()
        {
            List<string> validSentences = new List<string>();

            foreach (KeyValuePair<int, string> number in Program.Numbers)
            {
                string sentence = Program.replacePlaceholder(number.Value, Program.Sentence);
                string temp = sentence.Replace(" ", ""); // Leerzeichen werden gelöscht, da nur Buchstaben und der Punkt am Ende relevant sind.

                int expectedCharacters = number.Key; 
                int realCharacters = temp.Length;

                if(expectedCharacters == realCharacters)
                {
                    validSentences.Add(sentence);
                }
            }

            return validSentences;
        }

        /// <summary>
        /// Ersetzt in text placeholder durch value.
        /// Hierbei ist zu beachten, dass _alle_ placeholder durch value ersetzt werden.
        /// 
        /// Sollte es benötigt werden, so kann die Funktion erweitert werden, sodass zwei Listen übergeben werden,
        /// somit können mehrere _verschiedene_ Platzhalter gehandelt werden.
        /// Aber für die aktuelle Aufgabe reicht das so ;)
        /// </summary>
        /// <param name="value">Der Wert der in Platzhalter eingesetzt wird.</param>
        /// <param name="text">Der Text indem das Platzhalterzeichen vorhanden ist.</param>
        /// <param name="placeholder">Das Platzhalterzeichen</param>
        /// <returns></returns>
        private static string replacePlaceholder(string value, string text, string placeholder = "#")
        {
            return text.Replace(placeholder, value);
        }

        /// <summary>
        /// Lädt das "ZahlenWert;AusgeschriebeneZahl"-Mapping aus übergebenem Dateipfad (CSV) in ein Dictionary.
        /// </summary>
        /// <param name="filePath">Der Dateipfad</param>
        private static void getMapping(string filePath)
        {
            if(!File.Exists(filePath))
            {
                throw new FileNotFoundException("Datei wurde nicht unter \"" + filePath + "\" gefunden.");
            }

            using (FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read))
            {
                using (StreamReader sr = new StreamReader(fs, Encoding.Default))
                {
                    while(sr.Peek() >= 0)
                    {
                        string[] numberParts = sr.ReadLine().Split(';');
                        Program.Numbers.Add(Convert.ToInt32(numberParts[0]), numberParts[1]);
                    }
                }
            }
        }
    }
}
vote_ok
von AchtungHuPe (120 Punkte) - 03.01.2019 um 11:36 Uhr
Quellcode ausblenden C#-Code
using System;

namespace SentenceLength
{
    class Program
    {
        static void Main(string[] args)
        {
            int minStringLength = "Dieser Satz hat  Buchstaben sowie einen Punkt".Replace(" ", string.Empty).Length;

            string[] decadeList = { "vierzig", "fünfzig", "sechzig", "siebzig", "achtzig", "neunzig" };
            string[] unitPositionList = { "einund", "zweiund", "dreiund", "vierund", "fünfund", "sechsund", "siebenund", "achtund", "neunund" };

            int i = 40;
            foreach (string decade in decadeList)
            {
                if ( i == minStringLength + decade.Length)
                    Console.WriteLine("Dieser Satz hat {0} ({1}) Buchstaben sowie einen Punkt", decade, minStringLength + decade.Length);

                int j = 1;
                foreach (string unit in unitPositionList)
                {
                    int numberStringLength = unit.Length + decade.Length;
                    int curStringLength = minStringLength + numberStringLength;

                    if (i + j == minStringLength + numberStringLength)
                        Console.WriteLine("Dieser Satz hat {0}{1} ({2}) Buchstaben sowie einen Punkt", unit, decade, minStringLength + numberStringLength);
                    j = j + 1;
                }
                i = i + 10;       
            }

            Console.ReadKey();
        }
    }
}
vote_ok
von Meinezukunft (60 Punkte) - 25.01.2019 um 13:17 Uhr
Quellcode ausblenden C#-Code
String eingabe;
 
            int anzahlA = 0;
            int anzahlE = 0;
            int anzahlI = 0;
            int anzahlO = 0;
            int anzahlU = 0;
 
            Console.WriteLine("Geben Sie einen Satz ein:");
            eingabe = Console.ReadLine();
 
 
            //Jedes Zeichen des Satzes einzeln in einem Array speichern.
            Char[] zeichen = eingabe.ToLower().ToCharArray(); //ToLower() -> auch Großbuchstaben sollen beachtet werden.
 
            //Jedes Zeichen durchgehen und prüfen ob ein Vokal vorliegt.
            for(int i = 0; i<zeichen.Length; i++)
            {
                char aktuellesZeichen = zeichen[i];
 
                if (aktuellesZeichen == 'a') anzahlA++;
                else if (aktuellesZeichen == 'e') anzahlE++;
                else if (aktuellesZeichen == 'i') anzahlI++;
                else if (aktuellesZeichen == 'o') anzahlO++;
                else if (aktuellesZeichen == 'u') anzahlU++;
            }
 
            Console.WriteLine("Vokale : " + (anzahlA + anzahlE + anzahlI + anzahlO + anzahlU));
            Console.WriteLine("A: " + anzahlA);
            Console.WriteLine("E: " + anzahlE);
            Console.WriteLine("I: " + anzahlI);
            Console.WriteLine("O: " + anzahlO);
            Console.WriteLine("U: " + anzahlU);
 
            Console.ReadLine();
vote_ok
von Meinezukunft (60 Punkte) - 25.01.2019 um 13:54 Uhr
Quellcode ausblenden C#-Code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Satzüberprüfung
{
    class Program
    {
        static void Main(string[] args)
        {
            string zusammen = "Dieser Satz hat neunhundertneunundneunzig Buchstaben sowie einen Punkt.";
            Console.WriteLine(zusammen);
            string zusammen2 = "";
            while (true)
            {
                zusammen2 = zusammen.Replace(" ", String.Empty);
                int länge = (zusammen2.Length) - 1;
                string[] aufgeteilt = new string[8];
                aufgeteilt = zusammen.Split(' ');
                if (länge == Umwandlung.Wortzuzahl(aufgeteilt[3]))
                {
                    Console.WriteLine("Erfolg!");
                    Console.ReadKey();
                    break;
                }
                else
                {
                    aufgeteilt[3] = Umwandlung.Zahlzuwort(länge);
                    zusammen = aufgeteilt[0] + " " + aufgeteilt[1] + " " +
                        aufgeteilt[2] + " " + aufgeteilt[3] + " " +
                        aufgeteilt[4] + " " + aufgeteilt[5] + " " +
                        aufgeteilt[6] + " " + aufgeteilt[7];
                    Console.WriteLine(zusammen);
                }
            }
        }
    }
}

-------------------------------Neue Klasse -----------------------------

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Satzüberprüfung
{
    class Umwandlung
    {
        public static int Wortzuzahl(string a)
        {
            int zahl = 0;
            string temp = "";
            if (a.Contains("hundert"))
            {
                if (a.StartsWith("hundert"))
                {
                    zahl += 100;
                }
                else
                {
                    for (int i = 0; i < 4; i++)
                    {
                        temp += a[i];
                    }
                    zahl += (Wortzuzahl(temp) * 100);
                    while (true)
                    {
                        if (a.StartsWith("hundert"))
                        {
                            a = a.Remove(0, 7);
                            break;
                        }
                        a = a.Remove(0, 1);
                    }
                }

            }
            if (a.EndsWith("dreißig"))
            {
                zahl += 30;
                a = a.TrimEnd('d', 'r', 'e', 'i', 'ß', 'i', 'g');
            }
            /*else*/
            if (a.EndsWith("zig"))
            {
                a = a.TrimEnd('z', 'i', 'g');

                if (a.EndsWith("neun"))
                {
                    zahl += 90;
                    a = a.TrimEnd('n', 'e', 'u', 'n');
                }
                else if (a.EndsWith("acht"))
                {
                    zahl += 80;
                    a = a.TrimEnd('a', 'c', 'h', 't');
                }
                else if (a.EndsWith("sieb"))
                {
                    zahl += 70;
                    a = a.TrimEnd('s', 'i', 'e', 'b');
                }
                else if (a.EndsWith("sech"))
                {
                    zahl += 60;
                    a = a.TrimEnd('s', 'e', 'c', 'h');

                }
                else if (a.EndsWith("fünf"))
                {
                    zahl += 50;
                    a = a.TrimEnd('f', 'ü', 'n', 'f');
                }
                else if (a.EndsWith("vier"))
                {
                    zahl += 40;
                    a = a.TrimEnd('v', 'i', 'e', 'r');
                }
                else if (a.EndsWith("zwan"))
                {
                    zahl += 20;
                    a = a.TrimEnd('z', 'w', 'a', 'n');
                }
            }
            /*else*/
            if (a.EndsWith("zehn"))
            {
                zahl += 10;
            }
            /*else*/
            if (a.StartsWith("ein"))
            {
                zahl += 1;
            }
            /*else*/
            if (a.StartsWith("zwei"))
            {
                zahl += 2;
            }
            /*else*/
            if (a.StartsWith("drei"))
            {
                zahl += 3;
            }
            /*else*/
            if (a.StartsWith("vier"))
            {
                zahl += 4;
            }
            /*else*/
            if (a.StartsWith("fünf"))
            {
                zahl += 5;
            }
            /*else*/
            if (a.StartsWith("sech"))
            {
                zahl += 6;
            }
            /*else*/
            if (a.StartsWith("sieb"))
            {
                zahl += 7;
            }
            /*else*/
            if (a.StartsWith("acht"))
            {
                zahl += 8;
            }
            /*else*/
            if (a.StartsWith("neun"))
            {
                zahl += 9;
            }
            /*else*/
            if (a.StartsWith("elf"))
            {
                zahl = 11;
            }
            /*else*/
            if (a.StartsWith("zwölf"))
            {
                zahl = 12;
            }

            return zahl;
        }

        public static string Zahlzuwort(int a)
        {
            int erste;
            int zweite;
            string erster;
            string zweiter;
            string zahl = "";
            if ((a / 100) > 0)
            {
                erste = a / 100;
                zweite = a % 100;
                erster = Zahlzuwort(erste);
                zweiter = Zahlzuwort(zweite);
                if (erster == "eins")
                {
                    erster = "ein";
                }
                zahl = erster + "hundert" + zweiter;
            }
            else if (a < 13)
            {
                switch (a)
                {
                    case 1:
                        zahl = "eins";
                        break;
                    case 2:
                        zahl = "zwei";
                        break;
                    case 3:
                        zahl = "drei";
                        break;
                    case 4:
                        zahl = "vier";
                        break;
                    case 5:
                        zahl = "fünf";
                        break;
                    case 6:
                        zahl = "sechs";
                        break;
                    case 7:
                        zahl = "sieben";
                        break;
                    case 8:
                        zahl = "acht";
                        break;
                    case 9:
                        zahl = "neun";
                        break;
                    case 10:
                        zahl = "zehn";
                        break;
                    case 11:
                        zahl = "elf";
                        break;
                    case 12:
                        zahl = "zwölf";
                        break;
                }
            }
            else if (a % 10 == 0)
            {
                switch (a)
                {
                    case 20:
                        zahl = "zwanzig";
                        break;
                    case 30:
                        zahl = "dreißig";
                        break;
                    case 40:
                        zahl = "vierzig";
                        break;
                    case 50:
                        zahl = "fünfzig";
                        break;
                    case 60:
                        zahl = "sechzig";
                        break;
                    case 70:
                        zahl = "siebzig";
                        break;
                    case 80:
                        zahl = "achtzig";
                        break;
                    case 90:
                        zahl = "neunzig";
                        break;
                }
            }
            else if (a > 12 && a < 20)
            {
                erste = (a / 10) * 10;
                zweite = a % 10;
                erster = Zahlzuwort(erste);
                zweiter = Zahlzuwort(zweite);
                if (zweiter == "sieben")
                {
                    zweiter = zweiter.TrimEnd('e', 'n');
                }
                if (zweiter == "sechs")
                {
                    zweiter = zweiter.TrimEnd('s');
                }
                zahl = zweiter + erster;
            }
            else
            {
                erste = (a / 10) * 10;
                zweite = a % 10;
                erster = Zahlzuwort(erste);
                zweiter = Zahlzuwort(zweite);
                if (zweiter == "eins")
                {
                    zweiter = zweiter.TrimEnd('s');
                }
                zahl = zweiter + "und" + erster;
            }
            return zahl;
        }
    }
}
vote_ok
von hollst (10290 Punkte) - 05.02.2019 um 09:42 Uhr
Quellcode ausblenden C#-Code
using System;
using static System.Console;

namespace int_to_word   //    18.12.2018    18.12.2018
{
    class Program
    {
        static void Main()
        {
            test_n_to_word();
        }

        static string n0_99_to_string(int n)
        {
            string[] temp = new string[] {
                "null",
                "eins", "zwei",  "drei",     "vier",     "fünf",     "sechs",    "sieben",   "acht",     "neun",
                "zehn",
                "elf" , "zwölf", "dreizehn", "vierzehn", "fünfzehn", "sechzehn", "siebzehn", "achtzehn", "neunzehn"
            };

            if (n < 20)
                return temp[n];

            temp[1] = "ein";

            string[] temp_zig = new string[] {
                "zwanzig", "dreizig", "vierzig", "fünfzig", "sechzig", "siebzig", "achtzig", "neunzig"
            };

            string result = string.Empty;
            int n_1 = n % 10, n_10 = n / 10;

            if (n_1 == 0)
                return temp_zig[n_10 - 2];

            return result += temp[n_1] + "und" + temp_zig[n_10 - 2];
        }

        static string n_to_word(int n)
        {
            if (n < 0 || n > 999)
                return $"n = {n} does not meet input range (0 ... 999)";

            int n_100 = n / 100;
            if (n_100 == 0)
                return n0_99_to_string(n);

            string[] temp = new string[] {
                "ein", "zwei",  "drei",     "vier",     "fünf",     "sechs",    "sieben",   "acht",     "neun"
            };

            int n_10 = n % 100;
            string result = temp[n_100 - 1] + "hundert";
            if (n_10 != 0)
                result += n0_99_to_string(n_10);
            return result;
        }

        static void test_n_to_word()
        {
            int temp = "diesersatzhatbuchstabensowieeinenpunkt".ToCharArray().Length;
            for (int i = -1; i < 1002; i++)
            {
                int temp2 = n_to_word(i).ToCharArray().Length;
                WriteLine($"{i,3}: {temp2}   {temp + temp2}");
                if (temp + temp2 == i)
                    WriteLine("LÖSUNG");
            }
            ReadKey(false);
        }
    }
}
vote_ok
von daniel59 (3990 Punkte) - 06.02.2019 um 15:25 Uhr
Quellcode ausblenden C#-Code
using System;
using System.Collections.Generic;
using System.Linq;

namespace ConsoleSelbstbezueglicheAussage
{
    class Program
    {
        static void Main(string[] args)
        {
            string sentenceFmt = "Dieser Satz hat {0} Buchstaben sowie einen Punkt.";
            int counter = 0;
            for (int i = 2; i <= 100; i++)
            {
                string sentence = string.Format(sentenceFmt, GermanNumberConverter.Translate(i));
                string onlyLetters = KeepLetters(sentence);
                if (onlyLetters.Length == i)
                {
                    Console.WriteLine(sentence);
                    counter++;
                }
            }

            Console.WriteLine("{0} Sätze haben eine korrekte Aussage.", counter);
            Console.ReadLine();
        }

        static string KeepLetters(string input)
        {
            return new string(input.Where(c => char.IsLetter(c)).ToArray());
        }
    }

    class GermanNumberConverter
    {
        const string minus = "minus ";
        static readonly Dictionary<int, string> constants = new Dictionary<int, string>()
        {
            //{0, "null" },
            {1, "eins" },
            {2, "zwei" },
            {3, "drei" },
            {4, "vier" },
            {5, "fünf" },
            {6, "sechs" },
            {7, "sieben" },
            {8, "acht" },
            {9, "neun" },
            {10, "zehn" },
            {11, "elf" },
            {12, "zwölf" },
            {13, "dreizehn" },
            {14, "vierzehn" },
            {15, "fünfzehn" },
            {16, "sechszehn" },
            {17, "siebzehn" },
            {18, "achtzehn" },
            {19, "neunzehn" },
            {20, "zwanzig" },
            {21, "einundzwanzig" },
            {31, "einunddreizig" },
            {41, "einundvierzig" },
            {51, "einundfünfzig" },
            {61, "einundsechzig" },
            {70, "siebzig" },
            {71, "einundsiebzig" },
            {81, "einundachtzig" },
            {91, "einundneunzig" },
            {100, "einhundert" },
            {1000, "eintausend" },
            {1000000, "einemillion" },
            {1000000000, "einemilliarde" },
        };

        static readonly TranslationRule[] RuleSet =
        {
            new TranslationRule() { RangeFrom = 2, RangeTo = 999, Factor = 1000000000, Suffix = "milliarden" },
            new TranslationRule() { RangeFrom = 2, RangeTo = 999, Factor = 1000000,Suffix = "millionen" },
            new TranslationRule() { RangeFrom = 2, RangeTo = 999, Factor = 1000, Suffix = "tausend" },
            new TranslationRule() { RangeFrom = 2, RangeTo = 9, Factor = 100, Suffix = "hundert" },
            new TranslationRule() { RangeFrom = 3, RangeTo = 9, Factor = 10, Suffix = "zig" }
        };

        public static string Translate(int n)
        {
            if (n == 0)
            {
                return "null";
            }
            else if (n < 0)
            {
                return minus + TranslatePositiveNumber(-n);
            }
            else
            {
                return TranslatePositiveNumber(n);
            }
        }

        private static string TranslatePositiveNumber(int n)
        {
            List<NumberElement> elements = new List<NumberElement>();
            string s = Translate(n, ref elements);

            var ret = elements.Where(a => !string.IsNullOrWhiteSpace(a.Value)).ToArray();

            string value = "";
            for (int i = 0; i < ret.Length - 2; i++)
            {
                value += ret[i];
            }
            if (ret.Length >= 2)
            {
                NumberElement secondLast = ret[ret.Length - 2];
                NumberElement last = ret[ret.Length - 1];

                if (!secondLast.Value.StartsWith("ein") && secondLast.Value.EndsWith("zig") && last.Constant >= 1 && last.Constant <= 9)
                {
                    value += last.Value + "und" + secondLast.Value;
                }
                else
                {
                    value += secondLast.Value + last.Value;
                }
            }
            else
            {
                value = ret.FirstOrDefault();
            }

            return value;
        }

        private static string Translate(int n, ref List<NumberElement> list)
        {
            if (constants.Keys.Contains(n))
            {
                list.Add(new NumberElement() { Value = constants[n], Constant = n });
                return constants[n];
            }

            string result = "";

            int v = n;
            foreach (var rule in RuleSet)
            {
                NumberElement element;
                int sub;
                if (!rule.Assign(n, out element, out sub))
                {
                    return "";
                }
                v -= sub;
                result += element;
                list.Add(element);
                if (sub > 0)
                {
                    break;
                }
            }
            if (v > 0)
            {
                result += Translate(v, ref list);
            }

            return result;
        }

        private class GermanNumberTranslation
        {
            public int Number { get; set; }
            public string AsText { get; set; }
        }

        private class TranslationRule
        {
            public int RangeFrom { get; set; }
            public int RangeTo { get; set; }
            public int Factor { get; set; }
            public string Suffix { get; set; }

            public bool Assign(int n, out NumberElement element, out int sub)
            {
                element = (NumberElement)"";
                sub = 0;
                int value = n / Factor;
                sub = value * Factor;
                if (value == 0)
                {
                    return true;
                }
                if (constants.ContainsKey(sub))
                {
                    element.Value = constants[sub];
                    element.Constant = sub;
                    return true;
                }
                else if (value < RangeFrom || value > RangeTo)
                {
                    return false;
                }

                if (!constants.ContainsKey(value))
                {
                    element.Value = TranslatePositiveNumber(value);
                    if (string.IsNullOrWhiteSpace(element))
                    {
                        return false;
                    }
                    element.Value += Suffix;
                }
                else
                {
                    element.Value = constants[value] + Suffix;
                }


                return true;
            }
        }

        private class NumberElement
        {
            public string Value { get; set; }
            public int Constant { get; set; }

            public static implicit operator string(NumberElement v)
            {
                return v.Value;
            }

            public static explicit operator NumberElement(string v)
            {
                return new NumberElement() { Value = v };
            }

            public override string ToString()
            {
                return Value;
            }
        }
    }
}