Delphi-PRAXiS
Seite 2 von 2     12   

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi Ordung muss sein (https://www.delphipraxis.net/9742-ordung-muss-sein.html)

Hansa 5. Okt 2003 11:56

Re: Ordung muss sein
 
Hehe, das war ja nur ein Häkchen. :lol: Stimmt ww fällt raus.

Zitat:

Zitat von Sharky
Ist der genannte Sohn der ältere verbleibt nur noch wm und mm dann wäre es 1/2 genauso wenn bekannt ist das er der jüngere ist.

Was im Umkehrschluß bedeutet, daß es egal ist, ob jünger oder älter. Ich wollte ein Mißverständnis ansprechen. Und zwar kursieren z.B. Listen, wie lange irgendwelche Lottozahlen nicht mehr gezogen wurden. Jetzt gibts ganz schlaue, die tippen nur die Zahlen, die am längsten nicht mehr gezogen wurden und wundern sich, daß sie keinen 6er haben. Liegt bereits ein Teilergebnis vor, z.B. ein Kind, so fängt das Spiel wieder von vorne an: beim Kind mit 50 % und beim Lotto hat jede Zahl 1:49, egal ob sie gestern erst gezogen wurde oder seit 10 Jahren nicht mehr.

negaH 5. Okt 2003 12:05

Re: Ordung muss sein
 
Zitat:

Was im Umkehrschluß bedeutet, daß es egal ist, ob jünger oder älter. Ich wollte ein Mißverständnis ansprechen. Und zwar kursieren z.B. Listen, wie lange irgendwelche Lottozahlen nicht mehr gezogen wurden. Jetzt gibts ganz schlaue, die tippen nur die Zahlen, die am längsten nicht mehr gezogen wurden und wundern sich, daß sie keinen 6er haben. Liegt bereits ein
Jetzt wird's kompliziert, denn tatsächlich muß es beim realen Lotto so sein das bestimmte Kugeln häufiger gezogen werden als andere. Denn die Ziehungsmachine ist mechanisch und verteilt die Wahrscheinlichkeiten nicht fair auf jede Kugel. Es gibt Kugeln die ganz leichte Abweichungen in ihrer Form und Gewicht gegenüber anderen habe. Man kann NICHT 100% perfekt identische Kugel herstellen. Somit wäre es logischer beim realen Lotto die Kugeln zu tippen die am häufigsten vorkommen. In einem System das elektronisch arbeitet muß man die Kugeln tippen die am wenigsten bisher vorgekommen sind. Denn, der benutzte elekronische Zufallsgenerator muß über die Dauer aller Ziehungen gesehen, eine Gleichverteilung auf alle Kugeln erzeugen. Ansonsten wäre er nämlich nicht mehr echt Zufällig !

Allerdings, bei beiden Systemen müssten absolut gleiche Umweltbedingungen herrschen. Denn diese Abweichungen sind so minimal das z.b. minimalste Temperaturschwankungen darauf Einfluß haben.

Gruß Hagen

Hansa 5. Okt 2003 12:14

Re: Ordung muss sein
 
@negaH: Jetzt hab ichs gerafft, wo der Denkfehler liegt. Die Wahrscheinlichkeiten werden tatsächlich verfälscht. Für die erste Kugel ist sie 1:49, aber die anderen Kugeln werden eventuell mehrfach gezogen und haben somit eine höhere Chance.

Nein, nein Kommando zurück. Das Ergebnis ist doch dasselbe. Irgendwie muß sich das mathematisch aufheben. Und zwar eben durch das zurücklegen der Kugel. In Deiner Formel fehlt das. Da fehlen ein paar - würde ich mal vermuten. In dem Algo verwende ich tatsächlich "Ziehung mit zurücklegen", allerdings dann mit dem Zusatz "unter Auschluß der bereits gezogenen bei nächster Ziehung". Ich vermute, daß das ein seltener Sonderfall in der Wahrscheinlichkeitstheorie ist und die genaue Formel wird nicht einfach sein. Aber für das menschliche Denken sind Wahrscheinlichkeiten irgendwie auch unlogisch. Deshalb würde mich nicht wundern, wenn es doch ein Unterschied ist. Trotzdem, die Wahrscheinlichkeit müßte gleich sein.

negaH 5. Okt 2003 15:00

Re: Ordung muss sein
 
Zitat:

Das Ergebnis ist doch dasselbe. Irgendwie muß sich das mathematisch aufheben. Und zwar eben durch das zurücklegen der Kugel. In Deiner Formel fehlt das.
Jai, hmpf...

Es fehlt aus gutem Grunde, weil eben dein Algo die Wahscheinlichkeiten verfälscht. Aber nochmal erkläre ich das nicht, denn anscheinend kann ich es keinem richtig erklären :)

