Seite 1 von 2

Zufallszahlen nicht doppelt vorkommen

Verfasst: Donnerstag 17. April 2008, 13:46
von Pille0503
Hallo,
ich habe da ein kleines Problem.
Wir sollen in der Schule ein Programm schreiben, welches Zufallszahlen zwischen 1 und 49 erzuegt (also so zu sagen ein "Lottoprogramm"). Wie jeder weiß, können dabei Zahlen nicht zweimal gezogen werden. Und genau hier liegt das Problem. Wie bekommt man es hin, dass der Zufallszahlengenerator eine gezogene Zahl nicht noch einmal zieht?

Verfasst: Donnerstag 17. April 2008, 13:48
von meneliel
... alle bereits gezogenen Zahlen in eine Liste schreiben. Und jede neue Ziehung mit der Liste vergleichen.

Aber das ist vielleicht ein bisschen umständlich ...

Re: Zufallszahlen nicht doppelt vorkommen

Verfasst: Donnerstag 17. April 2008, 13:50
von Leonidas
Hallo Pille0503, willkommen im Forum,
Pille0503 hat geschrieben:Wie bekommt man es hin, dass der Zufallszahlengenerator eine gezogene Zahl nicht noch einmal zieht?
Indem man die bereits gezogenen Zahlen aus der Liste die man ``random.choice()`` übergibt vorher entfernt.

Verfasst: Donnerstag 17. April 2008, 13:52
von jens
oder [mod]random#random.shuffle[/mod] verwenden ;)

Verfasst: Donnerstag 17. April 2008, 14:26
von audax
oder random.sample ;)

Verfasst: Donnerstag 17. April 2008, 14:29
von numerix
oder so lange Zufallszahlen zu einem set hinzufügen, bis 6 Elemente drin sind ...

Verfasst: Donnerstag 17. April 2008, 14:54
von Jan-Peer
Kreativwettbewerb? Man könnte auch so lange zufällige Zahlen aus einer mit range(1,50) erzeugten Liste entfernen, bis nur noch sechs Zahlen übrig sind :roll: :lol:

Verfasst: Donnerstag 17. April 2008, 15:03
von meneliel
Jan-Peer hat geschrieben:Kreativwettbewerb? Man könnte auch so lange zufällige Zahlen aus einer mit range(1,50) erzeugten Liste entfernen, bis nur noch sechs Zahlen übrig sind :roll: :lol:
:D das gefällt mir :P

Verfasst: Donnerstag 17. April 2008, 15:10
von jens
lasst uns doch mal alle Varianten zusammentragen und mit timeit messen, die langsamste Variante hat gewonnen ;)

Verfasst: Donnerstag 17. April 2008, 15:21
von Jan-Peer
... und der Gewinner darf dann bei den Hausaufgaben helfen. :twisted:

Verfasst: Donnerstag 17. April 2008, 15:55
von numerix
jens hat geschrieben:lasst uns doch mal alle Varianten zusammentragen und mit timeit messen, die langsamste Variante hat gewonnen ;)
Ich biete dann diese Variante.
Mit etwas Glück schafft man es damit unter 10 Sekunden ...

Code: Alles auswählen

from random import random

numbers = []
while len(numbers)<6:
    n = 0
    while random()>.000001:
        n += 1
    n = n % 49 + 1
    numbers = [] if n in numbers else numbers+[n]
print numbers

Verfasst: Donnerstag 17. April 2008, 16:03
von Leonidas
jens hat geschrieben:die langsamste Variante hat gewonnen ;)
Warum gerade die?

Verfasst: Donnerstag 17. April 2008, 16:05
von jens
...nur so ;)

Verfasst: Donnerstag 17. April 2008, 16:24
von Sr4l
Leonidas hat geschrieben:
jens hat geschrieben:die langsamste Variante hat gewonnen ;)
Warum gerade die?
Weil moderne CPUs ausgelastet werden müssen, sonst wären die unnötig und CO2 Sünder.

Verfasst: Donnerstag 17. April 2008, 17:58
von Leonidas
Sr4l hat geschrieben:sonst wären die unnötig und CO2 Sünder.
Grad durch Auslastung können sie nicht in einen Modus mit geringerem Takt schalten um Strom zu sparen :P

Verfasst: Samstag 19. April 2008, 13:53
von Pille0503
Danke für die Hilfe. Werde alles mal ausprobieren. :D :D

Verfasst: Samstag 19. April 2008, 22:28
von dennda

Code: Alles auswählen

import random

pool = range(1, 50)

def ziehen(numbers=[]):
    chosen = random.choice(pool)
    numbers.append(chosen)
    pool.remove(chosen)

    if len(numbers) < 7:
        ziehen(numbers)

    return numbers


print ziehen()
Für die Rekursion gibts bestimmt Extrapunkte. :)

Verfasst: Samstag 19. April 2008, 22:33
von Leonidas
dennda hat geschrieben:Für die Rekursion gibts bestimmt Extrapunkte. :)
Nö, Extrapunkte gibts nur für Endrekursion :P

Aber mutable Defaultargumente in Funktionen sind keine besonders tolle Idee, denn die Liste wird nur einmal erstellt und so bleiben die dort gespiecherten Items "hängen".

Verfasst: Samstag 19. April 2008, 23:03
von dennda
Stimmt.

Code: Alles auswählen

import random

pool = range(1, 50)

def ziehen(numbers):
    chosen = random.choice(pool)
    numbers.append(chosen)
    pool.remove(chosen)

    if len(numbers) < 7:
        ziehen(numbers)

    return numbers


print ziehen([])

Verfasst: Samstag 19. April 2008, 23:45
von Leonidas
Dann meckere ich gleich mal weiter, denn die Rekursion ist zwar aus funktionaler Sicht klasse, jedoch veränderst du ``pool``, wodurch ``ziehen`` nicht Seiteneffektfrei ist *nitpick*.