Zufällige Zahlen Liste
Übersicht

![]() |
FosJonasBetreff: Zufällige Zahlen Liste |
![]() Antworten mit Zitat ![]() |
---|---|---|
Hallo,
habe mir vor einer woche Blitzbasic gedownloadet und versuche gerade mein erstes spiel in blitzbasic zu programmieren. dabei treffe ich aber auf dieses problem: Ich will eine zufällige Liste erstellen die alle zahlen von 1-8 enthält, dabei soll jede zahl nur einmal vorkommen. ich habe das so veruscht: Code: [AUSKLAPPEN] For x= 1 To 8 Nummer(10+x)=x Next For x= 1 To 8 Nummer(4)=Nummer(10+Rand(1,8-x)) Game_List(x)=Nummer(4) For y=Nummer(4) To 7 Nummer(10+y)=Nummer(11+y) Next Next EndIf das ergibt zwar eine liste aber es kommen immer manche zahlen doppelt und dreifach drin vor. warum? |
||
![]() |
The_Nici |
![]() Antworten mit Zitat ![]() |
---|---|---|
Versteh deinen Ansatz überhaupt nicht, aber so hätte ich das gemacht:
Code: [AUSKLAPPEN] SeedRnd MilliSecs() Dim randomlist(7) For i = 0 To 7 Repeat zahl = Rand(1,8) For c = 0 To 7 If randomlist(c) = zahl Then Exit If randomlist(c) = 0 Then randomlist(c) = zahl Exit EndIf Next Until c = 7 Next For i = 0 To 7 Print randomlist(i) Next WaitKey() Ich prüfe das Dim-Feld, wenn es darin eine gleiche Zahl hat geht es aus der inneren For-Schleife, was zur Konsequenz hat, dass c nicht bis auf 7 gezählt wird, und so die Bedingung der Repeat-Schleife nicht erfüllt wird, also sich die Schleife wiederholt, bis die Zahl einzigartig ist. Das ganze mache ich 7 mal und gebe danach die Liste aus. MfG |
||
![]() |
Starwar |
![]() Antworten mit Zitat ![]() |
---|---|---|
Ich habe meine eigene Methode.
Ich fülle eine Array mit den Zahklen von 1 bis 8. Dann tausche ich ein paar viele mal zwei zufällig ausgwählte Einträge. Vorteil: Nehmen wir an, wir haben eine Millionen Zahlen und haben schon 999.998 ermittelt. Jetzt bleiben nur noch zwei. Die Chance, dass genau einer dieser 2 per zufall ausgewählt wird, ist ziemich gering.... Code: [AUSKLAPPEN] Dim zahlen(7)
For i=0 To 7 zahlen(i) = i+1 Print zahlen(i) Next For i=0 To 8*8 zufall1%=Rand(0,7) zufall2%=Rand(0,7) tmp% = zahlen(zufall1%) zahlen(zufall1%) = zahlen(zufall2%) zahlen(zufall2%) = tmp% Next Print "------------" For i=0 To 7 Print zahlen(i) Next WaitKey() MFG |
||
- Zuletzt bearbeitet von Starwar am Mi, Mai 20, 2009 15:39, insgesamt einmal bearbeitet
![]() |
FosJonas |
![]() Antworten mit Zitat ![]() |
---|---|---|
wow danke für die schnelle hilfe, jetzt funktioniert es. ![]() Hmm mein ansatz war wohl wirklich völlig falsch, aber nun weis ich ja wies geht. |
||
![]() |
The_Nici |
![]() Antworten mit Zitat ![]() |
---|---|---|
Ui, Starwars Methode ist um 0.04 Millisekunden schneller. ![]() |
||
![]() |
FosJonas |
![]() Antworten mit Zitat ![]() |
---|---|---|
hmmm starwars seine methode raff ich nicht so ganz.
Naja 0,04 millisekunden sind mir eig. egal^^ |
||
![]() |
Starwar |
![]() Antworten mit Zitat ![]() |
---|---|---|
Hi,
Also erstmal das Problem: Wenn wir einfach so lange probieren, bis wir eine Zahl durch Zufall finden, die noch nicht in der Liste ist, können wir uns totsuchen. Das PRogramm "läuft sich Tot". Nehmen wir an, wir haben eine Millionen Zahlen und haben schon 999.998 ermittelt. Jetzt bleiben nur noch zwei. Die Chance, dass genau einer dieser 2 per zufall ausgewählt wird, ist ziemlich gering.... Meine Lösung: Stell dir ein Kartenspiel vor. Alle Karten sind von 1-36 durchnummeriert und in Reihenfolge. Code: [AUSKLAPPEN] Dim zahlen(7)
For i=0 To 7 zahlen(i) = i+1 Next Jetzt nimmst du dir irgendeine Karte. Und eine zufällige Zeite. (das kann auch die selbe sein, ist egal) Code: [AUSKLAPPEN] zufall1%=Rand(0,7)
zufall2%=Rand(0,7) Dann tauschen wir die Karten Code: [AUSKLAPPEN] tmp% = zahlen(zufall1%)
zahlen(zufall1%) = zahlen(zufall2%) zahlen(zufall2%) = tmp% Und das ganze machen wir ein paar mal (Ich nehm gerne das Quardrat der Anzahl der Werte (hier 8*8)). Ich gehe nochmal genau auf diesen Code ein: Code: [AUSKLAPPEN] tmp% = zahlen(zufall1%)
zahlen(zufall1%) = zahlen(zufall2%) zahlen(zufall2%) = tmp% Zuerst merken wir uns die 1. Zahl in einer Variable. Jetzt überschreiben wir nämlich die Variable in der die 1. Zahl liegt mit der 2.. Dann wissen wir die 1. natürlich nicht mehr, da wir sie überschrieben haben. Aber dafür ist die TMP-Variable. Die weiß die 1. Zahl noch. Also hat die Variable, in der die 2. Zahl ist jetzt den Wert der TMP-Variable. So haben wir die 1. und 2. Zahl getauscht. Ich hoffe es ist nachvollziehbar... ![]() MFG Und herzlich Willkommen im Portal. |
||
![]() |
das wurgel |
![]() Antworten mit Zitat ![]() |
---|---|---|
Hi,
Hab hier noch ne schnellere Methode, die auch für beliebig große Anzahlen von Zahlen anwendbar sein müsste: Code: [AUSKLAPPEN] SeedRnd MilliSecs()
Dim randomlist(7) For i = 1 To 8 zahl = Rand(1, 8-i+1) k=0 For j = 0 To 7 If randomlist(j)=0 Then k=k+1 If k=zahl Then randomlist(j)=i EndIf Next Next For i = 0 To 7 Print randomlist(i) Next WaitKey() In der Schleife werden alle Zahlen von 1 - 8 durchgegangen. Dann wird per Zufall ausgewählt, die wievielte freie Stelle im Feld die Zahl gespeichert werden soll. Also z.B. wird in der ersten Schleifenrunde eine Zahl von 1 - 8 ausgewählt. Nehmen wir an diese Zahl wäre 5. In der nächsten Runde wird eine Zahl von 1 - 7 gewählt weil die Stelle 5 im Feld schon besetzt und daher noch 7 Stellen übrigbleiben. Die 5 Stelle wird dann nicht mehr mitgezählt und eine 7 würde bewirken dass die 8. Stelle mit der Zahl 2 gefüllt wird usw. mfg |
||
1 ist ungefähr 3 |
![]() |
Starwar |
![]() Antworten mit Zitat ![]() |
---|---|---|
Sehr schöne Methode, wenn sie mir auch nicht sofort eingeleuchtet ist. Totlaufen kann sie sich jedenfalls nicht und zufälliger gehts auch nicht ![]() Aber wenn du sehr auf Geschwindigkeit wert legst, dann hab ich noch eine kleine Ergänzung: Code: [AUSKLAPPEN] If k=zahl Then randomlist(j)=i : Exit ![]() MFG |
||
Kruemelator |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Ich habe hier auch nochmal eine ganz andere Methode.
Sie ist auch ein ganz wenig schneller als die von das wurgel. Code: [AUSKLAPPEN] SeedRnd MilliSecs()
Dim zahlen(7) zahlenreihe$ = "12345678" For x=0 To 7 stelle = Rand(0,7-x)+1 zahlen(x) = Mid(zahlenreihe$ ,stelle ,1) zahlenreihe$ = Replace(zahlenreihe$, zahlen(x), "") Next For a=0 To 7 Print zahlen(a) Next Es wird ein String erstellt mit den Zahlen die enthalten sind. Dann wir eine zufällige Stelle gewählt und die Zahl die dort steht in dem Dim Feld gespeichert und diese Stelle aus dem String gelöscht. Gruß Kruemelator |
||
![]() |
TimBo |
![]() Antworten mit Zitat ![]() |
---|---|---|
boah wie geil, hier sieht man mal wie man sauber und unsauber programmieren kann. Gerade The_nici hat ein echt sehr cooles Beispiel gebracht. Wenn man 10000 Zahlen haben wird dieser Code schon echt viel lahmer als die anderen.
@The_Nici: ich möchte dich nicht Blosstellen oder so, aber daraus kann man doch lernen oder? Dein Ansatz ist am einfachsten zu verstehen und eigentlich vom normalen verstand doch der logischste , aber allerdings nicht der beste. Das mit dem String ist das vom gedankengang strangste aber echt einleuchtend. Man löscht einfach das verwendete und schon hat sichs. Echt coole überlegung Viele Grüße TimBo |
||
mfg Tim Borowski // CPU: Ryzen 2700x GPU: Nvidia RTX 2070 OC (Gigabyte) Ram: 16GB DDR4 @ 3000MHz OS: Windows 10
Stolzer Gewinner des BCC 25 & BCC 31 hat einen ersten Preis in der 1. Runde beim BWInf 2010/2011 & 2011/12 mit BlitzBasic erreicht. |
![]() |
Starwar |
![]() Antworten mit Zitat ![]() |
---|---|---|
Ich denke bei 8 Zahlen müssen wir kein Geschwindikeitsrekord aufstellen ![]() Aber bei 1000 schon... Die String-Methode wird bei unterschiedlich-ziffrigen Zahlen schon komplizierter. Aber sie zeigt wie viele intressante Lösungen es für dieses Problem gibt. Sehr inspirierend ![]() MFG |
||
Kruemelator |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Herausforderung angenommen ![]() Code: [AUSKLAPPEN] SeedRnd MilliSecs()
Dim zahlen(999) zahlenreihe$ = "" time1 = MilliSecs() For stelle100=0 To 9 For stelle10=0 To 9 For stelle1=0 To 9 zahlenreihe$ = zahlenreihe$ + "-" + stelle100 + "" + stelle10 + "" + stelle1 Next Next Next time2 = MilliSecs() For x=0 To 999 stelle = Rand(0,999-x) wert$ = Mid(zahlenreihe$ ,stelle*4+1 ,4) zahlen(x) = Right(wert$,3) zahlenreihe$ = Replace(zahlenreihe$, wert$, "") Next time3 = MilliSecs() Print time3 - time1 Print time3 - time2 ;datei = WriteFile("c:\zahlenliste.txt") ;For a=0 To 999 ;WriteLine datei,zahlen(a) ;Next ;CloseFile datei Edit: Man kann mit Strings auch andere Probleme lösen: Z.B.: Socken aus Schrank ziehen ![]() Code: [AUSKLAPPEN] SeedRnd MilliSecs()
Dim zahlen$(8) zahlenreihe$ = "-r-r-r-g-g-b-b-b-b" ;Print zahlenreihe$ For x=0 To 8 stelle = Rand(0,8-x) wert$ = Mid(zahlenreihe$ ,stelle*2+1 ,2) zahlen$(x) = Right(wert$,1) vorher = Len(zahlenreihe$) zahlenreihe$ = Replace(zahlenreihe$, wert$, "") nachher = Len(zahlenreihe$) wiederholungen = (vorher - nachher)/2 -1 While wiederholungen <> 0 zahlenreihe$ = zahlenreihe$ + "" + wert$ wiederholungen = wiederholungen - 1 Wend ;Print zahlenreihe$ Next For a=0 To 8 Print zahlen(a) Next |
||
![]() |
Starwar |
![]() Antworten mit Zitat ![]() |
---|---|---|
Wohl nen Clown gefrühstückt, was? ![]() Gute Ideen, ich werds mir auf jedenfall merken. In PHP mach ichs bereits, da gibts die schöne Funktion "explode". Ich glaube ich werd die jetzt mal schnell nachcoden... Hier ist sie nun. Aber es geht gewiss noch eleganter... ![]() Code: [AUSKLAPPEN] Dim exploded$(0)
AppTitle "Exploding String" in$ = "Dieser String ist explodiert oder so was in der Art..." anz = explode(in$," ") For i=0 To anz-1 Print exploded$(i) Next WaitKEy() End Function explode(in$,tz$) pos=Instr(in$,tz$) If pos=0 Then Dim exploded$(0) exploded$(0)=in$ Return 1 EndIf Repeat pos=Instr(in$,tz$,pos+1) anz=anz+1 If pos = 0 Then Exit Forever Dim exploded$(anz) pos=0 altpos=0 Repeat altpos=pos pos=Instr(in$,tz$,pos+1) If pos = 0 Then pos=-1 exploded$(i)=Mid(in$,altpos+1,pos-1-altpos) i=i+1 If pos=-1 Then Exit Forever Return anz+1 End Function MFG |
||
Übersicht


Powered by phpBB © 2001 - 2006, phpBB Group