Nur eines noch, berücksichtige mal die Anzahl der Aufrufe von Random() und deren Zahlenbereiche mit in der Wahrscheinlichkeitsrechnung. Erzeuge die gleichen Zufallsbedingungen mit deinem Algo. und vergleiche das Resultat der gezogenen Zahlen mit meinem Algo. Dann knetest du 49 Kugeln, malst die Zahlen von 1 bis 49 drauf, legst sie aufsteigend in eine Reihe und erzeugt per Random() den Index der herauszunehmenden Kugel. In allen drei Fällen MÜSSEN die gleichen Zahlen gezogen werden.

Gruß hagen

Billa 5. Okt 2003 15:49

Re: Ordung muss sein
 
Hallo zusammen,

nachdem ich jetzt die ganze Diskussion verfolgt habe, möchte ich dazu auch was loswerden.
Bei solchen Aufgabenstellungen sind doch wohl die Algorithmen die besten, die die "Wirklichkeit" am besten abbilden (und damit häufig am besten verstanden werden. Deshalb würde ich beim Lottoproblem eine Synthese aus den Ansätzem von Hansa und den Überlegungen von Hagen wählen:

Was passiert den da tatsächlich?

Am Anfang haben wir eine (geordnete!!!) Menge von 49 Kugeln auf dem Plastikgitter. Okay, wir erzeugen eine Liste A mit 49 Elementen. Der Einfachheit halber mit Zahlen als Bezeichnern. Da könnten nämlich auch Äpfel, Birnen oder sonstwas aufgemalt sein. Es geht hier um 49 verschiednene Symbole, und das die zählbar sind ist Zufall! (...und führt zu dem Kardinalfehler die Ordnungsnummer mit dem Wert zu verwechseln....)

Dann fallen die Kugeln in die Trommel und werden gemischt. Das können wir auch: wir erzeugen z.B. 1000 Zahlenpaare aus Zufallszahlen (1..n, n = 49) und vertauschen jeweils die Elemente der Liste A mit diesem Index.

Dann entnehmen wir die erste "Kugel" (Zufallszahl, Trunc(Random*n)+1 ), löschen das Element aus der Liste und vermindern die obere Grenze (n = n - 1).
In Liste B wird das soeben gezogene Element eingefügt. Das wird 6 mal wiederholt. Damit sind sowohl die (richtigen) Überlegungen von Hagen befriedigt, als auch die Anschaulichkeit gewahrt.

Ich würde für kleine Mengen sogar wirklich Listen (einfach verkettet) benutzen. Das letzte Element erhält als Nachfolger das erste. Dieser "Ring" kann wunderbar mit Hilfe der Indizes abgeklappert werden. Gefundene Elemente werden wirklich aus der Liste entfernt, durch die Ringstruktur gibt es keinen Überlauf. Um die Schwächen der Random-Funktion etwas abzumildern kann zu jedem Zufallswert nochmal n addiert werden. Dann "läuft" der Index einfach ein Runde länger. Die Zufallszahl sollte nur auf alle Fälle > n sein.

Beim echten Lotto wird die Liste B anschließend noch geordnet.

Und jetzt die Schwächen dieser Lösung: Wenn es sich um große Mengen handelt, dauern speziell das Mischen und die Einfüge- und Ausfüge-Operationen lange. Aber die "Lottoshow" dauert ja auch einige Minuten. Und für max 49 Elemente reicht das.

Hansa 5. Okt 2003 16:08

Re: Ordung muss sein
 
Noch ein Mit-Lottospieler. :thuimb: Ja so würde ich es, wenn es wichtig wäre, auch machen. 2 verkettete Listen, im Prinzip nur eine mit den noch zu ziehenden Zahlen. Die würde schon reichen. Und dann wirklich ein einfacher Ring. Und dann mit random (AnzahlUebrig) da rund wandern, wie bei der richtigen Lottotrommel. Die Idee ist echt lustig. Bei gezogener Kugel den next Zeiger der Vorgängerzahl einfach auf den Next der gezogenen setzen, d.h. die Kugel fällt dann echt aus der Trommel raus. :lol: hehe, so wärs wie bei der echten Fernseh-ziehung. Das wär noch ein schönes Joke-Programm.

Nur, die Diskussion war zuletzt, ob die Wahrscheinlichkeit durch meinen SET Vorschlag tatsächlich verfälscht wird und da blickt keiner außer Hagen echt durch. Ich bin mittlerweile soweit, daß es sich mathematisch nicht einfach darstellen läßt. Was ich da mache läuft wenn überhaupt auf eine unstetige Funktion hinaus. Eher nur auf eine Relation, da ich nicht nur ein y (x), sondern eher mehrere habe, durch das zurücklegen der Kugeln. Uff, es wird immer komplizierter. Was solls, besser als Kreuzworträtsel für alte Omas.

Und @Hagen: Ist deine Formel 1/49+1/48 so richtig ? Das muß doch eher 1/49*1/48 heißen bei zwei Kugeln. Da gibts doch 49*48 Möglichkeiten ? Oder hab ich mich schon wieder verhauen ?

Billa 5. Okt 2003 16:42

Re: Ordung muss sein
 
@Hansa: Deine SET-Lösung verfälscht in der Tat das Ergebnis. Aber das ist nicht so einfach ersichtlich.

Genauso wie es beim realen Lotto Einflüsse durch unterschiedliche Beschaffenheit der Kugeln gibt, ist der Algo extrem abhängig von der "Qualität" der Zufallszahlen. Dazu ein guter Tipp:

Robert Sedgewick, Algorithmen, Bonn, München, Reading 1991

Jede Lösung des Lotto-Problems die mit Zurücklegen der Kugeln operieren muß (also auch deine erste SET-Lösung), wird zwangsläufig einen negativen Einfluss haben. Man stelle sich im Umkehrschluss nur mal eine Lotto-Ziehung vor, in der der "ordnungsgemäße Ziehungsbeamte" :mrgreen: eine Kugel zurücklegen muß. Da käme zu Recht Zweifel an der "Redlichkeit" der Ziehung auf. Und Lösungen, die nach dem Motto verfahren: "Tschulligung, da muß ich eben nochmal ziehen" können theoretisch sogar dahingehend entarten, daß die Ziehung zu keinem Ende kommt: der Zufallszahlen-Generator erzeugt eine "entartete Zufallsreihe". Die Mathematik ist mir an dieser Stelle zu hoch. Selbst wenn am Ende die gleichen Wahrscheinlichkeiten herauskämen, finde ich die Evaluierung dieser Methode viel zu kompliziert. Die "Ring"-Lösung ist so schön anschaulich, daß auch jemand ohne Mathematikstudium sie nachvollziehen kann.

negaH 5. Okt 2003 16:46

Re: Ordung muss sein
 
Zitat:

Dann entnehmen wir die erste "Kugel" (Zufallszahl, Trunc(Random*n)+1 ), löschen das Element aus der Liste und vermindern die obere Grenze (n = n - 1).
In Liste B wird das soeben gezogene Element eingefügt. Das wird 6 mal wiederholt. Damit sind sowohl die (richtigen) Überlegungen von Hagen befriedigt, als auch die Anschaulichkeit gewahrt.
Viele Postings zurück hier im Thread habe ich zur "Beweisführung" meinen Code mit genau dieser Methode erweitert. Allerdings man muß dabei NICHT die Liste vermischen, sondern es reicht aus der immer sortierten Liste per Zufallsindex eine Kugel herauszunehmen. Denn, entweder wird die Liste immer gemischt und an einem festen Index < 45 eine Kugel herausgenommen, oder aber die Liste wird nie gemischt und dafür per Zufallsindex eine Kugel entnommen. Beides führt aus Sicht der Wahrscheinlichkeiten zum selben Resultat. Es darf NICHT die Liste gemischt werden und per Zufallsindex eine Kugel entnommen werden !! Dies würde zwei Wahrscheinlichkeiten kummulieren.


Zitat:

Ist deine Formel 1/49+1/48 so richtig ? Das muß doch eher 1/49*1/48 heißen bei zwei Kugeln. Da gibts doch 49*48 Möglichkeiten ? Oder hab ich mich schon wieder verhauen ?
1/49, 1/48, 1/47, 1/46, 1/45, 1/44 sind die Wahrscheinlichkeiten pro Zug und pro Kugel.
Somit beträgt die Gesamtwahrscheinlichkeit das eine Kugel in den 6 Ziehungen gezogen wird,
6/279 = 1/46,5 meiner Meinung nach.

Da aber selbst mich die ganzen Diskussionen verwirren, werde ich erstmal meine schlauen Bücher befragen müssen.

Gruß Hagen

Hansa 5. Okt 2003 17:33

Re: Ordung muss sein
 
Zitat:

Zitat von negaH
...Da aber selbst mich die ganzen Diskussionen verwirren, werde ich erstmal meine schlauen Bücher befragen müssen...

:mrgreen:

Das mit dem mischen der Zahlen ist überflüssig. Das passiert ja durch das random. Und durch den Ring kann es theoretisch auch mit random (10000) passieren. Dann dreht sich die "richtige" Lottokugel eben den ganzen Tag. Das ganze geht dann ähnlich wie bei einem Glücksrad.

Ich glaube aber, daß einige hier nicht wissen, was ein Ring ist. Das ist eine verkettete Liste, bei der zum Schluß das Ende einen Zeiger auf den Anfang hat. Wenn ich nun mit random (100) arbeite kann ich ganz einfach durch
Delphi-Quellcode:
r := random (100);
for i := 1 to r do begin
  vorgaenger := ring;
  ring := ring^.naechst;
end;
die Position in dem Ring um r Positionen verschieben. Angenommen ich stehe am Anfang auf der 1, dann würde, falls r 48 ergibt die Zahl 49 gezogen. Diese müßte mit dispose oder zumindest umhängen der Zeiger, (wofür man noch ein paar Hilfsvariable bräuchte) aus dem Ring rausgenommen werden. Dieser hätte dann noch 48 Elemente. usw.

Die Datenstruktur wäre ziemlich simpel:

Delphi-Quellcode:
type RingTyp       = ^RingZeigerTyp;

      RingZeigerTyp = RECORD
                         wert : byte;
                         naechst : RingTyp;
                       END;
var RingVar,
    Vorgaenger : RingTyp;
    GezogeneKugel : byte;
Bei einer gezogenen Kugel müßte man nur folgendes machen:

Delphi-Quellcode:
GezogeneKugel := RingVar^.wert;
Vorgaenger^.naechst := RingVar.naechst^; // gezogene Kugel aus Ring nehmen
Vorgaenger := RingVar;
RingVar := RingVar^.naechst;
Vorgaenger als Hilfsvariable müßte halt immer mitgeschleppt werden. Hmmm, kann das da so stimmen ? :gruebel:

Billa 6. Okt 2003 06:42

Re: Ordung muss sein
 
...hmm, meine Lösung für das Vorgänger-Problem sähe so aus:

Wie vorher schon mal beschrieben, einfach n (Anzahl Kugeln) zur Zufallszahl addieren, und (um den Vorgänger bequem zu erreichen, die Zufallszahl um 1 vermindern. Dann bleibt der Zeiger auf dem gewünschten Ringeintrag "stehen".... Ansonsten scheint mir die Struktur und das Vorgehen ok....

negaH 6. Okt 2003 14:28

Re: Ordung muss sein
 
Die Idee von Hansa über eine verlinkte Liste zu arbeiten ist gut.
Allerdings benötigt man keinen "Ring" oder eine verlinkte Liste über zB. 49 Kugeln.
Ich habe meinen Algorithmus dahingehend umgeschrieben damit er mit einer verlinkten Liste arbeitet. Dies optimiert nochmals den vorher beschriebenen Algorithmus, da nun das sortierte Einfügen der gezogenen Kugeln ohne Kopieroperationen auskommt. D.h. Speicherzugriffsmäßig gesehen ist der Algo. nun effizienter.

Delphi-Quellcode:
type
  PKugel = ^TKugel;
  TKugel = packed record
    Wert: Integer;               // Zahlenwert der Kugel
    Naechste: PKugel;            // nächsthöhere Kugel
  end;

  TKugeln = array of TKugel;

function Lotto(var Kugeln: TKugeln; Ziehungen: Integer = 6; Elemente: Integer = 49): PKugel;
// Lotto-Ziehung, korrekte Simulation der Wahrscheinlichkeiten einer realen Lotto-Ziehung
// Dieser Algo. vermeidet das Umsortierung und somit Kopieren im Speicher über die Nutzung
// einer verlinkten Liste von Kugeln.
var
  I,Index: Integer;
  Erste: PKugel;            // Wurzel der verlinkten Liste, erstes sortiertes Element
  Naechste: PKugel;         // aktuell untersuchtes Element
  Vorherige: PKugel;        // vorheriges Element von Aktuelle
begin
  Kugeln := nil;
  if Ziehungen > Elemente then
    raise Exception.Create('Man kann nicht mehr Kugeln ziehen als in der Urne sind');

  Erste := nil;
  SetLength(Kugeln, Ziehungen);
  for I := 0 to Ziehungen -1 do
  begin
 // ziehe Index der Kugel aus Urne, 1 basierter Index
    Index := Random(Elemente) +1;
    Dec(Elemente);
 // berechne Zahlenwert der Kugel mit Index
    Vorherige := nil;
    Naechste := Erste;
    while (Naechste <> nil) and (Index >= Naechste.Wert) do
    begin
      Inc(Index);
      Vorherige := Naechste;
      Naechste := Naechste.Naechste;
    end;
 // trage Kugel in Kugeln ein und aktualisiere die sortierte verlinkte Liste
    Kugeln[I].Wert := Index;
    Kugeln[I].Naechste := Naechste;
    if Vorherige <> nil then Vorherige.Naechste := @Kugeln[I]
      else Erste := @Kugeln[I];
  end;
  Result := Erste;
end;

procedure TestLotto;
var
  Kugeln: TKugeln;
  Kugel,Erste: PKugel;
  I: Integer;
begin
  Erste := Lotto(Kugeln, 6, 49);

// Ausgabe
  Write('gezogene : ');
  for I := Low(Kugeln) to High(Kugeln) do
    Write(Kugeln[I].Wert:4);
  WriteLn;

  Write('sortiert : ');
  Kugel := Erste;
  while Kugel <> nil do
  begin
    Write(Kugel.Wert:4);
    Kugel := Kugel.Naechste;
  end;
  WriteLn;
end;
Gruß Hagen

PS: die Moderatoren sollten nun diesen Thread auf's Wesentliche zusammenstreichen und in der CodeLib veröffentlichen. Denn in spätesten 3-4 Wochen kommt diese Frage wieder.

Billa 6. Okt 2003 15:00

Re: Ordung muss sein
 
@Hagen:

1. Du hast Recht: Mischen muß man nicht mehr, das wäre genauso verfälschend, wie es das "Zurücklegen" der Kugel wäre.

2. Ich glaube, die "Ring"-Idee ist von mir ?! :mrgreen: Aber ok, ok Hansa hats's codiert!

@Mods: Ja bitte: das gehört bestimmt in die CodeLib. Man denke nur an andere (bereits erwähnte) Fallstellungen: Kartenspiele, "Abzählreime" u.a.

negaH 6. Okt 2003 15:24

Re: Ordung muss sein
 
Zitat:

1. Du hast Recht: Mischen muß man nicht mehr, das wäre genauso verfälschend, wie es das "Zurücklegen" der Kugel wäre.
Nich ganz. Man kann sehr wohl eine Liste von 49 Zahlen erzeugen. Diese Liste wird gemischt und das 1. Element wird aus der Liste entfernt.
Nun sind 48 Elemente in der Liste. Die Liste wird erneut gemischt und das 1. Element wird entfernt.
Nun 47 Elemente mischen und 1. entfernen, usw. usw.
Wichtig ist nur das
1.) die Anzahl der Elemente nach rausnehmen reduziert wird
2.) das immer an festem Index das Element gezogen wird
3.) das nach dem Ziehen die Liste immer wieder neu gemischt wird
4.) das das Mischen der Liste die Anzahl der Elemente in der Liste berücksichtig, also man berechnet bei einer Liste mit 46 Elemente zwei Indexe mit Random(46) und tauscht diese aus.
Man darf NICHT bei einer Liste mit 46 Elemente per Random(49) diese Indexe berechnen. Eigentlich logisch, da Random(46) eben mit 1/46 Wahrscheinlichkeit eine Zahl aus 0 bis 45 erzeugt.

