PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : 6 aus 49 programmieren:



axeljaeger
07-05-2004, 16:47
Wir haben heute im Informatikunterricht die schöne Aufgabe bekommen, ein Programm zu schreiben, das die Lottozahlen ziehen soll: Also 6 zufällige Zahlen aus dem Zahlenraum von 1 - 49. Das schwierige ist ja nur, dass man keine doppelten Zahlen hinterher in der Lösung hat. Ich hab da einen Ansatz, weis aber noch nicht, ob der der Weisheit letzter Schluss ist, es soll möglichst elegant programmiert sein. Ich hab die Musterlösung gesehen und da waren es dann 6 Ifs hintereinander. Hier ist also mein Lösungsvorschlag in Java geschrieben:



import java.applet.Applet;
import java.awt.*;
import java.awt.event.*;

public class Lotto extends Applet implements ActionListener {
int feld[] = new int [6];
TextArea ta = new TextArea (10, 20);

Button bu = new Button("Ziehe Zahlen");

public void init () {
add(bu);
add(ta);
bu.addActionListener(this);
}

public void actionPerformed(ActionEvent e) {
for (int i = 0; i < 6; ++i) {
int nzahl = (int) Math.ceil(Math.random() * 49);
while (alreadyInArray(nzahl, i)) {
nzahl = (int) Math.ceil(Math.random() * 49);

}
feld[i] = nzahl;
}
ta.append("Ziehung der Lottozahlen: \n");
for (int i = 0; i < 6; ++i) {
ta.append("Die " + (i+1) + ". Zahl ist " + feld[i] + "\n");
}
}

boolean alreadyInArray(int zahl, int until) {
for (int i = 0; i <= until; ++i) {
if (feld[i] == zahl) {
return true;
}
}
return false;
}
}

wraith
07-05-2004, 17:10
C++


#include <algorithm>
#include <iostream>
#include <iterator>
#include <cstdlib>
#include <ctime>

using namespace std;

int lottorand(int)
{
return rand() % 50;
}

int main()
{
int array[49];
for(int i = 0;i < 49;i++)
array[i] = i + 1;

srand(time(NULL));
random_shuffle(array,array + 49,lottorand);

copy(array,array + 6,ostream_iterator<int>(cout,","));
}

axeljaeger
07-05-2004, 17:28
Damit ich das richitig verstehe: Du machst erst ein Array mit den Zahlen von 1 - 49, dann mischst du das Array und nimmst dann die ersten 6 Zahlen? Weis jmd. ob es so eine Funktion auch in Java gibt? Wenn sollen wir die zwar nicht benutzten, ich bin aber sehr an einer kurzen "genialen" Lösung interessiert.

wraith
07-05-2004, 17:33
Original geschrieben von axeljaeger
Damit ich das richitig verstehe: Du machst erst ein Array mit den Zahlen von 1 - 49, dann mischst du das Array und nimmst dann die ersten 6 Zahlen?

Genau.


Weis jmd. ob es so eine Funktion auch in Java gibt?
Im Collections Framework gibt es AFAIK eine statische Methode shuffle(List).

axeljaeger
07-05-2004, 17:37
Original geschrieben von wraith

Im Collections Framework gibt es AFAIK eine statische Methode shuffle(List).
Ob es das auch für Arrays gibt? Selber programmieren wird man ja sowas schlecht können von wegen echt zufälliger Verteilung und so.

wraith
07-05-2004, 17:41
Original geschrieben von axeljaeger
Selber programmieren wird man ja sowas schlecht können von wegen echt zufälliger Verteilung und so.
Das hängt nur von der Zufallsfunktion ab.
Die Implementierung von std::random_shuffle sieht zb. so aus (gnu)


