Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   [Java] Ziehen ohne Zurücklegen (Mastermind) (https://www.delphipraxis.net/103136-%5Bjava%5D-ziehen-ohne-zuruecklegen-mastermind.html)

Eichhoernchen 10. Nov 2007 23:12


[Java] Ziehen ohne Zurücklegen (Mastermind)
 
Ich hab in meinem Studium, die Aufgabe bekommen Mastermind zu programmieren, dabei ist es nötig eine Buchstabenfolge der Länge 4 aus 8 Zeichen zu erzeugen.
Sprich, ich hab die Buchstaben A..H und soll daraus 4 auswählen, jedoch keine doppelten, das ganze ist ja nicht schwer, jedoch bekamen wir die Einschränkung nur 4 mal die Funktion aufrufen zu dürfen, die uns einen Zufallsbuchstaben erzeugt. Das ganze habe ich auch Problemlos gelöst, jedoch bin ich mir über die Qualität des Codes nicht sicher. Da wir keine Bibliotheksfunktionen nutzen dürfen sondern nur diese eine Zufallsbuchstabenmethode, schränkt es das ganze ziemlich ein.

Ich habe die Gleichverteilung folgendermaßen programmiert:
Code:
      char[] abc = new char[8];
      char x, c;
      for(int i = 0; i <= 7; i++) {
         abc[i] = (char)(65+i);
      }
      
      String secretWord = "";
      for(int j = 0; j <= 3; j++) {
         c = abc[Zufall.zufallszeichen((char)(72 - j)) - 'A'];
         int i = 0;
         while(abc[i] != c) i++;
         x = abc[i];
         abc[i] = abc[7 - j];
         abc[7 - j] = x;
         secretWord += c;
      }
Das ganze funktioniert auch so wie es soll, jedoch benutze ich die Zufallszeichenmethode quasi als Zufallszahl, was ja nicht ganz Sinn der Sache sein kann, jedoch will mir einfach keine andere Lösung einfallen.

Danke für Tipps.

Edit: Wobei der komplette Tausch im Code natürlich nur zur Anschauung ist, es würde reichen einfach das Zeichen zu ersetzen.

Amateurprofi 11. Nov 2007 01:08

Re: [Java] Ziehen ohne Zurücklegen (Mastermind)
 
[quote="Eichhoernchen"]Ich hab in meinem Studium, die Aufgabe bekommen Mastermind zu programmieren, dabei ist es nötig eine Buchstabenfolge der Länge 4 aus 8 Zeichen zu erzeugen.
Sprich, ich hab die Buchstaben A..H und soll daraus 4 auswählen, jedoch keine doppelten, das ganze ist ja nicht schwer, jedoch bekamen wir die Einschränkung nur 4 mal die Funktion aufrufen zu dürfen, die uns einen Zufallsbuchstaben erzeugt. Das ganze habe ich auch Problemlos gelöst, jedoch bin ich mir über die Qualität des Codes nicht sicher. Da wir keine Bibliotheksfunktionen nutzen dürfen sondern nur diese eine Zufallsbuchstabenmethode, schränkt es das ganze ziemlich ein.


Hallo Eichhörnchen,

Ich würde das so lösen (in Delpi - kannst du sicher leicht umsetzen)

Delphi-Quellcode:
FUNCTION RandomCode:string;
var c:char; i,n:integer;
begin
   result:='ABCDEFGH';
   for i:=7 downto 4 do begin
      n:=Random(i)+1; // liefert eine Zahl im Bereich 1 bis i
      c:=result[i];
      result[i]:=result[n];
      result[n]:=c;
   end;
   Delete(result,1,4);
end;

alzaimar 11. Nov 2007 09:26

Re: [Java] Ziehen ohne Zurücklegen (Mastermind)
 
Ich bezweifle, das das viermalige Mischen auch statistisch gesehen eine gleichförmige Verteilung erzielt. Im Prinzip ist das schon richtig, aber ich würde auf Nummer-Sicher gehen, und den Fisher-Yates-Algorithmus vollständig implementieren.

Wenn man sich die Aufgabe aber genau anschaut, sollt ihr eure Funktion 4x aufrufen. Wenn Dich der Lehrer darauf festnageln will, dann ist die Lösung vom Amateurprofi nicht richtig, weil Du seine Funktion ja nur 1x aufrufst. :stupid:

Du müsstest Dir eine Java-Klasse bauen, die bei jedem Aufruf von 'GibMirEinenZufallsBuchstaben' einen Buchstaben zurückliefert.

Ich würde das so realisieren:
Delphi-Quellcode:
Type
  TUniqueRandomCodeGenerator = Class
  Private
    fCodesAvail : String;
  Public
    Constructor Create (aCodesAvail : String);
    Function GetNextRandomCode : Char;
  End;

Constructor TUniqueRandomCodeGenerator.Create(aCodesAvail : String);
Begin
  fCodesAvail := aCodesAvail;
End;

Function TUniqueRandomCodeGenerator.GetNextRandomCode : Char;
Var
  i : Integer;

Begin
  If Length (fCodesAvail)=0 Then
    Raise Exception.Create('No more codes available')
  Else Begin
    i := 1 + Random (Length (fCodesAvail));
    Result := fCodesAvail[i];
    System.Delete (fCodesAvail,i,1);
  End
End;
Lange Rede, kurzer Sinn: Die Funktion 'GetNextRandomCode' liefert ein zufälliges Zeichen aus dem Zeichenvorrat und löscht dieses Zeichen anschließend aus dem Vorrat. Damit kann dieses Zeichen ja nicht nochmal gezogen werden.

Amateurprofi 11. Nov 2007 12:33

Re: [Java] Ziehen ohne Zurücklegen (Mastermind)
 
Zitat:

Zitat von alzaimar
Wenn man sich die Aufgabe aber genau anschaut, sollt ihr eure Funktion 4x aufrufen. Wenn Dich der Lehrer darauf festnageln will, dann ist die Lösung vom Amateurprofi nicht richtig, weil Du seine Funktion ja nur 1x aufrufst.

Zitat:

Zitat von Eichhoernchen
... jedoch bekamen wir die Einschränkung nur 4 mal die Funktion aufrufen zu dürfen, die uns einen Zufallsbuchstaben erzeugt. ...

@alzaimar:
Ja, aber wenn man sich die Aufgabe nicht nur genau, sondern sehr genau anschaut, dann steht da

Erstens:
Die Funktion darf nur 4 mal aufgerufen werden (also nicht öfter als 4 mal).
Wenn die Funktion nur 1 mal aufgerufen wird ist diese Bedingung erfüllt.

Zweitens (und wichtiger):
Es soll nicht irgendeine Funktion nur 4 mal aufgerufen werden dürfen, sondern die Funktion, die einen Zufallsbuchstaben erzeugt.

marabu 11. Nov 2007 12:44

Re: [Java] Ziehen ohne Zurücklegen (Mastermind)
 
Hallo,

ich glaube auch, dass der Prof hier den vierfachen Aufruf nicht vorschreiben, sondern lediglich den häufigeren Aufruf mit Prüfung auf Doppelte ausschließen will - Stichwort: Urnenziehung.

Freundliche Grüße

Eichhoernchen 11. Nov 2007 12:46

Re: [Java] Ziehen ohne Zurücklegen (Mastermind)
 
ich hätte das ganze auch anders Implementiert, jedoch werden uns etwas die Hände gebunden, wir dürfen nicht alle Mittel nutzen, wir kennen (nach lernstand) z.B. noch keine Klassen und dürfen dementsprechend auch nicht mit objekten rumfriemeln. Also mein Code klappt ja, aber diese Zufall.zufallszeichen(char) ,liefert einen Zufallsbuchstaben aus dem Bereich A ... Char... das blöde ist ja nur, dass ich in der 2. Ziehung ne Wahrscheinlichkeit von 1/7 erreichen muss, also kann ich ja nicht so einfach nen Buchstaben abschneiden, falls der noch nicht gezogen wurde. Euer Code macht ja im Prinzip nichts anderes als ich auch mache, nur dass ich mir eben keine Zufallszahlen sondern nur Zufallsbuchstaben erzeugen muss, mit den gegebenen Mitteln, Zufallszahlen darf ich nicht. So wie ich das sehe habe ich ja diesen Fisher-Yates-Algorithmus implementiert.

Naja am Dienstag werde ich eine Musterlösung bekommen, da bin ich echt mal gespannt drauf.

Ps.: Doch es steht explizit im Aufgabentext, dass die Funktion: Zufall.zufallszeichen() nur maximal 4 mal aufgerufen werden darf.

DeddyH 11. Nov 2007 12:48

Re: [Java] Ziehen ohne Zurücklegen (Mastermind)
 
[Etwas OT] Java ohne Klassen? :gruebel: [/Etwas OT]

Eichhoernchen 11. Nov 2007 13:07

Re: [Java] Ziehen ohne Zurücklegen (Mastermind)
 
Zitat:

Zitat von DeddyH
[Etwas OT] Java ohne Klassen? :gruebel: [/Etwas OT]

jaaa.... ich weiß.... wir lernen eben so, dass wir erstmal funktional lernen zu Programmieren, jedem ist auch klar das Java völlig Klassenbasierend ist, wir schreiben uns ja auch jedesmal ne Klasse fürs Hauptprogramm, aber rein vom Stand des Wissen, wissen wir noch nicht was Klassen sind und dürfen deshalb auch nicht alle Möglichkeiten ausschöpfen. Das ist sehr nervig, wenn man unter Delphi das schon alles gemacht hat und sich denkt, ahh cool, ja easy Aufgabe und dann kommen sie an und ähhh... ne Array ist nicht oder Strings vergleichen.... nööö... Okay Arrays haben wir schnell am Freitag besprochen und dürfen sie auch deshalb nutzen, es ist aber schon nervig... ich verstehe auch nicht ganz das Lernschema dahinter, für Anfänger ist es aber sicher einfacher wenn alles eingeschränkt ist.

alzaimar 11. Nov 2007 20:06

Re: [Java] Ziehen ohne Zurücklegen (Mastermind)
 
Zitat:

Zitat von Amateurprofi
@alzaimar:
Ja, aber wenn man sich die Aufgabe nicht nur genau, sondern sehr genau anschaut, dann steht da

Erstens:
Die Funktion darf nur 4 mal aufgerufen werden (also nicht öfter als 4 mal).
Wenn die Funktion nur 1 mal aufgerufen wird ist diese Bedingung erfüllt.

[wortklauberei] Wenn sie nur 1x aufgerufen wird, wird sie nicht 4x aufgerufen, auch nicht 'nur 4x'. :mrgreen:
Beweis:
Delphi-Quellcode:
If CompareText ('nur 1x', 'nur 4x') = 0 Then
  Showmessage('Ja ja, Du hast Recht')
Else
  Showmessage('Tja.')
:freak:
Wenn da stünde, das die Funktion maximal 4x aufgerufen werden darf, hättest du Recht. Steht da aber nicht, bätsch. (Du siehst, mir ist langweilig)

U.. U..Und überhaupt: Die Funktion von Dir liefert nicht einen Zufallsbuchstaben, sondern gleich die ganze Lösung. Das ist gemein. :zwinker:
[/wortklauberei]

Amateurprofi 12. Nov 2007 22:28

Re: [Java] Ziehen ohne Zurücklegen (Mastermind)
 
Zitat:

Zitat von alzaimar
U.. U..Und überhaupt: Die Funktion von Dir liefert nicht einen Zufallsbuchstaben, sondern gleich die ganze Lösung. Das ist gemein.

Es mag Leute geben, die das, subjektiv vielleicht zu Recht, als gemein empfinden.
Ich, ebenfalls subjektiv empfunden, halte es für nett, weil es exakt das ist, was Eichhoernchen haben wollte nämlich quote ... eine Buchstabenfolge der Länge 4 aus 8 Zeichen zu erzeugen. Sprich, ich hab die Buchstaben A..H und soll daraus 4 auswählen, jedoch keine doppelten ... unquote.

Vielleicht können wir noch eine Diskussion über die verschiedenen Bedeutungen des Wortes "gemein" führen ?
Mal sehen wann der erste OT-Rüffel kommt.


Alle Zeitangaben in WEZ +1. Es ist jetzt 02:52 Uhr.

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