Willkommen auf myCSharp.de! Anmelden | kostenlos registrieren
 | Suche | FAQ

Hauptmenü
myCSharp.de
» Startseite
» Forum
» Suche
» Regeln
» Wie poste ich richtig?

Mitglieder
» Liste / Suche
» Wer ist online?

Ressourcen
» FAQ
» Artikel
» C#-Snippets
» Jobbörse
» Microsoft Docs

Team
» Kontakt
» Cookies
» Spenden
» Datenschutz
» Impressum

  • »
  • Community
  • |
  • Diskussionsforum
Das Programmier-Spiel: nette Übungsaufgaben für zwischendurch
DerKleineTomy
myCSharp.de - Member



Dabei seit:
Beiträge: 96

beantworten | zitieren | melden

Leider hab ich einen Fehler im vorgegebenen Code gefunden, zumindest stimmt es nicht mit der Beschreibung überein. Ich korrigiere den Fehler und mache die Stelle kenntlich. Hoffe niemand hat sich daran den Kopf zerbrochen :(

Hier sind drei Test-Automaten:


        // Gleich viele "a" wie "b"
        private static PushDownAutomaton GleichVieleAundB()
        {
            PushDownAutomaton automat = new PushDownAutomaton();
            State startUndEndZustand = new State();

            // (eingabe, stack, ausgabe)
            // Wichtig zu beachten: Das was auf dem Stack liegt wird vom Stack genommen!
            Transition a_1 = new Transition("a", null, startUndEndZustand, "a"); // (a, leer, a) => a auf den Stack legen
            Transition a_2 = new Transition("a", "a", startUndEndZustand, "a", "a"); // (a, a, aa) => a verdoppeln (1 a wird zu 2 a)
            Transition a_3 = new Transition("a", "b", startUndEndZustand, null); // (a, b, nichts) => b vom Stack nehmen
            Transition b_1 = new Transition("b", null, startUndEndZustand, "b"); // (b, leer, b) => b auf den Stack legen
            Transition b_2 = new Transition("b", "b", startUndEndZustand, "b", "b"); // (b, b, bb) => b verdoppeln
            Transition b_3 = new Transition("b", "a", startUndEndZustand, null); // (b, a, nichts) => a vom Stack nehmen

            startUndEndZustand.Transitions.AddRange(new Transition[] 
            {
                a_1, a_2, a_3, b_1, b_2, b_3
            });

            automat.FinalStates.Add(startUndEndZustand);
            automat.StartState = startUndEndZustand;

            return automat;
        }

        // Es gibt mehrere mögliche Übergänge.
        // Anzahl von a = (2 + 4k) => 2, 6, 10, 14, ...
        // Ein etwas komplizierter Automat
        private static PushDownAutomaton MehrereÜbergänge()
        {
            PushDownAutomaton automat = new PushDownAutomaton();
            State startZustand = new State();
            State endZustand = new State();

            // (eingabe, stack, ausgabe)
            Transition start_1 = new Transition("a", null, startZustand, "a"); // (a, leer, a)
            Transition start_2 = new Transition("a", "a", startZustand, "a", "a"); // (a, a, aa)
            Transition start_3 = new Transition("a", "a", endZustand, null); // (a, a, nichts)

            Transition end_1 = new Transition("a", null, endZustand, "a"); // (a, leer, a)
            Transition end_2 = new Transition("a", "a", endZustand, "a", "a"); // (a, a, aa)
            Transition end_3 = new Transition("a", "a", startZustand, null); // (a, a, nichts)

            startZustand.Transitions.AddRange(new Transition[] 
            {
                start_1, start_2, start_3
            });

            endZustand.Transitions.AddRange(new Transition[] 
            {
                end_1, end_2, end_3
            });

            automat.FinalStates.Add(endZustand);
            automat.StartState = startZustand;

            return automat;
        }

        // Gerade Anzahl an a
        private static PushDownAutomaton EpsilonÜbergänge()
        {
            PushDownAutomaton automat = new PushDownAutomaton();
            State startZustand = new State();
            State endZustand = new State();

            // (eingabe, stack, ausgabe)
            Transition start_1 = new Transition("a", null, startZustand, "a"); // (a, leer, a)
            Transition start_2 = new Transition("a", "a", startZustand, "a", "a"); // (a, a, aa)
            Transition start_3 = new Transition(null, null, endZustand, null); // Epsilonübergang

            Transition end = new Transition("a", "a", endZustand, null); // (a, a, nichts)

            startZustand.Transitions.AddRange(new Transition[] 
            {
                start_1, start_2, start_3
            });

            endZustand.Transitions.AddRange(new Transition[] 
            {
                end
            });

            automat.FinalStates.Add(endZustand);
            automat.StartState = startZustand;

            return automat;
        }

        public static void Main(String[] args)
        {
            PushDownAutomaton automat = GleichVieleAundB();


            while (true)
            {
                String input = Console.ReadLine();
                List<String> word = new List<String>();
                foreach (Char c in input)
                    word.Add(c.ToString());

                Console.WriteLine(automat.CheckWord(word));
            }
        }
private Nachricht | Beiträge des Benutzers
DerKleineTomy
myCSharp.de - Member



Dabei seit:
Beiträge: 96

beantworten | zitieren | melden

Da wohl keiner Lust hatte die Aufgabe zu lösen, poste ich meine Lösung. Somit ist das Programmierspiel wieder freigegeben (so wie es auch im ersten Post beschrieben ist, da keine Antwort innerhalb einer Woche kam).

        // input => Wort
        // index => Der aktuelle Buchstabe im Wort
        // stack => Der Stack
        // finalStates => Die Endzustände
        // Gibt <true> zurück, wenn das Wort abgearbeitet ist, der Stack leer ist und der letzte Zustand ein Endzustand war
        public Boolean ChangeState(List<String> input, Int32 index, Stack<String> stack, List<State> finalStates)
        {
            // Wenn das Wort abgearbeitet ist, nichts mehr auf dem Stack liegt und der momentane Zustand ein Endzustand ist...
            if (index ≥ input.Count && stack.Count == 0 && finalStates.Contains(this))
                return true; // Dann wurde das Wort erkannt

            // Alle Übergänge durchgehen
            foreach (var transition in Transitions)
            {
                // Wenn das Wort abgearbeitet ist, sind nur noch Epsilonübergänge erlaubt, andernfalls muss die Bedingung überprüft werden
                Boolean condition = index ≥ input.Count ? transition.IsEpsilon : transition.CheckConditions(input[index], stack);
                if (condition)
                {
                    String element = null;
                    // Den Stack ändern, außer bei Epsilonübergängen und leeren Stacks
                    if (stack.Count > 0 && !transition.IsEpsilon)
                        element = stack.Pop();

                    // Den Output vom Übergang auf den Stack legen
                    foreach (String str in transition.Output)
                        stack.Push(str);
                    // ------------

                    // Zum nächsten Zustand wechseln. Wenn es ein Epsilonübergang war, darf nicht zum nächsten Element im Wort gesprungen werden!
                    if (transition.NextState.ChangeState(input, index + (transition.IsEpsilon ? 0 : 1), stack, finalStates))
                        return true;

                    // Alle Änderungen auf dem Stack rückgängig machen
                    for (Int32 i = 0; i < transition.Output.Count; i++)
                        stack.Pop();

                    if (element != null)
                        stack.Push(element);
                    // ------------
                }
            }

            // Alle Übergange wurden geprüft und keiner hat zum Ziel geführt
            return false;
        }
private Nachricht | Beiträge des Benutzers
stalky13
myCSharp.de - Member

Avatar #avatar-3335.jpg


Dabei seit:
Beiträge: 4
Herkunft: Österreich

beantworten | zitieren | melden

Hallo Leute,

da die Letzte Aufgabe nicht gelöst wurde, nach 10 Tagen die Lösung vom Aufgabensteller selbst gepostet wurde, dieser darauf verzichtet hat erneut eine Aufgabe zu stellen ...
Zitat von DerKleineTomy
Somit ist das Programmierspiel wieder freigegeben
... und seit 5 Tagen keine neue Aufgabe mehr gestellt wurde, versuche ich es jetzt einmal mit einer neuen Aufgabe. Insofern niemand was dagegen hat.

Also:
Aufgabe:
Vervollständigen Sie, die im Test-Code definierte Methode so, dass diese eine [URL]Mandelbrot-Menge[/URL] (Apfelmännchen) zeichnet.

Rahmenbedingungen:
- Die Mandelbrot-Menge soll Einfarbig (frontColor) und mit einer Hintergrundfarbe (backColor) gezeichnet werden.
- Die Parameter "section -Left -Top -Right -Bottom" geben den Ausschnitt in der Mandelbrot-Menge an, der gezeichnet werden soll.
- Der Parameter "deep" gibt die maximale Anzahl Iterationen pro Pixel an.

Test-Code:

using System;
using System.Windows.Forms;
using System.Drawing;

namespace Fractals
{

	/// <summary>
	/// Stellt ein Fenster dar, dass ein Mandelbrot Apfelmännchen Fraktal anzeigt.
	/// </summary>
	public class MandelbrotForm : Form
	{

		//Mandelbrot PictureBox
		PictureBox mandelbrotPicture;

		/// <summary>
		/// Erstellt ein neues Mandelbrot Fenster.
		/// </summary>
		public MandelbrotForm()
		{
			//Fenster Parameter festlegen
			this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
			this.StartPosition = FormStartPosition.CenterScreen;
			this.Size = new Size(900, 600);

			//Image Control erstellen
			mandelbrotPicture = new PictureBox();
			mandelbrotPicture.Dock = DockStyle.Fill;
			this.Controls.Add(mandelbrotPicture);

			//Fenster anzeigen
			this.Show();

			//Image mit dem Mandelbrot Fraktal erstellen
			Bitmap mandelbrot = new Bitmap(this.Size.Width, this.Size.Height);
			using (Graphics gfx = Graphics.FromImage(mandelbrot))
			{
				Mandelbrot.DrawMandelbrot(
						gfx,
						Color.OrangeRed,
						Color.LightBlue,
						-2.0, -1.0, 1.0, 1.0,															//Ganzes Apfelmännchen
						//0.3184375, -0.0557421875, 0.34533203125, -0.0355712890625,					//Ausschnitt
						//0.32155833984375, -0.6327984375, 0.422811767578125, -0.55685836669921875,		//Ausschnitt
						100);
			}
			mandelbrotPicture.Image = mandelbrot;
		}

	}


	/// <summary>
	/// Stellt eine Klasse zum Zeichnen von Mandelbrot Apfelmännchen Fraktalen dar.
	/// </summary>
	public static class Mandelbrot
	{

		/// <summary>
		/// Zeichnet ein Mandelbrot Apfelmännchen.
		/// </summary>
		/// <param name="gfx">Grafikausgabe.</param>
		/// <param name="frontColor">Farbton, der für das Zeichnen verwendet werden soll.</param>
		/// <param name="backColor">Hintergrundfarbe.</param>
		/// <param name="sectionLeft">Gibt den linken Rand des Ausschnitts an, der von dem Apfelmännchen gezeichnet werden soll.</param>
		/// <param name="sectionTop">Gibt den oberen Rand des Ausschnitts an, der von dem Apfelmännchen gezeichnet werden soll.</param>
		/// <param name="sectionRight">Gibt den rechten Rand des Ausschnitts an, der von dem Apfelmännchen gezeichnet werden soll.</param>
		/// <param name="sectionBottom">Gibt den unteren Rand des Ausschnitts an, der von dem Apfelmännchen gezeichnet werden soll.</param>
		/// <param name="deep">Gibt die maximale Anzahl Iterationen an.</param>
		public static void DrawMandelbrot(Graphics gfx, Color frontColor, Color backColor, double sectionLeft, double sectionTop, double sectionRight, double sectionBottom, int deep)
		{
			//Erstellen Sie Ihren Code hier.
		}
	}
}


Viel Spaß und Gruß Stalky13

Ps. Fraktale sind Awsome :D

Edit:
Da es nicht voran zu gehen scheint, hier ein Tipp: In dem Wikipediabeitrag findet ihr die nötigen Informationen zur Lösung ganz unten. Ihr müsst also nicht den ganzen Beitrag lesen, sondern nur einen kleinen Teil am Ende.
Meine Version besteht aus 20 Zeilen Code (ohne Klammern und Kommentare).
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von stalky13 am .
Aus großer Macht folgt große Verantwortung!

Moderationshinweis von herbivore (31.05.2012 - 07:05)

Zu dieser Aufgabe gibt es eine (etwas verspätete) Lösung von Quadsoft weiter unten.

private Nachricht | Beiträge des Benutzers
thetruedon
myCSharp.de - Member



Dabei seit:
Beiträge: 111

beantworten | zitieren | melden

Offenbar kommt keiner drauf also möchte ich eine neue kleine Aufgabe stellen.

Um etwas das Verständnis in Sachen "Wie rechnet mein Rechner?" eigentlich zu festigen würde ich gern folgende Funktion sehen:
Ich übergebe 3 Bit (2 die ich addieren will und den Übertrag von der vorherigen Rechnung)

Um Große zahlen zu berechnen wird jede Operation auf Additionen zurückgeführt die die Recheneinheit dann berechnen kann. (Wie das geht steht bestimmt irgendwo auf Wikipedia und co.) Dabei werden immer 2 Bit miteinander addiert und ggf. ein Übertrag der vorherigen Stelle)