Zitat:

2. Ich glaube, die "Ring"-Idee ist von mir ?! Aber ok, ok Hansa hats's codiert!
Sorry, da Hansa immer wieder sehr gerne mit verlinkten Listen und Zeigern arbeitet, dachte ich es käme von ihm :)

Gruß Hagen

Billa 7. Okt 2003 06:43

Re: Ordung muss sein
 
...Full Ack... :thuimb:

Hansa 7. Okt 2003 20:23

Re: Ordung muss sein
 
Toll, wenn die Urheber schon klar sind und keiner was macht. Das hier soll ein Ring werden, aber irgendwo ist ein Fehler:

Delphi-Quellcode:
procedure VorLottoZiehung; // Lottotrommel mit 49 Kugeln füllen
var i : byte;
    neu : PKugel;
begin
  anfang := nil;
  i := 1;
  new (neu);
  neu^.wert := i;
  neu^.naechst := anfang;
  anfang := neu;
  kugel := anfang;
  for i := 2 to MaxKugeln do begin
    new (neu);
    neu^.wert := i;
    neu^.naechst := kugel;
    new (kugel);
    kugel := neu;
  end;
  new (ende);                   // verkettete Liste ist fertig
  ende := kugel;
  ende^.naechst := anfang;      // jetzt ist der Kreis geschlossen !!