template<typename _RandomAccessIter, typename _RandomNumberGenerator>
void
random_shuffle(_RandomAccessIter __first, _RandomAccessIter __last,
_RandomNumberGenerator& __rand)
{
if (__first == __last) return;
for (_RandomAccessIter __i = __first + 1; __i != __last; ++__i)
iter_swap(__i, __first + __rand((__i - __first) + 1));
}

Doch recht simpel.

fs111
07-05-2004, 17:50
Vom Codestyling würde ich in die ActionPerformed nie so viel Code packen, sondern lieber eine Methode aufrufen, das IMHO übersichtlicher.

fs111

axeljaeger
07-05-2004, 18:08
Ja, da hast Du recht, das sollte ich sauberer ausführen. Aber wahrscheinlich ist es so schon zu kompliziert, ich weis jetzt schon nicht, wie ich das schaffen soll, das so zu erklären, dass es jeder im Kurs versteht.

fs111
08-05-2004, 10:43
Oh weia, das spricht natürlich nicht gerade für das Nivuea des Kurses...

fs111

axeljaeger
08-05-2004, 11:04
Meine Version ist noch verbesserungswürdig: Wenn ich anstatt while do..while nehme, brauch ich die Math.ceil (...) Zuweisung nur einmal. Aber das Kursnniveau lässt sehr zu wünschen übrig: Die sehnen sich nach Delphi mit dem GUI-Builder.

fs111
08-05-2004, 11:43
Wenn wir schon ans optimieren gehen, dann solltest Du auch mal Deine imports sortieren, und nur das importieren, was Du auch wirklich benutzt.

fs111

axeljaeger
08-05-2004, 13:24
Dann müsste ich ja auch erklären, was ich da gemacht habe. Unser Stand ist, das wir da "Pakete" verwenden wollen, um Fenster auf den Schirm zu bringen.

fs111
08-05-2004, 14:54
Mit was programmiert ihr denn eigentlich (IDE, Editor etc.)? Noch 'ne andere Frage: Ist es bei Euch verboten schon mehr zu wissen als in den Vorlesungen erklärt wurde, oder wie soll ich den vorheriges Posting lesen?

fs111

sticky bit
08-05-2004, 15:48
Hmm, hab ich auch mal gecoded, zieht allerdings gleich für nen ganzen Schein also 12 Spiele (in C):


/*

lottogen_c V1.0.1


Ein Lottozahlengenerator.

Das Programm gibt zufaellig generierte Lottozahlen fuer einen normalen
(vielleicht nur Deutschen) Lottoschein aus, als 12 Spiele mit 6 aus 49.
Einfach ausfuehren, es nimmt keinerlei Argumente entgegen.

Sollte sich problemlos mit jedem (ANSI) C Compiler compilieren lassen.

lottogen_c V1.0.1
Copyright (C) 2002-2003 Florian "sticky bit" Schafferhans

Dieses Programm ist freie Software. Sie koennen es unter den Bedingungen der
GNU General Public License, wie von der Free Software Foundation
herausgegeben, weitergeben und/oder modifizieren, entweder unter Version 2
der Lizenz oder (wenn Sie es wuenschen) jeder spaeteren Version.

Die Veroeffentlichung dieses Programms erfolgt in der Hoffnung, dass es Ihnen
von Nutzen sein wird, aber OHNE JEDE GEWAEHRLEISTUNG - sogar ohne die
implizite Gewaehrleistung der MARKTREIFE oder der EIGNUNG FUER EINEN
BESTIMMTEN ZWECK.

Details finden Sie in der GNU General Public License.

Eine Kopie der GNU General Public License unter der Adresse Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA zu
beziehen.

Bei etwaiger Weiterentwicklung des Programmes, Kritik oder Anregungen, wuerde
ich mich ueber eine E-Mail freuen...

sticky_bit@kriminell.com


Florian "sticky bit" Schafferhans

*/





/*
Preprozessor Directiven
*/
#include <stdio.h>
#include <time.h>