Ziel ist es ganz einfach eine Funktion zu schreiben der man 3 Bit (0 oder 1) übergibt.
Zahl1, Zahl2 und den Übertag.

Die Funktion gibt dann die Summe aus und zwar als string in Binärschreibweise.
Dazu will ich noch wissen wie sich das nennt was ihr da Programmiert habt.


Zur Info:
bei 3 Bit die Man addiert kann nur 00, 01, 10 oder 11 herauskommen von daher kann man das von mir aus auch mit einer switch Anweisung machen oder so um sich das umrechnen von dezimal in dual zu sparen.


Wichtig ist dass ich die Ergebnisse von
0 und 0 Übertrag 0
0 und 0 Übertrag 1
0 und 1 Übertrag 0
0 und 1 Übertrag 1
1 und 0 Übertrag 0
1 und 0 Übertrag 1
1 und 1 Übertrag 0
1 und 1 Übertrag 1
bekomme
Kommt ein Mann in die Wirtschaft und sagt zum Wirt: 16 Bit!
Sagt der Wirt: Das ist ein Wort!
private Nachricht | Beiträge des Benutzers
Scavanger
myCSharp.de - Member

Avatar #avatar-3209.jpg


Dabei seit:
Beiträge: 309

beantworten | zitieren | melden


static string VollAddierer(string x, string y, string cin)
{
    bool x_B, y_B, cin_B;

    if (!ParseBit(x, out x_B))
        throw new ArgumentException("x");

    if (!ParseBit(y, out y_B))
        throw new ArgumentException("y");

    if (!ParseBit(cin, out cin_B))
        throw new ArgumentException("cin");

    bool cout = (y_B & cin_B) | (x_B & cin_B) | (x_B & y_B);
    bool s = x_B ^ y_B ^ cin_B;

    return (cout ? "1" : "0") + (s ? "1" : "0");
}

