C# :: Aufgabe #167 :: Lösung #1

8 Lösungen Lösungen öffentlich
#167

Der Leidensweg eines Betrunkenen durch einen Tunnel

Anfänger - C# von hollst - 07.03.2017 um 09:40 Uhr
Ein leicht angetrunkener Mann muss für seinen Nachhauseweg durch einen Tunnel der Länge L (z. B. = 10 m)
und der Breite B (z. B. = 5.5 m). Zum Glück ist der Tunnel mit quadratischen Terrazzoplatten ausgelegt, nach denen
er sich zu richten versucht. Die Platten haben eine Gräße von 0.5 x 0.5 m². Somit besteht der Weg aus hier z. B. 20 Reihen a 11 Platten.

Der Mann startet in der ersten Reihe auf der Mittelplatte. Er möchte durch den Tunnel gehen, indem er bei jedem
Schritt auf eine benachbarte Platte tritt. Leider hat er in seinem Zustand völlig die Richtungsorientierung verloren,
so dass sein Schritt rein zufällig in eine der acht möglichen Richtungen verläuf, unabhängig davon,
dass zwei Wände links und rechts den Weg versperren. Wenn der Mann gegen eine der Wände läuft, gilt sein Versuch
den Tunnes zu durchlaufen als gescheitert, da er bewußtlos zu Boden stürzt und liegen bleibt. Als gescheiterter Versuch gilt auch,
wenn sein Weg ihn nicht zum Tunnelausgang, sondern nach einigen Schritten oder schon bereits beim ersten zurück vor den Eingang führt.

Die Frage lautet: Wie groß ist die Wahrscheinlichkeit dafür, dass er den Tunnel mit einem einzigen Versuch schadlos durchquert?
Die Wahrscheinlichkeit (Erwartungswert) soll anhand genügend vielen Simulationen abgeschätzt werden.
#1
vote_ok
von daniel59 (4260 Punkte) - 09.03.2017 um 11:48 Uhr
Quellcode ausblenden C#-Code
using System;
using System.Collections.Generic;
using System.Linq;

namespace ConsoleBetrunkenDurchDenTunnel
{
    class Program
    {
        static readonly Random rnd = new Random();
        static void Main(string[] args)
        {
            double plateSize = 0.5;
            double length = 10;
            double width = 5.5;

            Console.Write("Wie lang ist der Tunnel? ");
            string s = Console.ReadLine();
            if (!double.TryParse(s, out length))
            {
                Console.WriteLine("\"{0}\" ist keine gültige Längenangabe", s);
                Console.ReadLine();
                return;
            }
            Console.Write("Wie breit ist der Tunnel? ");
            s = Console.ReadLine();
            if (!double.TryParse(s, out width))
            {
                Console.WriteLine("\"{0}\" ist keine gültige Längenangabe", s);
                Console.ReadLine();
                return;
            }
            Console.Write("Wie groß sind die quadratischen Platten? ");
            s = Console.ReadLine();
            if (!double.TryParse(s, out plateSize))
            {
                Console.WriteLine("\"{0}\" ist keine gültige Größenangabe", s);
                Console.ReadLine();
                return;
            }
            int trys = 10000000;
            Console.Write("Wie viele Versuche sollen gezählt werden? ");
            s = Console.ReadLine();
            if (int.TryParse(s, out trys))
            {
                if (trys <= 0)
                {
                    Console.WriteLine("Der Anzahl muss größer 0 sein");
                    Console.ReadLine();
                    return;
                }
            }
            else
            {
                Console.WriteLine("\"{0}\" ist keine gültige Angabe", s);
                Console.ReadLine();
                return;
            }

            double temp = length / plateSize;
            int platesY = temp % 1 == 0 ? (int)temp : (int)temp + 1;
            temp = width / plateSize;
            int platesX = temp % 1 == 0 ? (int)temp : (int)temp + 1;


            int success = 0;
            List<int> moves = new List<int>();
            for (int i = 0; i < trys; i++)
            {
                int m = 0;
                if (Simulate(platesX, platesY, out m))
                {
                    success++;
                    moves.Add(m);
                }
            }

            double p = (double)success / (double)trys;
            double avgMoves = moves.Average();

            Console.WriteLine("\nDie Wahrscheinlichkeit unbeschadet durch den Tunnel zu kommen beträgt {0}%", p * 100);
            Console.WriteLine("Durchschnittlich werden {0} Schritte benötigt", avgMoves, 2);
            Console.WriteLine("Min: {0}\tMax: {1}", moves.Min(), moves.Max());
            Console.ReadLine();
        }

        static bool Simulate(int platesX, int platesY, out int moves)
        {
            int posY = 0;
            int posX = platesX / 2;//Start in der Mitte
            int borderL = -1;
            int borderR = platesX;
            moves = 1;

            while (true)//posY < platesY && posX != borderL && posX != borderR)
            {
                switch (rnd.Next(0, 8))
                {
                    case 0://Geradeaus
                        posY++;
                        break;

                    case 1://Geradeaus links
                        posY++;
                        posX--;
                        break;

                    case 2://Geradeaus rechts
                        posY++;
                        posX++;
                        break;

                    case 3://links
                        posX--;
                        break;

                    case 4://rechts
                        posX++;
                        break;

                    case 5://Zurück
                        posY--;
                        break;

                    case 6://Zurück Links
                        posY--;
                        posX--;
                        break;

                    case 7://Zurück rechts
                        posY--;
                        posX++;
                        break;
                }
                if (posY == platesY)
                {
                    return true;
                }
                else if (posX == borderL || posX == borderR || posY < 0)
                {
                    return false;
                }
                moves++;
            }
        }
    }
}

Kommentare:

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

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