Hi, Dear Taskmaster! I have adjusted your script and run it on my machine, with results like:
995 = 0 = 0
996 = 0 = 0
997 = 0 = 0
998 = 0 = 0
999 = 188 = 0.152597402597403
000 = 823 = 0.668019480519481
001 = 172 = 0.13961038961039
002 = 4 = 0.00324675324675325
003 = 6 = 0.00487012987012987
004 = 8 = 0.00649350649350649
005 = 16 = 0.012987012987013
006 = 3 = 0.00243506493506494
007 = 2 = 0.00162337662337662
008 = 0 = 0
009 = 1 = 0.000811688311688312
010 = 2 = 0.00162337662337662
Quite steady at around 80% for the first 500 cycles and then slowly moving down . Full of confidence I then ran it on an older/slower/cheaper/ laptop and got ...
987 = 0 = 0
988 = 0 = 0
989 = 6 = 0.00510204081632653
990 = 29 = 0.0246598639455782
991 = 59 = 0.0501700680272109
992 = 44 = 0.0374149659863946
993 = 60 = 0.0510204081632653
994 = 56 = 0.0476190476190476
995 = 55 = 0.0467687074829932
996 = 56 = 0.0476190476190476
997 = 63 = 0.0535714285714286
998 = 57 = 0.048469387755102
999 = 64 = 0.054421768707483
000 = 65 = 0.0552721088435374
001 = 61 = 0.0518707482993197
002 = 67 = 0.0569727891156463
003 = 54 = 0.0459183673469388
004 = 58 = 0.0493197278911565
005 = 111 = 0.0943877551020408
006 = 76 = 0.0646258503401361
007 = 42 = 0.0357142857142857
008 = 34 = 0.0289115646258503
009 = 19 = 0.016156462585034
010 = 18 = 0.0153061224489796
011 = 10 = 0.00850340136054422
012 = 7 = 0.00595238095238095
013 = 1 = 0.000850340136054422
014 = 0 = 0
015 = 2 = 0.00170068027210884
Completely spread out, sigh! I have tried to modify it but still get seemingly random behavior - at least I can get it to fluctuate around 000.
Not sure how to explain it - quality of processors, components? Did you try your version on different machines?
Given the number of submissions, I still think I have a shot at top three so here is my script below. Maybe you can try it on your machine to see if it works (it needs at least 10-15 minutes to get calibrated). If it does not work then maybe time to look for new computer? Joke aside, I'd be happy to try your version on my machine for comparison.
If it was mission critical then I guess one can do what some photographers do - shoot x frames per second and pick the best picture, ie just do a few relevant DateStamps into temp file(s) and then pick the one at 000 and append to the official file.
Again, thanks for the challenge, I learn a lot every time.
NOTE: I delete any previous copies of %Temp_dir%DateStampPuzzlerTrial.txt
Code: Select all
Let>resFile=%Temp_dir%DateStampPuzzlerTrial.txt
// Delete old versions of result file
IfFileExists>resFile
DeleteFile>resFile
EndIf
// Dialog
Dialog>Dialog1
object Dialog1: TForm
BorderIcons = [biSystemMenu, biMinimize]
Caption = 'Puzzler #13 DateStamp> Cycle 0'
ClientHeight = 100
ClientWidth = 380
Color = clBlue
OnTaskBar = True
PixelsPerInch = 96
Position = poScreenCenter
object Label1: TLabel
Left = 45
Top = 32
Width = 128
Height = 24
Caption = 'Please Wait...'
Font.Charset = DEFAULT_CHARSET
Font.Color = clYellow
Font.Height = -19
Font.Name = 'MS Sans Serif'
Font.Style = [fsBold]
ParentFont = False
end
end
EndDialog>Dialog1
AddDialogHandler>Dialog1,,OnClose,Quit
Let>vCycle=0
// SRT to handle Quit
SRT>Quit
ExecuteFile>resFile
Exit>0
END>Quit
Show>Dialog1
Let>RP_Wait=1
Let>RP_Windowmode=0
// Initialize, in particular determine the time (in ms) from start of macro
// to the next change in minute.
GoSub>Initialize
// Start of cycle
Label>Start
Add>vCycle,1
// Run 2 sec early to give enough time to clear everything before writeout to file at time 60
Wait>58
// Get the load%. Check time taken to allow for case if it were to take longer than 2 sec
CODEBLOCK
Timer>chk1
RunProgram>cmd /c wmic cpu get loadpercentage > %temp_dir%PuzzlerCPULoad.txt
ReadLn>%temp_dir%PuzzlerCPULoad.txt,2,vData
Trim>vData,vData
Timer>chk2
// If it took longer than 2 sec to get load% then do a manual DateStamp
Let>timecheck={%chk2%-%chk1%}
If>timecheck>2000
DateStamp>resFile,vData
EndIf
ENDCODEBLOCK
// SRT Check_Trigger will just wait until the DateStamp is due
GoSub>Check_Trigger
DateStamp>resFile,vData
SetDialogProperty>Dialog1,Label1,Caption,Last Checked CPU Load = %vData%
SetDialogProperty>Dialog1,,Caption,Puzzler #13 DateStamp> Cycle %vCycle%
// Correction will check if correction is needed due to drift etc.
GoSub>Correction
Goto>Start
// SRT Initialize - To initialize
SRT>Initialize
// Determine time in ms from start of script to the next change in minute
Min>minute0
Let>minute1=minute0
While>minute1=minute0
Min>minute1
EndWhile
//Var refTime gives the time increment to the start time of cycle 1.
//comp is a compensation variable intialized to 0
Timer>refTime
Let>comp=0
END>Initialize
// SRT Check-Trigger - To manage the scheduling of DateStamp
SRT>Check_Trigger
// Loop will run until next min starts
// comp is an adjustment variable that can shift +/- when it should trigger
Let>ref=1000
While>ref>=1000
Timer>currTime
Let>ref={(%currTime%-%refTime%+%comp%) MOD 60000}
EndWhile
END>Check_Trigger
// SRT Correction - To adjust timing
SRT>Correction
// Analyze first 5 cycles for overall difference from zero
// and adjust the timing by setting the comp variable.
If>vCycle=5
ReadFile>resFile,strFile
// Extract the times into array m_k
Let>tmp0=\d{3}(?= -)
RegEx>tmp0,strFile,0,m,nm,0
// Check how many of the 5 values are >0 (and < 25 to exclue any outliers)
Let>ctpos=0
Let>ctr=0
Let>k=0
While>k<5
Add>k,1
Let>tmpVal=m_%k%
If>%tmpVal%>0
If>%tmpVal%<25
Add>ctpos,tmpVal
Add>ctr,1
EndIF
EndIf
EndWhile
// Make a correction if at least 4 of the five values are >0
// Correction is the average value of the positive numbers
If>ctr<4
Let>comp=0
EndIf
If>ctr>3
Let>xRes={%ctpos%/%ctr%}
Let>xRes={Round(%xRes%)}
Let>comp=xRes
EndIf
EndIf
// After first 5 cycles check every 5 cycles for drift etc
If>vCycle>5
Let>refCheck={%vCycle% mod 5}
If>refCheck=0
// Read file and extract array m_k with all times
ReadFile>resFile,strFile
Let>tmp0=\d{3}(?= -)
RegEx>tmp0,strFile,0,m,nm,0
// ctpos and ctneg counts number of pos and neg numbers
Let>ctpos=0
Let>ctneg=0
Let>k={%nm%-5}
// Count number of pos and neg numbers. Note eg 999 is neg vs 000.
While>k<nm
Add>k,1
Let>tmpVal=m_%k%
If>%tmpVal%>0
If>%tmpVal%<500
Add>ctpos,1
EndIF
EndIf
If>%tmpVal%>900
Add>ctneg,1
EndIf
EndWhile
// If neg difference (at least 4 of 5 numbers)
If>ctneg>3
Add>comp,-1
EndIf
// If pos difference (at least 4 of 5 numbers)
If>ctpos>3
Add>comp,1
EndIf
EndIf
EndIf
END>Correction