static bool ParseBit(string value, out bool result)
{
    if (bool.TryParse(value, out result))
        return true;
    else if (value == "1")
    {
        result = true;
        return true;
    }
    else if (value == "0")
    {
        result = false;
        return true;
    }

    result = false;
    return false;
}

Das ganze nennt sich Volladdierer

Aber warum Strings?

using System;class H{static string z(char[]c){string r="";for(int x=0;x<(677%666);x++)r+=c[
x];return r;}static void Main(){int[]c={798,218,229,592,232,274,813,585,229,842,275};char[]
b=new char[11];for(int p=0;p<((59%12));p++)b[p]=(char)(c[p]%121);Console.WriteLine(z(b));}}
private Nachricht | Beiträge des Benutzers
thetruedon
myCSharp.de - Member



Dabei seit:
Beiträge: 111

beantworten | zitieren | melden

hiho die antwort ist richtig ich wollte grade noch sagen weil ich darauf hingewiesen wurde bitte auch strings als parameter. aber das hast du ja schon gemacht. warum strings? tja warum strings? ich wollt halt nicht klassisch bool oder zahlen nutzen ;) aber ist auch nebensächlich das wichtige ist dass die idee verstanden wurde wie ein rechner rechnet du bist dran scavanger
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von thetruedon am .
Kommt ein Mann in die Wirtschaft und sagt zum Wirt: 16 Bit!
Sagt der Wirt: Das ist ein Wort!
private Nachricht | Beiträge des Benutzers
dN!3L
myCSharp.de - Experte

Avatar #avatar-2985.png


Dabei seit:
Beiträge: 2.891

beantworten | zitieren | melden

Da seit über einem Monat keine neue Aufgabe gestellt wurde, mache ich das mal:
Gesucht ist eine Methode [tt]TElement PickRandom(IEnumerable<TElement> source)[/tt], die ein zufälliges Element aus einer Auflistung zurückgeben soll.

Folgende Bedingungen müssen allerdings erfüllt sein:
[list]
[*]Die Auflistung darf nur ein einziges Mal durchlaufen werden.
[*]Die Auflistung darf nicht zwischengespeichert werden.
[*]Die Wahrscheinlichkeit, ausgewählt zu werden, muss für alle Elemente der Auflistung gleich sein.
[/list]

Falls die Auflistung keine Elemente enthält, sollte eine Ausnahme ausgelöst werden.
private Nachricht | Beiträge des Benutzers
DeZio
myCSharp.de - Member

Avatar #avatar-3334.png


Dabei seit:
Beiträge: 76

beantworten | zitieren | melden


private static Random m_objRand;

public TElement PickRandom (IEnumerable<TElement> source) {
    if (m_objRand == null)  m_objRand = new Random();
    int iCount = source.Count<TElement>();
    if (iCount == 0) throw new Exception("COUNT darf nicht 0 sein.");
    int iIndex = 0;
    int iRandomObjectIndex = m_objRand.Next(0, source.Count<TElement>());
    foreach (TElement obj in source) {
        if (iIndex == iRandomObjectIndex) {
            return obj;
        } // if end
        iIndex++;
    } // foreach end
    return null;
}
Ich denke, die Antwort ist zu "einfach" oder? :D
Dieser Beitrag wurde 2 mal editiert, zum letzten Mal von DeZio am .
private Nachricht | Beiträge des Benutzers
DerKleineTomy
myCSharp.de - Member



Dabei seit:
Beiträge: 96

beantworten | zitieren | melden

Ich denke deine Lösung zählt nicht, da die Count() Methode die Liste einmal durchläuft und du deshalb insgesamt 3 Durchläufe hast.
private Nachricht | Beiträge des Benutzers
DeZio
myCSharp.de - Member

Avatar #avatar-3334.png


Dabei seit:
Beiträge: 76

beantworten | zitieren | melden

Okay... source.Count<TElement>() als 2. Parameter in new Random sollte eh iCount werden - aber das tut ja nichts zur Sache. 2 sind's trotzdem :D

// Edit
Schwierige Sache. Ich habe eine 2. Idee gehabt: Erst OrderBy Random (1 Durchlauf) - und dann das erste Element [0] durch ToList() returnen. Bei Fehler eben throw Excption - aber ich denke: ToList() läuft die IEnumerable ein zweites Mal durch. Oder?

Würde so aussehen:

    public class TElement { public int Index = 0; }

    internal class Program {
        private static Random m_objRand;

        private static void Main () {
            List<TElement> source = new List<TElement>();
            source.Add(new TElement() { Index = 0 });
            source.Add(new TElement() { Index = 1 });
            source.Add(new TElement() { Index = 2 });
            source.Add(new TElement() { Index = 3 });
            source.Add(new TElement() { Index = 4 });
            for (int i = 0; i < 2; i++) {
                TElement rand = PickRandom(source);
                Console.WriteLine(rand.Index);
            } // for end
        }

        
        public static TElement PickRandom (IEnumerable<TElement> source) {
            if (m_objRand == null) m_objRand = new Random();
            try {
                return source.OrderBy(obj => m_objRand.Next()).First();
            } // try end
            catch {
                throw new Exception();
            }
        }
    }

// Edit 2: Hab die Lösung! Man benötigt nicht "ToList()" - man kann auf die Methode First() zurückgreifen :)



Grüße
Dennis Z.
Dieser Beitrag wurde 3 mal editiert, zum letzten Mal von DeZio am .
private Nachricht | Beiträge des Benutzers
dN!3L
myCSharp.de - Experte

Avatar #avatar-2985.png


Dabei seit:
Beiträge: 2.891

beantworten | zitieren | melden

Zitat von DeZio
OrderBy
Naja, ein OrderBy speichert allerdings erst die gesamte Auflistung zwischen und gibt sie dann an First weiter. Verstößt gegen die zweite Regel.
private Nachricht | Beiträge des Benutzers
Darth Maim
myCSharp.de - Member



Dabei seit:
Beiträge: 216

beantworten | zitieren | melden

Ich glaube meine Methode sollte funktionieren.

public static T PickRandom<T>(IEnumerable<T> source)
{
  Random r = new Random();

  int count = 0;
  T selected = default(T);

  foreach (T t in source)
  {
    count++;
    if (r.Next(count) == 0)
      selected = t;
  }

  if (count == 0)
    throw new Exception("source was empty");

  return selected;
}

Ich laufe jedes Element der Auflistung durch und zähle dabei count hoch. Mit einer Wahrscheinlichkeit von 1/count überschreibe ich das Element in selected, dass heißt das erste Element überschreibt mit einer Wahrscheinlichkeit von 1/1 -> es wird auf jedenfall gewählt. Das 2. Element wird mit einer Wahrscheinlichkeit von 1/2 gewählt.
Das 3. Element überschreibt mit einer Wahrscheinlichkeit von 1/3 das Element, das davor gewählt wurde. Mit einer Wahrscheinlichkeit von 1/3 ist also das dritte Element das gewählte. Die restlichen 2/3 teilen sich die ersten beiden Elemente, die dadurch beide auch jeweils 1/3 Wahrscheinlichkeit haben.
Das n. Element wird mit einer Wahrscheinlichkeit von 1/n gewählt. Dadurch hat insgesamt jedes Element die Wahrscheinlichkeit 1/n, da das Element davor mit einer Wahrscheinlichkeit von 1/n überschrieben wird und die Elemente davor alle eine Wahrscheinlichkeit von 1/(n-1) hatten.

Nach dem Schleifendurchlauf prüfe ich dann noch ob count 0 war, damit ich dann wie in der Aufgabe gefordert eine Exception werfen kann.

Und falls ich nichts übersehen habe und meine Antwort richtig ist, darf wer anders die nächste Frage stellen.

Darth Maim
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von Darth Maim am .
private Nachricht | Beiträge des Benutzers
dN!3L
myCSharp.de - Experte

Avatar #avatar-2985.png


Dabei seit:
Beiträge: 2.891

beantworten | zitieren | melden

Zitat von Darth Maim
Und falls ich nichts übersehen habe und meine Antwort richtig ist, darf wer anders die nächste Frage stellen.
Das ist die Antwort, die ich gesucht habe. :)
Der Nächste ist dran!
private Nachricht | Beiträge des Benutzers
thetruedon
myCSharp.de - Member



Dabei seit:
Beiträge: 111

beantworten | zitieren | melden

OK wenn der nächste darf geb ich mal was neues vor.

Ich möchte ein Quine also ein Programm, das sich selber ausgibt (also den Quelltext)

Ich gebe mal folgende Klasse vor:

class Program
  {
    static void Main(string[] args)
    {
       Console.WriteLine("...");
    }
  }

Wie ihr seht will ich keine gigantische Anwendung belasst es bei einer kleinen Ausgabe da ihr euch sonst nur noch mehr Arbeit aufhalst.
Bearbeitet die Main so dass alles von class bis } ausgegeben wird.

