C# :: Aufgabe #232 :: Lösung #6

6 Lösungen Lösungen öffentlich
#232

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ß!

#6
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;
            }
        }
    }
}

Kommentare:

Für diese Lösung gibt es noch keinen Kommentar

Bitte melden Sie sich an um eine Kommentar zu schreiben.
Kommentar schreiben