end;
Muß ein dummer Fehler sein. Auf Anhieb sehe ich ihn aber nicht. Wer wollte den Ring noch bauen ? Dürfte einfach zu finden sein, aber ich habe mich jetzt verhackstückelt.

Und so wollte ich mal die "sich drehende Lottotrommel" simulieren (vorerst sortiert) :

Delphi-Quellcode:
procedure KugelnPruefen (e : integer); // Ziehungsbeamter, haha
var i,
    ElementeWeiter : integer;
begin
  randomize;
  Kugel := anfang;
  while kugel <> ende do begin
    form1.memo2.Lines.Add(IntToStr (Kugel^.wert));
    Kugel := Kugel^.naechst;
  end;
end;
Ich vermute mal, mit dem anfang und dem ende, da stimmt was nicht.

axelf98 20. Okt 2003 22:43

Re: Ordung muss sein
 
Meine Lösung für das Problem:

Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var i     :   integer;
    X     :   Cardinal;
    S     :   String;
    Zahlen :   Array[1..6] of Cardinal;
    Wahr  :   Array[1..49] of Boolean;
begin

  Randomize;

  for i := 1 to 6 do
  begin
   Repeat X := Random(49) + 1  until not Wahr[X];
   Zahlen[i] := X;
   Wahr[X] := true;
  end;
 
  for i := 1 to 6 do S := S + '  ' + inttostr(Zahlen[i]);
  edit1.Text := S;  // Ausgabe

