...den richtigen Fensternamen verwenden.. ![]()
"Google - Morzilla Firefox"
...den richtigen Fensternamen verwenden.. ![]()
"Google - Morzilla Firefox"
also ich finde, dass Euer Lösungsweg mit der For-Schleife bis 1299709 eigentlich Beschiss ist.
Tja, genau da liegt aber der Hund begraben. Jeder schnelle Algoritmus benötigt irgendeine Obergrenze zum Rechnen. Wenn ich einfach nur fortlaufend rechne: _IsPrime(Zahl) - Next, so funktioniert das zwar, ist wie du selbst siehst aber schneckenlahm.
Und was ist Beschiss, wenn du weißt, dass bis 1299709 genau 100.000 Primzahlen vorkommen? Um Chancengleichheit zu wahren, habe ich ja diese Information gegeben.. :wacko:
Hi,
ich hab mir eine Testumgebung erstellt, in der ich meine Algorithmen zum Primzahlbattle teste (nicht wundern, wegen der Zeiten: 1,5 GHz).
Dabei ist mir etwas seltsames aufgefallen:
- die Laufzeitabweichungen sind bei einem Skript max. 14%, beim anderen bis zu 25% !!
- führe ich die Skripts in einer Schleife immer abwechselnd aus ist die Abweichung am gerinsten
- wiederholte Ausführung eines Skriptes führt zu den stärksten Abweichungen
[01] 6.614 | 7.059 [02] 7.024 | 7.054 [03] 7.264 | 6.960
[04] 7.340 | 6.985 [05] 7.780 | 6.983 [06] 7.293 | 6.973
[07] 7.610 | 7.071 [08] 7.418 | 7.076 [09] 7.599 | 7.083
[10] 7.551 | 6.966
=== Algorithmus 1 ===
Min: 6.614 - vom Mittel: 90%
Max: 7.780 - vom Mittel: 105.86% - vom Min: 117.63%
Mittel: 7.349
=== Algorithmus 2 ===
Min: 6.960 - vom Mittel: 99.13%
Max: 7.083 - vom Mittel: 100.88% - vom Min: 101.77%
Mittel: 7.021
=============== Lauftest nur Algo 1:
[01] 6.742 | 0.000 [02] 7.846 | 0.000 [03] 7.876 | 0.000
[04] 8.108 | 0.000 [05] 8.236 | 0.000 [06] 8.108 | 0.000
[07] 8.256 | 0.000 [08] 8.103 | 0.000 [09] 8.009 | 0.000
[10] 8.385 | 0.000
=== Algorithmus 1 ===
Min: 6.742 - vom Mittel: 84.62%
Max: 8.385 - vom Mittel: 105.25% - vom Min: 124.37%
Mittel: 7.967
=============== Lauftest nur Algo 2:
[01] 0.000 | 7.181 [02] 0.000 | 7.856 [03] 0.000 | 6.849
[04] 0.000 | 6.907 [05] 0.000 | 6.875 [06] 0.000 | 7.150
[07] 0.000 | 6.974 [08] 0.000 | 6.891 [09] 0.000 | 6.927
[10] 0.000 | 6.899
=== Algorithmus 2 ===
Min: 6.849 - vom Mittel: 97.14%
Max: 7.856 - vom Mittel: 111.42% - vom Min: 114.7%
Mittel: 7.051
Alles anzeigen
#include <Array.au3>
[/autoit] [autoit][/autoit] [autoit]Local $n_Schleife = 10
Local $a_Time1[$n_Schleife]
Local $a_Time2[$n_Schleife]
Local $t, $sMess = ''
For $i = 1 To $n_Schleife
$t = TimerInit()
_GetPrime_1()
$a_Time1[$i -1] = Round(TimerDiff($t)/1000, 3)
$t = TimerInit()
_GetPrime_2()
$a_Time2[$i -1] = Round(TimerDiff($t)/1000, 3)
$sMess &= '[' & StringFormat('%0' & StringLen($n_Schleife) & 'd', $i) & '] ' & StringFormat('%.3f', $a_Time1[$i -1]) & ' | ' & StringFormat('%.3f', $a_Time2[$i -1]) & @TAB
If Mod($i, 3) = 0 Or $i = $n_Schleife Then
ConsoleWrite($sMess & @CRLF)
$sMess = ''
EndIf
Next
Local $av1 = 0, $av2 = 0
For $i = 0 To $n_Schleife -1
$av1 += $a_Time1[$i]
$av2 += $a_Time2[$i]
Next
ConsoleWrite(@CRLF & '=== Algorithmus 1 ===' & @CRLF)
ConsoleWrite('Min: ' & @TAB & StringFormat('%.3f', _ArrayMin($a_Time1, 1)) & @TAB & '- vom Mittel: ' & Round( _ArrayMin($a_Time1, 1)/Round($av1/$n_Schleife, 3)*100, 2) & '%' & @CRLF)
ConsoleWrite('Max: ' & @TAB & StringFormat('%.3f', _ArrayMax($a_Time1, 1)) & @TAB & '- vom Mittel: ' & Round( _ArrayMax($a_Time1, 1)/Round($av1/$n_Schleife, 3)*100, 2) & '%' & @TAB & '- vom Min: ' & Round( _ArrayMax($a_Time1, 1)/_ArrayMin($a_Time1, 1)*100, 2) & '%' & @CRLF)
ConsoleWrite('Mittel: ' & StringFormat('%.3f', Round($av1/$n_Schleife, 3)) & @CRLF & @CRLF)
ConsoleWrite('=== Algorithmus 2 ===' & @CRLF)
ConsoleWrite('Min: ' & @TAB & StringFormat('%.3f', _ArrayMin($a_Time2, 1)) & @TAB & '- vom Mittel: ' & Round( _ArrayMin($a_Time2, 1)/Round($av2/$n_Schleife, 3)*100, 2) & '%' & @CRLF)
ConsoleWrite('Max: ' & @TAB & StringFormat('%.3f', _ArrayMax($a_Time2, 1)) & @TAB & '- vom Mittel: ' & Round( _ArrayMax($a_Time2, 1)/Round($av2/$n_Schleife, 3)*100, 2) & '%' & @TAB & '- vom Min: ' & Round( _ArrayMax($a_Time2, 1)/_ArrayMin($a_Time2, 1)*100, 2) & '%' & @CRLF)
ConsoleWrite('Mittel: ' & StringFormat('%.3f', Round($av2/$n_Schleife, 3)) & @CRLF & @CRLF)
Vielleicht könnt ihr ja mal testen, wie das bei euch aussieht - beliebige Funktionen in die Testumgebung einsetzen und los. Vielleicht ist es ja auch nur bei meinem Schlepptop so. :wacko:
Die verwendeten Funktionen verwenden übrigens ausschließlich lokale Variablen.
Solche Skripte sind genau genommen auch Bots, und in solch einem Fall versteh ich nicht wie jemand komplett gegen Bots sein kann, da er ja hier nicht zwischen Gamebots und anderen unterscheidet!
Nur ein Kommentar von mir und dann denke ich, das Thema sollte endgültig durch sein.
Im Sprachgebrauch unseres Forums wird als Bot bezeichnet, was zur Vorteilsnahme führt oder sonstwie gegen Regeln verstößt. Punkt.
Grundsätzliche stellt jede Form der Automatisierung einen 'Bot' dar - aber wie will man dann differenzieren? Deshalb die Definition, wie eben angeführt.
Wenn also im Forum jemand sagt, er sei gegen Bots, dann ist genau diese von uns verabscheute Form der Automatisierung gemeint.
Genau das ist auch aus der überwiegenden Mehrzahl der Posts hier herauszulesen.
- Die Meinung der Forumsbetreiber steht unverrückbar fest.
- Die Mehrzahl der User geht damit konform.
Somit erübrigt sich für jetzt und alle Zeiten jede weitere Diskussion dazu.
Ich schließe damit diesen Thread und werde evtl. nochmals auftauchende Diskussionsversuche kommentarlos abwürgen.
[CLOSED]
Da könnte ich ja die 5 und die 7 und die .... auch noch als gegebenen annehmen.
Wenn du einen Algorithmus hast, der dadurch arbeitet, dass er genau das voraussetzt - warum nicht.
Allerdings ist mir grad kein Algo bekannt, der das tut. 2 und 3 - ja, aber 5, 7... etc. sind durch die Operationen mit 2 und 3 abgedeckt.
Lassen wir uns mal überraschen.
ZitatDürfen die ersten Zahlen ohne Berechnungen als Primzahlen angenommen werden? 2, 3 vieeleicht noch 5?
Wenn der Algorithmus darauf aufbaut, dass 2 und 3 Primzahlen sind, sind diese natürlich nicht berechenbar und sollten als gegeben betrachtet werden. Oder seht ihr das anders?
Kleiner Tipp: Niemals die GlobalProperties editieren. Ist eh alles wieder weg bei der nächsten SciTE-Version. Schreib deine Änderungen in die UserProperties, die Einträge werden vorrangig behandelt und bleiben, wenn ich nicht irre, auch nach SciTE-Update erhalten.
die ersten 100000 Primzahlen, nicht die Primzahlen unter 100000.
Keine Obergrenze darf gegeben sein, auch nicht per sqlite.
Reihenfolge ist egal.
Mit dieser (sehr seltsamen) Festlegung hast du schwupp-di-wupp alle ernsthaften Teilnehmer aus dem Wettbewerb gestrichen.
Zeig mir einen schnellen Algorithmus, der ohne Obergrenze funktioniert!
Das war ja der Grund, warum ich die Obergrenze (1.299.710) zum Ermitteln von 100.000 Primzahlen angegeben habe.
Auch von mir Alles Gute eukalyptus.
Nasch nicht zu viel vom Eukalyptus-Likör, das könnte arg enden. ![]()
Damit mal klar wird, was ich meinte:
Ein Schreibzugriff ist von soviel Begleitfaktoren abhängig, dass er niemals eine zeitgleiche Größe liefert.
Somit muss die Zeitmessung vor dem Schreiben in die Datei stattfinden.
Dazu könnte man die TimerInit-Variable ByRef übergeben:
; === Testumgebung
Local $timer = TimerInit()
Func _GetPrim(ByRef $timer)
; ...
; ...
ConsoleWrite(TimerDiff($timer) & @CRLF)
FileWrite($file, $100000_Primzahlen)
EndFunc
chip: Interessiert mich auch... kommt fileopen / close mit in den timerbereich?
Sollte definitiv außen vorbleiben, sonst läßt sich kein ernsthafter Vergleich erstellen. HD-Zugriffe sind niemals gleichmäßig.
Am Besten: Funktion gibt trennzeichenbasierten String oder Array mit allen Zahlen zurück. Dann wird Zeit gemessen und wenn man will kann man das anschließend in eine Datei schreiben.
Mal als kleine Hilfe:
Um 100.000 Primzahlen zu ermitteln muß man die Zahlen bis 1.299.710 untersuchen. ![]()
Jawoll L3viathan2142!
Wobei ich vorschlagen würde, die ersten 100.000 zu ermitteln, da 10.000 so schnell gehen, dass der Rechenalgorithmus den geringsten Anteil am Skript hat. ![]()
(für 100.000 brauch ich knapp 7 sec., für 10.000 unter 1 sec.)
Ich gehe mal stark davon aus, dass all jene die der Meinung sind, dass man einfach x Minuten ermittelt und dann einen vergleichbaren Wert an Primzahlen hat, sich bisher nicht mit der praktischen Umsetzung beschäftigt haben (auf jeden Fall nicht mit effektiven Algorithmen).
Daher sollten wir den von Pee vorgeschlagenen Weg gehen.
Alles andere ist Makulatur.
Wenn ein Skript in 5 Jahren 100 Primzahlen ermittelt, und ein anderes in 5 Minuten 10, dann ist zweiteres der Sieger.
Welche 100, oder welche 10? - Die ersten, die letzten bisher bekannten?
Diese Aussagen sind alle zu verwaschen und deshalb als Maßstab in einem Wettbewerb nicht geeignet.
Die Suche nach Primzahlen wird schwieriger und langwieriger, je größer der Zahlenbereich ist, indem man sich befindet. Ich denke darüber sind wir uns einig.
Das es wenig Sinn macht, dass wir hier "neue" Primzahlen ermitteln sollte auch klar sein (Bei der letzten "neuen" ist wohl der entsprechende Rechner ca. 3 Jahre gelaufen hab ich mal gelesen).
Also müssen wir uns einen Rahmen schaffen, indem wir arbeiten. Und Zeit ist kein Rahmen sondern ein Ergebnis. Zumal die Zeitsituation zusehr von der verwendeten Hardware abhängt.
Wer die höchste Primzahl bei der besten Geschwindigkeit finden kann, hat gewonnen.
Das geht nicht. Um vergleichbare Kriterien zu bekommen, mußt du zum Bsp. einen Zahlenbereich vorgeben, aus dem die größte Primzahl ermittelt werden soll.
Denn es gibt nunmal keine größte Primzahl und wenn ich mit einem Skript nach 5 Jahren Laufzeit eine bisher nicht bekannte Primzahl ermittle, habe ich dann gewonnen, obwohl jemand eine kleinere in 5 Sekunden ermittelt? ![]()
Du siehst, eine Obergrenze ist unumgänglich.
Edit:
So, meine Version steht.
Als kleiner Meßwert:
Für die größte Primzahl bis 1.000.000.000 brauch ich auf meinem Laptop (1,5 GHz; 448 MB RAM) genau 1,11 Sekunden.
Hi,
manchmal braucht man die Info, die hinter einem Makro steckt (z.B. Pfade für FileInstall, da dort keine Makros verwendet werden können).
Man kann natürlich mit "ConsoleWrite(@MACRO & @CRLF)" sich das ganze ausgeben lassen. Ich habe es aber mal in einer kleinen GUI zusammengefasst als praktische Anwendung für IntelliSenseBox.
Einfach das Makro in das untere Input schreiben, oben wird das ausgeführte Makro angezeigt. Per Button kann dann kopiert werden.
#include <EditConstants.au3>
#include <GUIConstantsEx.au3>
#include <ListBoxConstants.au3>
#include <WindowsConstants.au3>
#include <GUIListBox.au3>
#Include <WinAPI.au3>
Opt("GUICloseOnESC", 0)
Opt("GuiOnEventMode", 1)
Opt("MustDeclareVars", 1)
Global $show = False, $indexB = -1, $SenseGui, $SenseCtrl, $Macro, $guiBox, $box, $POSSenseGui[2]
Local $aMacro[47] = [ _
'@AppDataCommonDir','@AppDataDir','@AutoItExe','@AutoItVersion','@CommonFilesDir','@ComputerName', _
'@DesktopCommonDir','@DesktopDir','@DocumentsCommonDir','@FavoritesCommonDir','@FavoritesDir','@HomeDrive', _
'@HomePath','@HomeShare','@IPAddress1','@IPAddress2','@IPAddress3','@IPAddress4','@KBLayout','@LogonDNSDomain', _
'@LogonDNSDomain','@LogonDomain','@LogonDomain','@LogonServer','@LogonServer','@MyDocumentsDir','@OSArch', _
'@OSBuild','@OSLang','@OSServicePack','@OSType','@OSVersion','@ProgramFilesDir','@ProgramsCommonDir', _
'@ProgramsDir','@ScriptDir','@ScriptFullPath','@ScriptName','@StartMenuCommonDir','@StartMenuDir', _
'@StartupCommonDir','@StartupDir','@SystemDir','@TempDir','@UserName','@UserProfileDir','@WindowsDir']
$guiBox = GUICreate('', 150, 85, 0, 0, BitOR($WS_SIZEBOX,$WS_POPUP), BitOR($WS_EX_TOPMOST, $WS_EX_TOOLWINDOW))
$box = _GUICtrlListBox_Create($guiBox, '', 0, 0, 150, 86, BitOR($LBS_SORT, 0x00B00002))
For $i = 0 To UBound($aMacro) -1
_GUICtrlListBox_AddString($box, $aMacro[$i])
Next
GUIRegisterMsg($WM_COMMAND, "MY_WM_COMMAND")
GUIRegisterMsg($WM_MOVE, "_WM_MOVE")
GUIRegisterMsg(0x231, "_WM_ENTERSIZEMOVE")
$SenseGui = GUICreate('Makro Box', 500, 205)
GUISetOnEvent($GUI_EVENT_CLOSE, '_Exit')
GUICtrlCreateLabel('Inhalt', 10, 10, 60)
$Macro = GUICtrlCreateInput('', 10, 30, 480, 21, BitOR($ES_READONLY,$ES_AUTOHSCROLL))
GUICtrlSetBkColor(-1, 0xE0FFFF)
GUICtrlCreateLabel('Makro', 10, 60, 60)
$SenseCtrl = GUICtrlCreateInput('', 10, 80, 480, 21)
GUICtrlSetBkColor(-1, 0xFFFFE0)
GUICtrlCreateButton('Copy To Clipboard', 380, 175, 110, 20)
GUICtrlSetOnEvent(-1, '_Copy')
GUISetState()
Global $Dummy[5]
$Dummy[0] = GUICtrlCreateDummy()
For $i = 1 To 4
$Dummy[$i] = GUICtrlCreateDummy()
GUICtrlSetOnEvent(-1, "_Dummy")
Next
Dim $AccelKeys[4][2] = [["{ENTER}", $Dummy[1]],["{ESC}", $Dummy[2]],["{UP}", $Dummy[3]],["{DOWN}", $Dummy[4]]]
GUISetAccelerators($AccelKeys)
While True
Sleep(100)
WEnd
Func _Exit()
Exit
EndFunc
Func _Copy()
ClipPut(GUICtrlRead($Macro))
EndFunc
Func _Dummy()
If Not $show Then Return
Switch @GUI_CtrlId - $Dummy[0]
Case 1
Local $txt = _GUICtrlListBox_GetText($box, $indexB)
If $txt Then
ControlSetText($SenseGui, '', $SenseCtrl, $txt)
ControlSetText($SenseGui, '', $Macro, Execute($txt))
Else
ControlSetText($SenseGui, '', $Macro, '')
EndIf
GUISetState(@SW_HIDE, $guiBox)
$show = False
Case 2
GUISetState(@SW_HIDE, $guiBox)
$show = False
Case 3
If $indexB > 0 Then
$indexB -= 1
_GUICtrlListBox_SetCurSel($box, $indexB)
ControlSetText($SenseGui, '', $Macro, Execute(_GUICtrlListBox_GetText($box, $indexB)))
Sleep(90)
EndIf
Case 4
If $indexB < _GUICtrlListBox_GetCount($box) - 1 Then
$indexB += 1
_GUICtrlListBox_SetCurSel($box, $indexB)
ControlSetText($SenseGui, '', $Macro, Execute(_GUICtrlListBox_GetText($box, $indexB)))
Sleep(90)
EndIf
EndSwitch
EndFunc
Func MY_WM_COMMAND($hWnd, $Msg, $wParam, $lParam)
Local $nNotifyCode = BitShift($wParam, 16)
Local $hCtrl = $lParam
Local $hSenseCtrl = $SenseCtrl
If Not IsHWnd($hSenseCtrl) Then $hSenseCtrl = GUICtrlGetHandle($hSenseCtrl)
If ($nNotifyCode = 1024 Or $nNotifyCode = 6) And $hCtrl = $hSenseCtrl Then
Local $str = ControlGetText($SenseGui, '', $SenseCtrl)
$indexB = _GUICtrlListBox_FindString($box, $str)
_GUICtrlListBox_SetCurSel($box, $indexB)
Local $caret = _CaretPos()
If Not @error And Not $show Then
WinMove($guiBox, '', $caret[0], $caret[1] +25)
GUISetState(@SW_SHOWNOACTIVATE, $guiBox)
$show = True
ControlSetText($SenseGui, '', $Macro, Execute(_GUICtrlListBox_GetText($box, 0)))
EndIf
ElseIf $hCtrl = $box And $nNotifyCode = 1 Then
$indexB = _GUICtrlListBox_GetCurSel($box)
ControlSetText($SenseGui, '', $SenseCtrl, _GUICtrlListBox_GetText($box, $indexB))
ControlSetText($SenseGui, '', $Macro, Execute(_GUICtrlListBox_GetText($box, $indexB)))
GUISetState(@SW_HIDE, $guiBox)
$show = False
ElseIf $show And $nNotifyCode = 512 And $hCtrl = $lParam And Not $hCtrl = $box Then
GUISetState(@SW_HIDE,$guiBox)
$show = False
EndIf
If $show And Not StringLen(GUICtrlRead($SenseCtrl)) Then
GUISetState(@SW_HIDE,$guiBox)
$show = False
EndIf
Return $GUI_RUNDEFMSG
EndFunc
Func _WM_ENTERSIZEMOVE($hWnd)
If $hWnd = $SenseGui Then $POSSenseGui = WinGetPos($SenseGui)
EndFunc
Func _WM_MOVE($hWnd)
If $hWnd = $SenseGui Then
Local $pos = WinGetPos($guiBox)
Local $postemp = WinGetPos($SenseGui)
WinMove($guiBox,"",$pos[0]-($POSSenseGui[0]-$postemp[0]),$pos[1]-($POSSenseGui[1]-$postemp[1]))
$POSSenseGui = WinGetPos($SenseGui)
EndIf
EndFunc
Func _CaretPos()
Local $old = Opt("CaretCoordMode", 0) ;relative mode
Local $c = WinGetCaretPos() ;relative caret coords
Local $w = WinGetPos("") ;window's coords
Local $f = ControlGetFocus("","") ;text region "handle"
Local $e = ControlGetPos("", "", $f) ;text region coords
Local $h = ControlGetHandle("", "", $f) ;Ctrl-Handle
Local $t[5]
If IsArray($c) and IsArray($w) and IsArray($e) Then
If _WinAPI_IsClassName($SenseCtrl, 'Edit') Then ; Input wird als Edit-Class erkannt
$t[0] = $c[0] + $w[0] + $e[0]
ElseIf _WinAPI_IsClassName($SenseCtrl, 'ComboBox') Then
$t[0] = $w[0] + $e[0]
EndIf
$t[1] = $c[1] + $w[1] + $e[1]
$t[2] = $h
$t[3] = $w[1]
$t[4] = $e[1]
Opt("CaretCoordMode", $old)
Return $t ;absolute screen coords of caret cursor
Else
Opt("CaretCoordMode", $old)
SetError(1)
EndIf
EndFunc
Die TreeView-Funktionen sind m.M. noch nicht ausgereift. Das Übernehmen von Änderungen funktioniert ja auch mit dem Original Hilfebsp. nicht wirklich. Egal was ich reinschreibe, es wird nur das erste Zeichen übernommen. ![]()
Ist zwar etwas aufwändiger, aber sicher: Schreibe dein eigenes Edit-Tool, so wie ich es für ListView-Editierung gemacht hatte.
Ich mag aber nicht bei Neustart löschen, da ich mein Laptop nie (oder fast nie) neustarte sondern nur in Hibernate schicke. Also lösche ich gelockte Dateien lieber sofort mit Unlocker von Softonic. ![]()
Neue Version (Funktionen hinzugefügt), s. Post 1.