Und das alles ohne Reflection und in max. 5 Zeilen (soviele braucht man gar nicht denke ich.
Have fun
Kommt ein Mann in die Wirtschaft und sagt zum Wirt: 16 Bit!
Sagt der Wirt: Das ist ein Wort!
private Nachricht | Beiträge des Benutzers
Quadsoft
myCSharp.de - Member



Dabei seit:
Beiträge: 49
Herkunft: Flensburg

beantworten | zitieren | melden

In der Vorlage fehlen Namespaces...

class Program
{
    static void Main(string[] args)
    {
       string o = "class Program{{static void Main(string[] args){{string o={1}{0}{1};System.Console.WriteLine(o, o, (char)34);}}}}";
       System.Console.WriteLine(o, o, (char)34);
    }
}

btw so ists angenehmer

class Program
{
    static void Main(string[] args)
    {
        string o = "class Program{{static void Main(string[] args){{string o={1}{0}{1};System.Console.WriteLine(o, o, (char)34);System.Console.ReadLine();}}}}";
       System.Console.WriteLine(o, o, (char)34);
       System.Console.ReadLine();
    }
}
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von Quadsoft am .
private Nachricht | Beiträge des Benutzers
thetruedon
myCSharp.de - Member



Dabei seit:
Beiträge: 111

beantworten | zitieren | melden

Erstaunlich nahe an meinem Code
Jop naja namespace hin oder her die Vorlage sollte nur hinweisen dass ich nicht gleich ein 100 Zeilenprogramm sehen will weil das beim schreiben und lesen sonst zu depressionen geführt hätte
Richtig gemacht du bist dran

Edit:
Achso hab ich zwar nicht gesagt aber schön wäre ein Environment.NewLine für Zilenumbrüche gewesen schließlich will man den Code ja am ende auch wieder lesen können
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von thetruedon am .
Kommt ein Mann in die Wirtschaft und sagt zum Wirt: 16 Bit!
Sagt der Wirt: Das ist ein Wort!
private Nachricht | Beiträge des Benutzers
Quadsoft
myCSharp.de - Member



Dabei seit:
Beiträge: 49
Herkunft: Flensburg

beantworten | zitieren | melden

Meinst du so:


class Program
{
    static void Main(string[] args)
    {
        string o = "class Program{2}{{{2}static void Main(string[] args){2}{{{2}string o={1}{0}{1};{2}System.Console.WriteLine(o, o, (char)34, System.Environment.NewLine);{2}System.Console.ReadLine();{2}}}{2}}}";
        System.Console.WriteLine(o, o, (char)34, System.Environment.NewLine);
        System.Console.ReadLine();
    }
}

und kann bitte jemand anderes die neue aufgabe posten??
private Nachricht | Beiträge des Benutzers
Quadsoft
myCSharp.de - Member



Dabei seit:
Beiträge: 49
Herkunft: Flensburg

beantworten | zitieren | melden

Moderationshinweis von herbivore (31.05.2012 - 07:03)

Diese Lösung bezieht sich auf die Aufgabe von Stalky13 weiter oben.


@Stalky13

Noch so ein Fraktalbegeisteter, der hier rumläuft :D

Hier die Lösung: (siehe unten)

Guck dir dazu auch mein Programm XFract an:

XFract - Fraktalgenerator für Julia- und Mandelbrotmengen - NEUE VERSION

Und meine Facharbeit zum Thema Fraktale:

http://fraktale.quadsoft.org

/// <summary>
        /// Zeichnet ein Mandelbrot Apfelmännchen.
        /// </summary>
        /// <param name="gfx">Grafikausgabe.</param>
        /// <param name="frontColor">Farbton, der für das Zeichnen verwendet werden soll.</param>
        /// <param name="backColor">Hintergrundfarbe.</param>
        /// <param name="sectionLeft">Gibt den linken Rand des Ausschnitts an, der von dem Apfelmännchen gezeichnet werden soll.</param>
        /// <param name="sectionTop">Gibt den oberen Rand des Ausschnitts an, der von dem Apfelmännchen gezeichnet werden soll.</param>
        /// <param name="sectionRight">Gibt den rechten Rand des Ausschnitts an, der von dem Apfelmännchen gezeichnet werden soll.</param>
        /// <param name="sectionBottom">Gibt den unteren Rand des Ausschnitts an, der von dem Apfelmännchen gezeichnet werden soll.</param>
        /// <param name="deep">Gibt die maximale Anzahl Iterationen an.</param>
        public static void DrawMandelbrot(Graphics gfx, Color frontColor, Color backColor, double sectionLeft, double sectionTop, double sectionRight, double sectionBottom, int deep)
        {
            SolidBrush front = new SolidBrush(frontColor);
            SolidBrush back = new SolidBrush(backColor);

            System.Numerics.Complex  z, c;

            for (int x = 0; x < (int)gfx.VisibleClipBounds.Width; x++)
            {
                for (int y = 0; y < (int)gfx.VisibleClipBounds.Height; y++)
                {
                    z = new System.Numerics.Complex(0,0);
                    c = new System.Numerics.Complex(sectionLeft + (sectionRight - sectionLeft) * (x / gfx.VisibleClipBounds.Width),
                        sectionTop + (sectionBottom - sectionTop) * (y / gfx.VisibleClipBounds.Height));

                    int i = 0;

                    while (true)
                    {
                        i++;
                        z = z * z + c;

                        if (z.Magnitude > 2.0)
                        {
                            gfx.FillRectangle(back, x, y, 1, 1);
                            break;
                        }
                        else if (i == deep)
                        {
                            gfx.FillRectangle(front, x, y, 1, 1);
                            break;
                        }
                    }
                }
            }
        }
Dieser Beitrag wurde 2 mal editiert, zum letzten Mal von Quadsoft am .
private Nachricht | Beiträge des Benutzers
stalky13
myCSharp.de - Member

Avatar #avatar-3335.jpg


Dabei seit:
Beiträge: 4
Herkunft: Österreich

beantworten | zitieren | melden

Hi,

die Lösung von Quadsoft entspricht genau der Aufgabe und ist somit völlig korrekt.
Mit Einfarbig hatte ich eigendlich einen Farbverlauf von der Fordergrund zur Hintergrund Farbe gemeint, beim erneuten durch lesen der Aufgabe, ist mir allerdings erst jetzt aufgefallen, das ich diesen Punkte hätte besser definieren sollen.

Wie auch immer, ich freue mich, dass nun doch eine Lösung gekommen ist

@Quadsoft

Ich werd mir dein Programm und deine Facharbeit auf jeden Fall ansehen, aber erst morgen ich muss nämlich gleich los.
Ach ja und da deine Antwort richtig ist, darfst du vor 2 Monaten eine neue Aufgabe stellen
Aus großer Macht folgt große Verantwortung!
private Nachricht | Beiträge des Benutzers
Jasper
myCSharp.de - Member



Dabei seit:
Beiträge: 6
Herkunft: Frankfurt

beantworten | zitieren | melden

Zitat
Wenn eine Woche seit dem jeweils letzten Beitrag vergangen ist, ist der Thread wieder frei für eine neue Aufgabe (egal wer die neue Aufgabe stellen möchte und egal ob dieser letzte Beitrag nun eine Aufgabe, eine Nachfrage oder eine Lösung ist und egal ob die Lösung richtig oder falsch war, also einfach: eine Woche Inaktivität = neue Aufgabe erlaubt).

Damit möchte ich auch gleich den Thread mal wieder aus der Versenkung holen.

Es ist eine kleine Aufgabe, ihr könnt sie als Code oder auch mit Code und Papier lösen.
Wie ihr das macht ist ja im Endeffekt euch überlassen.

Hinter folgender Zahl ist ein Wort versteckt, welches ich gerne von euch wissen möchte:
110098088072122105107

2 kleine Tipps:
- Das Wort besteht aus 7 Buchstaben.
- Sobald ihr aus den Zahlen Buchstaben gemacht habt müsst ihr verkehrt herum denken.

Viel Spaß beim Lösen!
private Nachricht | Beiträge des Benutzers
Alf Ator
myCSharp.de - Member



Dabei seit:
Beiträge: 700

beantworten | zitieren | melden

@ Patrick R.

myCSarp
private Nachricht | Beiträge des Benutzers
Jasper
myCSharp.de - Member



Dabei seit:
Beiträge: 6
Herkunft: Frankfurt

beantworten | zitieren | melden

Da ist mir doch glatt selbst ein Fehler beim Umschreiben unterlaufen. Peinlich, Peinlich...
Aber ja, in diesem Fall stimmt das dann.

War wie gesagt nur etwas sehr kleines, damit der Thread mal wieder aus der Versenkung erscheint.

@Alf Ator It's your turn.
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von Jasper am .
private Nachricht | Beiträge des Benutzers
Alf Ator
myCSharp.de - Member



Dabei seit:
Beiträge: 700

beantworten | zitieren | melden

Zitat von Patrick R.
Da ist mir doch glatt selbst ein Fehler beim Umschreiben unterlaufen.

Ich dachte schon, dass war Absicht, um uns zu testen.


Also ich überlege mir eine Aufgabe. Aber jeder der will und eine Aufgabe hat, kann eine Posten. Dann mach ich meine Aufgabe später.
private Nachricht | Beiträge des Benutzers
dN!3L
myCSharp.de - Experte

Avatar #avatar-2985.png


Dabei seit:
Beiträge: 2.891

beantworten | zitieren | melden

Könntet ihr bitte noch einen kurzen Satz hinterlassen, wie man denn nun von den Zahlen auf das Wort kommt?
private Nachricht | Beiträge des Benutzers
Alf Ator
myCSharp.de - Member



Dabei seit:
Beiträge: 700

beantworten | zitieren | melden

Oh, natürlich, sorry.



Also 7 Buchstaben-Wort und 21 Zahlen -> 3 Ziffern pro Buchstabe. Das ganze in der Asciitabelle nachschlagen und dann die herausgefundenen Buchstaben, von hinten abzählen. Also X wird zu C.
Die Tipps habens sehr einfach gemacht.
private Nachricht | Beiträge des Benutzers
trib
myCSharp.de - Member



Dabei seit:
Beiträge: 702

beantworten | zitieren | melden

Hallo "Spieler"

da sich noch keiner erbarmt hat und Alf Ator es freigestellt hat sich dazwischen zu drängeln, hier eine Aufgabe aus dem Alltag.

Letzte Woche stand ich vor folgendem Problem:

Eine Erinnerungsfunktion sollte um eine Sprachausgabe erweitert werden und mir ein paar Informationen nennen.
Darunter die aktuelle Uhrzeit und die Dauer zum nächsten Termin.

Wie spreche ich nun also nach allen Regeln der deutschen Sprache korrekt ganze Zahlen aus?

Ganz klar, folgende Wörter sind obligatorisch:

string [] bis20 = new string[]{"Null", "ein", "zwei", "drei", "vier", "fünf",
              "sechs", "sieben", "acht", "neun", "zehn", "elf",
              "zwölf", "dreizehn", "vierzehn", "fünfzehn",
              "sechzehn", "siebzehn", "achtzehn", "neunzehn"};

string[] zehner = new string[]{"Null", "zehn", "zwanzig", "dreissig", "vierzig",
                "fünfzig", "sechzig", "siebzig", "achtzig", "neunzig"};
Um es noch etwas schwieriger zu machen, brauchen wir auch noch Hunderter, Tausender, bis zur einer Milliarde (Zahlennamen).
(Es hat einen speziellen Grund, weshalb ich diese nicht als string[] oben mit eingefügt habe)

Nun kann man schon fleißig los programmieren und schnell wird klar, dass noch ein und her muss. Die Ausgaben scheinen auch schon zu funktionieren:
Fünfhundertsechsundzwanzig
Zweihundertsieben ("und" bei einer Null an der Zehnerstelle nicht unbedingt notwendig)
Hundertein => Fehler!
Also noch eine Unterscheidung mehr und wir sind am Ende angekommen.

Oder?

[EDIT] Auf Anraten von herbivore möchte ich die Aufgabe auf folgenden Zahlenbereich deckeln:
0 bis 1 000 000 000 (eine Millarde).
Den Bereich noch weiter zu erhöhen ist schließlich nur Fleißarbeit.
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von trib am .
private Nachricht | Beiträge des Benutzers
trib
myCSharp.de - Member



Dabei seit:
Beiträge: 702

beantworten | zitieren | melden

Da sich bisher noch niemand gemeldet hat, gebe ich noch schnell zwei entscheidende Tipps:
(Wer sich dessen schon angenommen hat, sollte hier ggf. nicht weiterlesen )
  • Die Hunderter, Tausender, usw. habe ich absichtlich weggelassen, da diese optimaler Weise auf zwei Arrays aufgeteilt werden müssen. Und zwar in singular & plural.
  • Die Eingabe wird in Dreiergruppen aufgespaltet und verarbeitet!

Ansonsten: Kritik oder Anregungen?
Zu einfach, zu langweilig, gibt es schon 100fach im Internet?
private Nachricht | Beiträge des Benutzers
jannemann13
myCSharp.de - Member

Avatar #avatar-2976.gif


Dabei seit:
Beiträge: 69

beantworten | zitieren | melden

Hallo trib,

Hier mal meine Lösung, basierend auf deinen Tipps:

public class NumberToTextConverter
{
  private string[] _lessThan20 = 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" };
  private string[] _magnitude1 = new string[] { "", "ein", "zwei", "drei", "vier", "fünf", "sechs", "sieben", "acht", "neun" };
  private string[] _magnitude10 = new string[] { "", "zehn", "zwanzig", "dreissig", "vierzig", "fünfzig", "sechzig", "siebzig", "achtzig", "neunzig" };
  private string[] _magnitudesSingular = new string[] { "hundert", "tausend", " million ", " milliarde " };
  private string[] _magnitudesPlural = new string[] { "hundert", "tausend", " millionen ", " milliarden " };

  public string NumberToText(int number)
  {
    StringBuilder resultBuilder = new StringBuilder();
    string result = string.Empty;
    string numberText = number.ToString();
    int orderOfMagnitude = 0;

    if (number < 20)
      result = _lessThan20[number];
    else
    {
      while (numberText.Length > 2)
      {
        result = this.NumberPartToText(numberText.Substring(numberText.Length - 3, 3), orderOfMagnitude++) + result;
        numberText = numberText.Remove(numberText.Length - 3);
      }
      result = this.NumberPartToText(numberText.PadLeft(3, '0'), orderOfMagnitude++) + result;
    }

    foreach (string word in result.Split(' '))
      if (word.Length > 0)
        resultBuilder.Append(word.Substring(0, 1).ToUpper() + word.Substring(1) + " ");

    return resultBuilder.ToString(); 
  }

  private string NumberPartToText(string numberPart, int orderOfMagnitude)
  {
    string result = string.Empty;

    if (numberPart == "000")
      return string.Empty;

    if (numberPart == "001" && orderOfMagnitude > 0)
      return (orderOfMagnitude == 1 ? "ein" : "eine") + _magnitudesSingular[orderOfMagnitude];

    if (numberPart[0] != '0')
      result = _magnitude1[int.Parse(numberPart[0].ToString())] + _magnitudesSingular[0];

    result += this.TwoDigitsToText(numberPart.Substring(1, 2));
    if (orderOfMagnitude > 0)
      result += int.Parse(numberPart) > 1 ? _magnitudesPlural[orderOfMagnitude] : _magnitudesSingular[orderOfMagnitude];

    return result;
  }

  private string TwoDigitsToText(string twoDigits)
  {
    string result = string.Empty;
    int value = int.Parse(twoDigits);

    if (twoDigits == "00")
      return string.Empty;

    if (value < 20)
      return _lessThan20[value];

    if (twoDigits[1] != '0')
      result += _magnitude1[int.Parse(twoDigits[1].ToString())] + "und";
    result += _magnitude10[int.Parse(twoDigits[0].ToString())];

    return result;
  }
}

Viel kürzer krieg ich's aufgrund der ganzen Spezialfälle nicht hin ... schon erstaunlich, wie "unregelmässig" das ist, wenn man genau hinschaut Zum Testen hab ich folgenden Code genommen:

static void Main(string[] args)
{
  NumberToTextConverter num = new NumberToTextConverter();
  int[] test = new int[] {
    0, 1, 19, 30, 99, 
    100, 201, 311, 420, 543,
    1000, 2001, 3012, 4300, 5430, 5432, 
    10000, 20001, 30012, 55555, 99200,
    100000, 200001, 333333, 550055, 444000, 333301,
    1000000, 2000001, 1234567, 5000000, 7050011, 
    10000000, 30000001, 12345678, 87654321, 1000000000, int.MaxValue };

  for (int i = 0; i < test.Length; i++)
    Console.WriteLine("{0}: {1}", test[i].ToString().PadRight(10), num.NumberToText(test[i]));

  Console.ReadLine();
}

Und die Ausgabe sieht in dem Fall so aus (ob die Spaces da jetzt überall Sinn machen, weiss ich nicht, aber das wäre ja schnell geändert - und vorgegeben war es auch nicht):
0         : Null
1         : Eins
19        : Neunzehn
30        : Dreissig
99        : Neunundneunzig
100       : Einhundert
201       : Zweihunderteins
311       : Dreihundertelf
420       : Vierhundertzwanzig
543       : Fünfhundertdreiundvierzig
1000      : Eintausend
2001      : Zweitausendeins
3012      : Dreitausendzwölf
4300      : Viertausenddreihundert
5430      : Fünftausendvierhundertdreissig
5432      : Fünftausendvierhundertzweiunddreissig
10000     : Zehntausend
20001     : Zwanzigtausendeins
30012     : Dreissigtausendzwölf
55555     : Fünfundfünfzigtausendfünfhundertfünfundfünfzig
99200     : Neunundneunzigtausendzweihundert
100000    : Einhunderttausend
200001    : Zweihunderttausendeins
333333    : Dreihundertdreiunddreissigtausenddreihundertdreiunddreissig
550055    : Fünfhundertfünfzigtausendfünfundfünfzig
444000    : Vierhundertvierundvierzigtausend
333301    : Dreihundertdreiunddreissigtausenddreihunderteins
1000000   : Eine Million
2000001   : Zwei Millionen Eins
1234567   : Eine Million Zweihundertvierunddreissigtausendfünfhundertsiebenundsechzig
5000000   : Fünf Millionen
7050011   : Sieben Millionen Fünfzigtausendelf
10000000  : Zehn Millionen
30000001  : Dreissig Millionen Eins
12345678  : Zwölf Millionen Dreihundertfünfundvierzigtausendsechshundertachtundsiebzig
87654321  : Siebenundachtzig Millionen Sechshundertvierundfünfzigtausenddreihunderteinundzwanzig
1000000000: Eine Milliarde
2147483647: Zwei Milliarden Einhundertsiebenundvierzig Millionen Vierhundertdreiundachtzigtausendsechshundertsiebenundvierzig
private Nachricht | Beiträge des Benutzers
trib
myCSharp.de - Member



Dabei seit:
Beiträge: 702

beantworten | zitieren | melden

Hallo jannemann13 ,

vorab: Getestet und für gut befunden :)
Du bist dran!