end;

negaH 20. Okt 2003 23:51

Re: Ordung muss sein
 
Zitat:

(M)keine Lösung für das Problem:
Hast du wirklich die Positings in diesem Thread gelesen ?

Hansa 20. Okt 2003 23:55

Re: Ordung muss sein
 
hat er nicht. :mrgreen:

Billa 21. Okt 2003 08:32

Re: Ordung muss sein
 
Hallo zusammen,

@negaH: Sorry, aber ich hatte wirklich viel zu tun und war ein paar Tage nicht up-to-date.... :oops:

Hier ist jetzt meine kleine "Spontanlösung". Die hat sicherlich noch reichlich Mängel, und ich habe nicht alle Eure Postings berücksichtigt. Aber sei's drum:

Code:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Memo1: TMemo;
    procedure Button1Click(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

const
  MaxKugeln = 49;

type
  PElement = ^TElement;
  TElement = record
            Wert : integer;
            Text : string;
            Next : PElement;
          end;

var
  Anfang : PElement;
  AnzKugeln : Integer;

procedure RingErzeugen( var Anfang : PElement; var AnzElemente : Integer; MaxElemente : integer );
var
  i : integer;
  Element : PElement;
begin

  // 1.Element auf alle Fälle erzeugen erzeugen
  try
    New( Anfang );
    with Anfang^ do
    begin
      Wert := 1;
      Text := IntToStr( Wert ); // beliebig, aber beim Lotto eben ein Zahlensymbol
      New( Next );
      Next := Anfang;  // Ring schließen
    end;
    AnzElemente := 1;
  except
  end;

  // falls erfolgreich, folgende Elemente erzeugen und in den Ring "einklinken"
  if AnzElemente = 1 then
  for i := 2 to MaxElemente do
  begin
    try
      New( Element );    //erzeugen
      with Element^ do
      begin
        Wert := i;
        Text := IntToStr( Wert );  // benennen
        New( Next );
        Next := Anfang^.Next;  // Ring schließen
      end;
      Anfang^.Next := Element;
      Inc( AnzElemente );
    except
    end;
  end;
  // kleiner "Schönheitsfehler": die Reihe ist absteigend geordnet, aber es müssen ja
  // keine Zahlen sein...
end;

procedure EntnehmeElement( var Anfang : PElement; var Ergebnis : TElement; var AnzElemente : integer );
var
  Hilfszeiger : PElement;
  i,
  Zufallszahl : Integer;
begin
  if AnzElemente <> 0 then
  begin

    // Es ist nützlich, nicht das gesuchte Element,
    // sondern seinen Vorgänger zu finden, da sonst
    // wegen der einfachen Verkettung der Vorgänger
    // mühsam gesucht werden müsste ...
    // ( also nicht wie üblich Random(X)+1 )
    // ...und damit sich auf jeden Fall etwas "bewegt"
    // wird einfach die Anzahl der Elemente addiert.
    // Das ist beim Durchlaufen des Rings neutral.
    // ( und nur Spielerei )
    Zufallszahl := Random( AnzElemente ) + AnzElemente;

    // bewege den Zeiger zum ausgelosten Element
    for i := 1 to Zufallszahl do
      Anfang := Anfang^.Next;
    // Wert zuweisen
    Ergebnis := Anfang^.Next^;

    // Element aus dem Ring entfernen
    Hilfszeiger := Anfang^.Next;
    Anfang^.Next := Hilfszeiger^.Next;
    try
      Dispose( Hilfszeiger );
      Dec( AnzElemente );
    except
    end;

  end;
end;


procedure TForm1.Button1Click(Sender: TObject);
var
  Run : integer;
  Ergebnis : TElement;
begin

  // Vorbereitung
  Randomize;
  Memo1.Lines.Clear;

  // Aufbauen ....
  RingErzeugen( Anfang, AnzKugeln, MaxKugeln );

  // Lotto spielen ....
  for Run := 1 to 7 do
  begin
    EntnehmeElement( Anfang, Ergebnis, AnzKugeln );
    Memo1.Lines.Add( Ergebnis.Text );
  end;

  // Abräumen ....
  while AnzKugeln > 0 do
    EntnehmeElement( Anfang, Ergebnis, AnzKugeln );

end;

end.
...und jetzt werden die Bestien mich zerreissen... :mrgreen:

axelf98 21. Okt 2003 09:17

Re: Ordung muss sein
 
Na dann eben nicht!

Billa 21. Okt 2003 09:29

Re: Ordung muss sein
 
@axelf98: an wen geht das? Oder hast Du ein Problem mit dem Source???

Schubi 2. Mär 2004 08:12

Re: Ordung muss sein
 
Nochmal zum Problem mit dem Bruder:
Wenn da steht 2 Kinder, eines ist ein Männlein. Muss das andere dann nicht zwangsläufig weiblich sein? :gruebel: :mrgreen: :wall:


Alle Zeitangaben in WEZ +1. Es ist jetzt 15:31 Uhr.
Seite 2 von 2     12   

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz