C# :: Aufgabe #272 :: Lösung #1
3 Lösungen

#272
Das Problemspiel der spagetti-essenden Philosophen
Anfänger - C#
von hollst
- 04.12.2019 um 18:44 Uhr
wiki
https://de.wikipedia.org/wiki/Philosophenproblem
Fünf Philosophen sitzen um einen runden Tisch, vor jedem ein Teller voll mit Spagetti und links davon eine Gabel (BILD 1).
Um von dem Teller Spagetti essen zu können, benötigt man allerdings zwei Gabeln. Die zweite Gabel kann man sich von seinem
rechten Nachbarn borgen, sofern dieser nicht gerade selber beim Essen ist. Außerdem sollte man seine eigene Gabel auch nicht gerade
an seinen linken Nachbarn verborgt haben.
Das Spiel beginnt beim ersten Philosophen und geht Schritt für Schritt wie folgt reihum:
Jeder Philosoph kann sich in einem von drei möglichen Zuständen befinden,
u. z. denkend (Zustand 1, zu Beginn alle fünf Philosophen), hungernd (2) oder essend (3).
Ein denkender Philosoph kann per Zufallsentscheidung entweder in diesem Zustand 1 verweilen (dann geht der Zeiger sofort weiter an
seinen rechten Nachbarn) oder sich für "Essenwollen" entscheiden (Übergang von Zustand 1 in Zustand 2). In diesem Fall muss er prüfen,
ob ihm zwei Gabeln zur Verfügung stehen. Wenn Ja geht er von Zusand 2 in den Zustand 3 über und kann (sagen wir) zwei [Variable E wie Essen] Runden lang essen. Nach den zwei [E] Runden wird er zunächst wieder zum denkenden Philosophen (Zustand 1), der geleerte Teller wird sofort wieder aufgefüllt, falls der Philosoph erneut Hunger bekommt.
Hat er allerdings keine zwei Gabeln zur Verfügung, bleibt er die Runde hungrig (er verharrt im Zustand 2). Bekommt ein Philosoph
(sagen wir) zehn [Variable T wie Tod] Runden lang hintereinander nichts zu essen, ist er verhungert und das Gelage auch zu ende.
Die Frage lautet, nach wie vielen Runden (abhängig von E und T) ist im Durchschitt der erste Philosoph verhungert. Viel Spaß!
https://de.wikipedia.org/wiki/Philosophenproblem
Fünf Philosophen sitzen um einen runden Tisch, vor jedem ein Teller voll mit Spagetti und links davon eine Gabel (BILD 1).
Um von dem Teller Spagetti essen zu können, benötigt man allerdings zwei Gabeln. Die zweite Gabel kann man sich von seinem
rechten Nachbarn borgen, sofern dieser nicht gerade selber beim Essen ist. Außerdem sollte man seine eigene Gabel auch nicht gerade
an seinen linken Nachbarn verborgt haben.
Das Spiel beginnt beim ersten Philosophen und geht Schritt für Schritt wie folgt reihum:
Jeder Philosoph kann sich in einem von drei möglichen Zuständen befinden,
u. z. denkend (Zustand 1, zu Beginn alle fünf Philosophen), hungernd (2) oder essend (3).
Ein denkender Philosoph kann per Zufallsentscheidung entweder in diesem Zustand 1 verweilen (dann geht der Zeiger sofort weiter an
seinen rechten Nachbarn) oder sich für "Essenwollen" entscheiden (Übergang von Zustand 1 in Zustand 2). In diesem Fall muss er prüfen,
ob ihm zwei Gabeln zur Verfügung stehen. Wenn Ja geht er von Zusand 2 in den Zustand 3 über und kann (sagen wir) zwei [Variable E wie Essen] Runden lang essen. Nach den zwei [E] Runden wird er zunächst wieder zum denkenden Philosophen (Zustand 1), der geleerte Teller wird sofort wieder aufgefüllt, falls der Philosoph erneut Hunger bekommt.
Hat er allerdings keine zwei Gabeln zur Verfügung, bleibt er die Runde hungrig (er verharrt im Zustand 2). Bekommt ein Philosoph
(sagen wir) zehn [Variable T wie Tod] Runden lang hintereinander nichts zu essen, ist er verhungert und das Gelage auch zu ende.
Die Frage lautet, nach wie vielen Runden (abhängig von E und T) ist im Durchschitt der erste Philosoph verhungert. Viel Spaß!
#1