Zum Code:
Der sieht für mich vollkommen in Ordnung aus. Mir ist nur aufgefallen, dass ich mit einem Array weniger ausgekommen bin. "_magnitude1" ist ja quasi bis auf ein/eins in "_lessThan20" enthalten.

Meine Lösung:
Die Arrays:

        static string [] upTo20 = new string[]{"Null", "ein", "zwei", "drei", "vier", "fünf",
              "sechs", "sieben", "acht", "neun", "zehn", "elf",
              "zwölf", "dreizehn", "vierzehn", "fünfzehn",
              "sechzehn", "siebzehn", "achtzehn", "neunzehn"};

        static string[] ten = new string[]{"Null", "zehn", "zwanzig", "dreissig", "vierzig",
                "fünfzig", "sechzig", "siebzig", "achtzig", "neunzig"};

        static string[] singular = new string[]{"s", "tausend", "e Million", "e Milliarde",
                    "e Billion", "e Billiarde", "e Trillion", "e Trilliarde",
                    "e Quadrillion", "e Quadrilliarde"};

        static string[] plural = new string[]{" ", "tausend", " Millionen", " Milliarden",
                    " Billionen", " Billiarden", " Trillionen", " Trilliarden",
                    " Quadrillionen", " Quadrilliarden"};
Dreier-Pakete schnüren:

        private static string Speak(long number)
        {
            string result = string.Empty;
            double maxNo = Math.Pow(10, (3 * singular.Length)); //10*3*10
            if(number ≥ maxNo)
		        return "Nummer ist zu groß!!!";

            if (number == 0)
                return "null";

           //number in Dreiergruppen aufspalten:
	        int[] group = new int[(number.ToString().Length / 3)+1];
	        int i = 0;
	        while( number > 0)
            {			        
		        group[i++] = Convert.ToInt32(number % 1000);
                number = number / 1000;
	        }

            //Dreiergruppen von links nach rechts aussprechen:	        
            i = group.Length -1;
	        while(i ≥ 0)
            {
                result += SpeakTrifurcator(group[i], i) + "\n";
                i--;
	        }
            return result;
        }