/*
main
*/
int main ()
{
int ziehung[5];
int spiel;
int i;
int ii;
int temp;
time_t zeit;

srand((unsigned) time(&zeit));

for (spiel = 1; spiel <= 12; spiel++) {

for (i = 0; i < 6; ) {
temp = rand()%49 + 1;
// FIXME: irgendwas wie grep() (PERL)?
if (temp != ziehung[0] &&
temp != ziehung[1] &&
temp != ziehung[2] &&
temp != ziehung[3] &&
temp != ziehung[4] &&
temp != ziehung[5]) {
ziehung[i] = temp;
i++;
}
}

// Sortieren, niedrigste Zahl an Index i;
// FIXME: effektivere Sortiermethode?
for (i = 0; i < 6; i++) {
for (ii = i + 1; ii < 6; ii++) {
if (ziehung[i] > ziehung[ii]) {
temp = ziehung[i];
ziehung[i] = ziehung[ii];
ziehung[ii] = temp;
}
}
}

printf(" Spiel %" "2i: ", spiel);

for (i = 0; i < 6; i++) {
printf("%" "2i ", ziehung[i]);
}
printf("\n");

}

return(0);
}

Und in PERL hab ich das auch noch gleich gemacht als CGI Version (siehe Anhang) damit das ganze dann ne Webseite generiert die aussieht wie n Lottoschein. Ist ist nicht so schön gecodet ist auch schon ne Weile her aber es tut...

Vielleicht will sich ja jmd. was abgucken von den Sourcen...

fs111
08-05-2004, 16:25
Wo wir hir ja gerade so munter Lösugen sammeln, hier mal zwei Python-Implementierungen mitz zwei verschiedenen Ansätzen:



#!/usr/bin/env python
import random
#erste Möglichkeit
zuf = [i for i in range(1,50)]
random.shuffle(zuf)
print zuf[0:6]

#zweite Möglichkeit
zuf2 = []
while len(zuf2)<6:
fig = int((random.random()*49)+1)
if fig not in zuf2:
zuf2.append(fig)
print zuf2


fs111

axeljaeger
08-05-2004, 16:35
Wir arbeiten mit dem CodeWarrior auf dem Mac. Die Qualität dieses "Editors" lasse ich jetzt mal unkommentiert. Es ist nicht verboten, was zu wissen, was über den Unterricht hinausgeht, aber ich will nicht immer der Dumme sein, der dann alles erklären darf. Schon jetzt lasse ich das, einen der 8 Rechner zu blockieren, weil ich eh immer nur am rumrennen bin. Jetzt hatte ich den paar Mädels in der Ecke schon eine Lösung mit Schleife aufgeschwatzt, da muss ich mir für nächste Woche noch was überlegen, wie ich denen die alreadyIn-Funktion schmackhaft machen kann, bisher können da noch doppelte Zahlen auftauchen. Ich fand das Problem eigentlich zu schwierig für den Kurs, der Lehrer ist da aber anderer Meinung, weil wie gesagt: Die Musterlösung des Lehrers aus einem Buch verzichtet auf Schleifen

peschmae
08-05-2004, 17:59
Original geschrieben von fs111
Wo wir hir ja gerade so munter Lösugen sammeln, hier mal zwei Python-Implementierungen mitz zwei verschiedenen Ansätzen:

Endlich mal ein Grund was mit Arrays zu machen. :)
Drum hier eine Implementierung in Bash-Script - wenngleich es sicher weniger lang ginge ;)


#!/bin/bash

inArray() {
for((i=$[${#zu[@]}-1]; i > 0; i--)); do
if [ ${zu[$i]} = $1 ]; then
echo already have $1
return 1;
fi
done
return 0;
}

declare -a zu
while [ ${#zu[@]} -lt 6 ]; do
N=$[$RANDOM*45/32767+1]
if inArray $N; then
zu[${#zu }]=$N
fi
done

echo ${zu[@]:0}


MfG Peschmä