von DanielWagner (220 Punkte)
- 14.12.2019 um 21:39 Uhr

enum Zustand { denkend, essend, hungernd } class Philosoph { public static List<Philosoph> AllePhilosophen = new List<Philosoph>(); public int Id; public string Name; public Enum Zustand { get; set; } public bool IsAlive; public int RundeBisZumTod; public int EssensRunden; public Philosoph(int id, string name, Enum zustand, bool isAlive) { Id = id; Name = name; Zustand = zustand; IsAlive = isAlive; AllePhilosophen.Add(this); } } class Program { static Random rand = new Random(); static void Main(string[] args) { new Philosoph(1, "Philosoph 1", Zustand.denkend, true); new Philosoph(2, "Philosoph 2", Zustand.denkend, true); new Philosoph(3, "Philosoph 3", Zustand.denkend, true); new Philosoph(4, "Philosoph 4", Zustand.denkend, true); new Philosoph(5, "Philosoph 5", Zustand.denkend, true); bool schalter = true; int round = 0; while (schalter) { foreach(Philosoph p in Philosoph.AllePhilosophen) { // wenn er nicht beim essen schon ist if (!p.Zustand.Equals(Zustand.essend)) { // zustand per Zufall wählen p.Zustand = (Zustand)rand.Next(2); // Console.WriteLine(p.Zustand); // zustand überprüfen, wenn essend dann weiter zum essen, sonst nächster Philosoph if (p.Zustand.Equals(Zustand.essend)) { // prüfen ob zwei Gabel zur Verfügung stehen bool GabelFrei = false; if (p.Id == Philosoph.AllePhilosophen.Count) { if (!Philosoph.AllePhilosophen[0].Zustand.Equals(Zustand.essend)) { p.Zustand = Zustand.essend; GabelFrei = true; } } else { if (!Philosoph.AllePhilosophen[p.Id].Zustand.Equals(Zustand.essend)) { p.Zustand = Zustand.essend; GabelFrei = true; } } // wenn true -> essensrunde auf 2 setzen if (GabelFrei) { p.EssensRunden = 2; } // wenn false -> RundeBisZumTod++ else { p.Zustand = Zustand.hungernd; p.RundeBisZumTod++; } } } // sonst wenn er beim essen ist else if(p.Zustand.Equals(Zustand.essend)) { // essensrunde-- p.EssensRunden--; if(p.RundeBisZumTod > 0) p.RundeBisZumTod--; // wenn essensrunde == 0 if (p.EssensRunden == 0) { // zustand auf denkend und RundenBisZumTod auf 0 setzen p.Zustand = Zustand.denkend; } } // prüfen ob RundeBisZumTod == 10 ist, denn IsAlive == false if (p.RundeBisZumTod == 10) { p.IsAlive = false; } } // überprüfen ob ein Philosoph ist schon verhungert, damit wird schleife beendet Philosoph.AllePhilosophen.ForEach(p => { if (!p.IsAlive) { schalter = false; } }); // Rounds round++; // Test Console.WriteLine("Round " + round); Philosoph.AllePhilosophen.ForEach(p => { Console.WriteLine(p.Name + " Zustand: " + p.Zustand + ", Essensrunden: " + p.EssensRunden + " Runde bis zum Tod: " + p.RundeBisZumTod + ", ist am Leben? - " + p.IsAlive); }); } // Ausgabe Philosoph.AllePhilosophen.ForEach(p => { Console.WriteLine($"Round {round}"); Console.WriteLine(p.Name + ", ist am Leben? - " + p.IsAlive); }); Console.ReadKey(); } }
Kommentare:
Für diese Lösung gibt es noch keinen Kommentar
Seite 1 von 0
1