Dreier-Zahlen aussprechen:


        private static string SpeakTrifurcator(int number, int position)
        {
            string result = string.Empty;
            
            if(number == 0)                
                return string.Empty;
            if (number == 1)
                return upTo20[number] + singular[position];
            
            int hundred = number / 100;
            int rest = number % 100;
            int tenth = rest / 10;
            int first = number % 10;

            //Make it speak
            if (hundred > 0)
                result += upTo20[hundred] + "hundert";
	
            //Do the rest
            if (rest > 0)
            {                
                // Sonderfall: number endet auf 01,
                // ist aber ungleich 1
                if (rest == 1)
                    result += "eins";
                else
                    if (rest < 20)
                        result += upTo20[rest];
                    else
                    {
                        if (first > 0)
                            result += upTo20[first];
                        // sage "und", wenn es Einer-
                        // und Zehneranteile vorhanden
                        if (tenth > 0 & first > 0)
                            result += "und";
                        // Zehneranteil aussprechen:
                        if (tenth > 0)
                            result += ten[tenth];
                    }
            }
            return result + plural[position];
        }
private Nachricht | Beiträge des Benutzers
jannemann13
myCSharp.de - Member

Avatar #avatar-2976.gif


Dabei seit:
Beiträge: 69

beantworten | zitieren | melden

Zitat von trib
Der sieht für mich vollkommen in Ordnung aus. Mir ist nur aufgefallen, dass ich mit einem Array weniger ausgekommen bin. "_magnitude1" ist ja quasi bis auf ein/eins in "_lessThan20" enthalten.

Ja stimmt, das hätte man noch etwas kürzen können ... wären aber wieder mehr Spezialfälle geworden
Zitat von trib
Du bist dran!

OK, der Thread deckt ja jetzt schon eine Menge ab und mir fällt grade keine wirklich neue Aufgabe ein, also machen wir doch das Naheliegende

Und nochmal rückwärts

Erstelle einen Parser, der aus einer komplett ausgeschriebenen Zahl den passenden Zahlenwert ermittelt. Das Ergebnis sollte eine Methode mit folgender Signatur sein:

int TextToNumber(string numberText);

Beispiele:
Eingabe "Eins" --> Ausgabe: 1
Eingabe "Zweiundvierzig" --> Ausgabe: 42
Eingabe "Acht Millionen Zweihundertachtunddreissigtausendvierhundertsechsundneunzig" --> Ausgabe: 8238496

Der Rahmen für die gültigen "Zahlentexte" soll auch hier wieder 0 bis 1 Milliarde umfassen, also genau wie in der letzten Aufgabe, nur eben umgekehrt. Zum Erzeugen von Testeingaben kann dann praktischerweise meine Klasse oder tribs Code verwendet werden ... Viel Spass 8)
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von jannemann13 am .

Moderationshinweis von gfoidl (17.08.2012 - 14:59)

Das ist die 100. Aufgabe :-)

private Nachricht | Beiträge des Benutzers