dilysmoore Posted December 27, 2021 Share Posted December 27, 2021 Hello everyone, i have an array like this: aArray = -23, -17, 0, 7, 25, 31, 53 I want to find the lowest number except the negative ones an zero (should be 7) Any good idea? Thank you so much!!! Link to comment Share on other sites More sharing options...
pseakins Posted December 27, 2021 Share Posted December 27, 2021 Good question. _ArrayMin() is not going to work, so unless there is another function I am not aware of I think you would have to search the array programmatically. I shouldn't need to show you how to do that, it's simple enough. Phil Seakins Link to comment Share on other sites More sharing options...
Luke94 Posted December 27, 2021 Share Posted December 27, 2021 Use _ArrayMax to find the highest number. #include <Array.au3> Local $aArray[7] = [ -23, -17, 0, 7, 25, 31, 53 ] Local $iHighestNumber = _ArrayMax($aArray, 1) ConsoleWrite('Highest Number: ' & $iHighestNumber & @CRLF) Once you have the highest number, loop through the array and check if each array element is greater than zero and less than the highest number. #include <Array.au3> Local $aArray[7] = [ -23, -17, 0, 7, 25, 31, 53 ] Local $iHighestNumber = _ArrayMax($aArray, 1) Local $iLowestNumber = $iHighestNumber For $i = 0 To (UBound($aArray) - 1) Step 1 If $aArray[$i] > 0 And _ $aArray[$i] < $iLowestNumber Then If $aArray[$i] = 1 Then $iLowestNumber = 1 ExitLoop EndIf $iLowestNumber = $aArray[$i] EndIf Next ConsoleWrite('Lowest Number: ' & $iLowestNumber & @CRLF) You could set $iHighestNumber to a really high number rather than using _ArrayMax, assuming the number you enter will always be higher than any number in $aArray. Link to comment Share on other sites More sharing options...
mikell Posted December 27, 2021 Share Posted December 27, 2021 17 minutes ago, Luke94 said: You could set $iHighestNumber to a really high number rather than using _ArrayMax Much simpler indeed Local $a[7] = [-23, -17, 0, 7, 25, 31, 53] $min = 10^6 For $i = 0 to UBound($a)-1 If $a[$i] > 0 Then $min = ($min < $a[$i]) ? $min : $a[$i] Next Msgbox(0,"", $min) Link to comment Share on other sites More sharing options...
Nine Posted December 27, 2021 Share Posted December 27, 2021 As @mikell suggested, you can make it fool-proof by using this (in case you are using very large number or all numbers are negative) : Local $a[7] = [-23, -17, 0, 7, 25, 31, 53] $min = -1 For $i = 0 to UBound($a)-1 If $a[$i] > 0 Then $min = $min < 0 ? $a[$i] : ($a[$i] < $min ? $a[$i] : $min) Next Msgbox(0,"", $min < 0 ? "Not found" : $min) “They did not know it was impossible, so they did it” ― Mark Twain Spoiler Block all input without UAC Save/Retrieve Images to/from Text Monitor Management (VCP commands) Tool to search in text (au3) files Date Range Picker Virtual Desktop Manager Sudoku Game 2020 Overlapped Named Pipe IPC HotString 2.0 - Hot keys with string x64 Bitwise Operations Multi-keyboards HotKeySet Recursive Array Display Fast and simple WCD IPC Multiple Folders Selector Printer Manager GIF Animation (cached) Screen Scraping Multi-Threading Made Easy Link to comment Share on other sites More sharing options...
markyrocks Posted December 29, 2021 Share Posted December 29, 2021 (edited) You could just sort the array in ascending order and then just return the first number >=0 https://www.autoitscript.com/autoit3/docs/libfunctions/_ArraySort.htm Edited December 29, 2021 by markyrocks Spoiler "I Believe array math to be potentially fatal, I may be dying from array math poisoning" Link to comment Share on other sites More sharing options...
RTFC Posted December 29, 2021 Share Posted December 29, 2021 (edited) A slightly more elegant way (and for large arrays, faster than sorting): #include <Array.au3> Global $aArray[7] = [ -23, -17, 0, 7, 25, 31, 53 ] $structIN=dllstructcreate("align 4; int") $structOUT=dllstructcreate("uint", DllStructGetPtr($structIN)) For $rc=0 To UBound($aArray)-1 DllStructSetData($structIN,1,$aArray[$rc] - 1) $aArray[$rc]=1 + DllStructGetData($structOUT,1) Next ConsoleWrite('Lowest Number: ' & _ArrayMin($aArray, 1) & @CRLF) NB of course this would fail for values >= 2GB (in which case you'd use int64/uint64 instead. EDIT: obviously, the above is not speed-optimised, it merely illustrated how the signed/unsigned distinction can be exploited here (so ArrayMin can work), and although the above array operation is reversible, the following snippet is faster than my first example and leaves the array intact (unlike sort): #include <Math.au3> Global $aArray[7] = [ -23, -17, 0, 7, 25, 31, 53 ] $structIN=dllstructcreate("align 4; int") $structOUT=dllstructcreate("uint", DllStructGetPtr($structIN)) $min=0x7fffffff For $rc=0 To UBound($aArray)-1 DllStructSetData($structIN,1,$aArray[$rc] - 1) $min = _Min(1 + DllStructGetData($structOUT,1),$min) Next ConsoleWrite("Lowest positive value: " & $min) Edited December 30, 2021 by RTFC My Contributions and Wrappers Spoiler BitMaskSudokuSolver BuildPartitionTable CodeCrypter CodeScanner DigitalDisplay Eigen4AutoIt FAT Suite HighMem MetaCodeFileLibrary OSgrid Pool RdRand SecondDesktop SimulatedAnnealing Xbase I/O Link to comment Share on other sites More sharing options...
junkew Posted December 29, 2021 Share Posted December 29, 2021 Is it homework? Whats the bigger context Can your arrays be bigger? Do you need speed? Is your array precoded or coming from a file or database? You could sort first run 1/n the size of the array in steps of n and add more compares in the same loop (probably not faster) .... You cannot run in parallel in AutoIt (you could however embed C#) markyrocks 1 FAQ 31 How to click some elements, FAQ 40 Test automation with AutoIt, Multithreading CLR .NET Powershell CMDLets Link to comment Share on other sites More sharing options...
markyrocks Posted December 29, 2021 Share Posted December 29, 2021 (edited) 10 hours ago, RTFC said: A slightly more elegant way (and for large arrays, faster than sorting): _ArraySort is pretty well optimized. If speed is the issue it could very easily be found in one pass. #include <Array.au3> Global $aArray[7] = [ -23, -17, 0, 7, 25, 31, 53 ] $min=0xfffffff for $i in $aArray $min=(($i<$min) and ($i>0)) ? $i : $min Next ConsoleWrite($min) If sort is always too expensive to use then...using autoit is too expensive. I may have bungled the ternary I don't have a editor in front of me. Edited December 30, 2021 by markyrocks Spoiler "I Believe array math to be potentially fatal, I may be dying from array math poisoning" Link to comment Share on other sites More sharing options...
Nine Posted December 29, 2021 Share Posted December 29, 2021 That is all very cute assumptions. With and without elegance : expandcollapse popup#include <Array.au3> Global $array[200000] GenerateArray($array) Local $hTimer = TimerInit() Example1() ConsoleWrite("#1 = " & TimerDiff($hTimer) & @CRLF) Local $hTimer = TimerInit() Example2() ConsoleWrite("#2 = " & TimerDiff($hTimer) & @CRLF) Func Example1() $structIN = DllStructCreate("align 4; int") $structOUT = DllStructCreate("uint", DllStructGetPtr($structIN)) For $rc = 0 To UBound($array) - 1 DllStructSetData($structIN, 1, $array[$rc] - 1) $array[$rc] = 1 + DllStructGetData($structOUT, 1) Next ConsoleWrite('Lowest #1 = ' & _ArrayMin($array, 1) & @CRLF) EndFunc ;==>Example1 Func Example2() $min = -1 For $i = 0 To UBound($array) - 1 If $array[$i] > 0 Then $min = $min < 0 ? $array[$i] : ($array[$i] < $min ? $array[$i] : $min) Next ConsoleWrite("Lowest #2 = " & $min & @CRLF) EndFunc ;==>Example2 Func GenerateArray(ByRef $a) For $i = 0 To UBound($a) - 1 $a[$i] = Random(-1000000, +1000000, 1) Next EndFunc ;==>GenerateArray Guess what would be faster markyrocks 1 “They did not know it was impossible, so they did it” ― Mark Twain Spoiler Block all input without UAC Save/Retrieve Images to/from Text Monitor Management (VCP commands) Tool to search in text (au3) files Date Range Picker Virtual Desktop Manager Sudoku Game 2020 Overlapped Named Pipe IPC HotString 2.0 - Hot keys with string x64 Bitwise Operations Multi-keyboards HotKeySet Recursive Array Display Fast and simple WCD IPC Multiple Folders Selector Printer Manager GIF Animation (cached) Screen Scraping Multi-Threading Made Easy Link to comment Share on other sites More sharing options...
markyrocks Posted December 30, 2021 Share Posted December 30, 2021 (edited) 1 hour ago, Nine said: That is all very cute assumptions. With and without elegance : Guess what would be faster I like this game its called I win. gawd I had no idea what a dog these array udf functions were.... maybe your results will vary but as far as i can tell #3 is the winner... I'm not sure how this array min function can be such a ball and chain . expandcollapse popup#include <Array.au3> Global $array[200000] GenerateArray($array) Local $hTimer = TimerInit() Example1() ConsoleWrite("#1 = " & TimerDiff($hTimer) & @CRLF) Local $hTimer = TimerInit() Example2() ConsoleWrite("#2 = " & TimerDiff($hTimer) & @CRLF) Local $hTimer = TimerInit() Example3() ConsoleWrite("#3 = " & TimerDiff($hTimer) & @CRLF) Local $hTimer = TimerInit() Example5() ConsoleWrite("#5 = " & TimerDiff($hTimer) & @CRLF) Func Example1() $structIN = DllStructCreate("align 4; int") $structOUT = DllStructCreate("uint", DllStructGetPtr($structIN)) For $rc = 0 To UBound($array) - 1 DllStructSetData($structIN, 1, $array[$rc] - 1) $array[$rc] = 1 + DllStructGetData($structOUT, 1) Next ConsoleWrite('Lowest #1 = ' & _ArrayMin($array, 1) & @CRLF) EndFunc ;==>Example1 Func Example2() $min = -1 For $i = 0 To UBound($array) - 1 If $array[$i] > 0 Then $min = $min < 0 ? $array[$i] : ($array[$i] < $min ? $array[$i] : $min) Next ConsoleWrite("Lowest #2 = " & $min & @CRLF) EndFunc ;==>Example2 Func GenerateArray(ByRef $a) For $i = 0 To UBound($a) - 1 $a[$i] = Random(-1000000, +1000000, 1) Next EndFunc ;==>GenerateArray Func Example3() $min=0xfffffff for $i in $array $min=(($i<$min) and ($i>0)) ? $i : $min Next ConsoleWrite("lowest #3 = " & $min & @CRLF) EndFunc func Example4() _ArraySort($array) for $i in $array if $i>0 then ConsoleWrite("lowest #4 = " & $i & @CRLF) ExitLoop EndIf Next EndFunc func Example5() for $i in $array $i = $i < 0 ? not $i : $i Next ConsoleWrite("lowest #5 = " & _ArrayMin($array) & @CRLF) EndFunc the difference between these 2 is like 10 seconds.... func Example5() $min=0xfffffff for $i in $array $i = $i < 0 ? not $i : $i Next for $i in $array ;loops throught TWICE!! $min=$i<$min ? $i : $min Next ConsoleWrite("lowest #5 = " & $min & @CRLF) EndFunc func Example6() for $i in $array $i = $i < 0 ? not $i : $i Next ConsoleWrite("lowest #6 = " & _ArrayMin($array) & @CRLF) EndFunc Edited December 30, 2021 by markyrocks Spoiler "I Believe array math to be potentially fatal, I may be dying from array math poisoning" Link to comment Share on other sites More sharing options...
pseakins Posted December 30, 2021 Share Posted December 30, 2021 (edited) 1 hour ago, markyrocks said: I like this game its called I win. I guess you guys must be all bored with nothing better to do over the Xmas break. I deliberately refrained from supplying a solution to OP as this looked much like a homework question and he can't learn if he doesn't apply himself to the problem in hand. @mikell's solution is even better that what I would have come up with. I often forget that you can use C's "conditional expression" in AutoIt. Edited December 30, 2021 by pseakins Credited wrong member. TheDcoder 1 Phil Seakins Link to comment Share on other sites More sharing options...
markyrocks Posted December 30, 2021 Share Posted December 30, 2021 total insanity. a million ints vs 200k in 5% of the time? 3 seconds vs 66....the only word that comes to mind is broken... i'll report back in a few min and post a python comparison. In my defense this is why noone else in the modern broader coding community is afraid to use sort. Spoiler "I Believe array math to be potentially fatal, I may be dying from array math poisoning" Link to comment Share on other sites More sharing options...
markyrocks Posted December 30, 2021 Share Posted December 30, 2021 I used an online compiler to test a couple of these I know that can slightly mess with the results, I'm kinda skeptical of the python result but I tested it in c , c#, c++, and python. I just don't have it in me to write it in java... I was actually thinking about the way I imagine the qsort algorithm works... I might have to play around with that. Spoiler "I Believe array math to be potentially fatal, I may be dying from array math poisoning" Link to comment Share on other sites More sharing options...
junkew Posted December 30, 2021 Share Posted December 30, 2021 Interesting to see 3 and 6 are competing in speed based on arraysize and number 8 is the winner 😉 so far in this christmas break context 😉 * Added code so only the fastest examples are run expandcollapse popup#include <Array.au3> Global $array[200000] GenerateArray($array) Func GenerateArray(ByRef $a) For $i = 0 To UBound($a) - 1 $a[$i] = Random(-1000000, +1000000, 1) Next EndFunc ;==>GenerateArray ;~ Just run the examples relevant for $fName in stringsplit("example3,example6,example7,example8",",",2) Local $hTimer = TimerInit() call($fName) If @error = 0xDEAD And @extended = 0xBEEF Then consolewrite($fname & " Function does not exist.") exitloop EndIf ConsoleWrite( "#" & $fName & " = " & TimerDiff($hTimer) & @CRLF) Next Func Example1() $structIN = DllStructCreate("align 4; int") $structOUT = DllStructCreate("uint", DllStructGetPtr($structIN)) For $rc = 0 To UBound($array) - 1 DllStructSetData($structIN, 1, $array[$rc] - 1) $array[$rc] = 1 + DllStructGetData($structOUT, 1) Next ConsoleWrite('Lowest #1 = ' & _ArrayMin($array, 1) & @CRLF) EndFunc ;==>Example1 Func Example2() $min = -1 For $i = 0 To UBound($array) - 1 If $array[$i] > 0 Then $min = $min < 0 ? $array[$i] : ($array[$i] < $min ? $array[$i] : $min) Next ConsoleWrite("Lowest #2 = " & $min & @CRLF) EndFunc ;==>Example2 Func Example3() $min=0xfffffff for $i in $array $min=(($i<$min) and ($i>0)) ? $i : $min Next ConsoleWrite("lowest #3 = " & $min & @CRLF) EndFunc func Example4() _ArraySort($array) for $i in $array if $i>0 then ConsoleWrite("lowest #4 = " & $i & @CRLF) ExitLoop EndIf Next EndFunc func Example5() for $i in $array $i = $i < 0 ? not $i : $i Next ConsoleWrite("lowest #5 = " & _ArrayMin($array) & @CRLF) EndFunc Func Example6() $min = -1 $uBoundArr=UBound($array) - 1 For $i = 0 To $uBoundArr $min = $array[$i] > 0 ? ($min < 0 ? $array[$i] : ($array[$i] < $min ? $array[$i] : $min)) : $min Next ConsoleWrite("Lowest #6 = " & $min & @CRLF) EndFunc ;==>Example6 Func Example7() $min = -1 $uBoundArr=UBound($array) - 1 For $i = $uBoundArr to 0 step -1 $min = $array[$i] > 0 ? ($min < 0 ? $array[$i] : ($array[$i] < $min ? $array[$i] : $min)) : $min Next ConsoleWrite("Lowest #7 = " & $min & @CRLF) EndFunc ;==>Example7 Func Example8() $min = 0xfffffff $uBoundArr=UBound($array) - 1 For $i = $uBoundArr to 0 step -1 $min = $array[$i] > 0 ? ($min > $array[$i] ? $array[$i] : $min) : $min next ConsoleWrite("Lowest #8 = " & $min & @CRLF) EndFunc ;==>Example8 FAQ 31 How to click some elements, FAQ 40 Test automation with AutoIt, Multithreading CLR .NET Powershell CMDLets Link to comment Share on other sites More sharing options...
markyrocks Posted December 31, 2021 Share Posted December 31, 2021 (edited) 8 hours ago, junkew said: Interesting to see 3 and 6 are competing in speed based on arraysize and number 8 is the winner 😉 so far in this christmas break context 😉 * Added code so only the fastest examples are run HAHA!! 8 was the winner ... until example9 came along... bazinga Func Example9() $min=0xfffffff for $i in $array $min= -$i > 0 ? $min : ($i < $min ? $i : $min ) Next ConsoleWrite("Lowest #9 = " & $min & @CRLF) EndFunc ;==>Example9 edit this is actually a hair faster it seems Func Example10() $min=0xfffffff for $i in $array $min= $i < 0 ? $min : ($i < $min ? $i : $min ) Next ConsoleWrite("Lowest #10 = " & $min & @CRLF) EndFunc ;==>Example9 Edited December 31, 2021 by markyrocks Spoiler "I Believe array math to be potentially fatal, I may be dying from array math poisoning" Link to comment Share on other sites More sharing options...
markyrocks Posted December 31, 2021 Share Posted December 31, 2021 (edited) ok so I'm just going to say this rn bc I know you all will think im full of it but.... I decided to give making a little dll for autoit to play with... and the results are just staggering. I'll post the autoit code with my added example 11 under the hidey thing. edit. notice how 9 and 10 ate shit on the run i screenshotted. Spoiler expandcollapse popup#include <Array.au3> Global $size = 1000000;<==ONE MILLION Global $array[$size] GenerateArray($array) $struct=GenerateDllStruct() Func GenerateArray(ByRef $a) For $i = 0 To UBound($a) - 1 $a[$i] = Random(-1000000, +1000000, 1) Next EndFunc ;==>GenerateArray func GenerateDllStruct() $s=DllStructCreate("int[" & $size & "]") For $i=1 to $size DllStructSetData($s,1,$array[$i-1],$i) Next return $s EndFunc ;~ Just run the examples relevant for $fName in stringsplit("example3,example6,example7,example8,example9,example10,example11",",",2) Local $hTimer = TimerInit() call($fName) If @error = 0xDEAD And @extended = 0xBEEF Then consolewrite($fname & " Function does not exist.") exitloop EndIf ConsoleWrite( "#" & $fName & " = " & TimerDiff($hTimer) & @CRLF) Next Func Example1() $structIN = DllStructCreate("align 4; int") $structOUT = DllStructCreate("uint", DllStructGetPtr($structIN)) For $rc = 0 To UBound($array) - 1 DllStructSetData($structIN, 1, $array[$rc] - 1) $array[$rc] = 1 + DllStructGetData($structOUT, 1) Next ConsoleWrite('Lowest #1 = ' & _ArrayMin($array, 1) & @CRLF) EndFunc ;==>Example1 Func Example2() $min = -1 For $i = 0 To UBound($array) - 1 If $array[$i] > 0 Then $min = $min < 0 ? $array[$i] : ($array[$i] < $min ? $array[$i] : $min) Next ConsoleWrite("Lowest #2 = " & $min & @CRLF) EndFunc ;==>Example2 Func Example3() $min=0xfffffff for $i in $array $min=(($i<$min) and ($i>0)) ? $i : $min Next ConsoleWrite("lowest #3 = " & $min & @CRLF) EndFunc func Example4() _ArraySort($array) for $i in $array if $i>0 then ConsoleWrite("lowest #4 = " & $i & @CRLF) ExitLoop EndIf Next EndFunc func Example5() for $i in $array $i = $i < 0 ? not $i : $i Next ConsoleWrite("lowest #5 = " & _ArrayMin($array) & @CRLF) EndFunc Func Example6() $min = -1 $uBoundArr=UBound($array) - 1 For $i = 0 To $uBoundArr $min = $array[$i] > 0 ? ($min < 0 ? $array[$i] : ($array[$i] < $min ? $array[$i] : $min)) : $min Next ConsoleWrite("Lowest #6 = " & $min & @CRLF) EndFunc ;==>Example6 Func Example7() $min = -1 $uBoundArr=UBound($array) - 1 For $i = $uBoundArr to 0 step -1 $min = $array[$i] > 0 ? ($min < 0 ? $array[$i] : ($array[$i] < $min ? $array[$i] : $min)) : $min Next ConsoleWrite("Lowest #7 = " & $min & @CRLF) EndFunc ;==>Example7 Func Example8() $min = 0xfffffff $uBoundArr=UBound($array) - 1 For $i = $uBoundArr to 0 step -1 $min = $array[$i] > 0 ? ($min > $array[$i] ? $array[$i] : $min) : $min next ConsoleWrite("Lowest #8 = " & $min & @CRLF) EndFunc ;==>Example8 Func Example9() $min=0xfffffff for $i in $array $min= -$i > 0 ? $min : ($i < $min ? $i : $min ) Next ConsoleWrite("Lowest #9 = " & $min & @CRLF) EndFunc ;==>Example9 Func Example10() $min=0xfffffff for $i in $array $min= $i < 1 ? $min : ($i < $min ? $i : $min ) Next ConsoleWrite("Lowest #10 = " & $min & @CRLF) EndFunc ;==>Example10 Func Example11() $dll=DllOpen(@ScriptDir & "\autoitdll.dll") if $dll=-1 then Exit $result=DllCall($dll,"int:cdecl","_ArrayMinGreaterThanZero","ptr",DllStructGetPtr($struct),"int",$size) ;~ if IsArray($result) then _ArrayDisplay($result) ConsoleWrite("Lowest #11 = " & $result[0] & @CRLF) EndFunc This screenshot shows how much of disparity there is and I'm fairly confident that I could pretty easily fix the arraysort buisness. I've offered to help fix things in the past. It usually doesn't go well. Anyways. I guess I'll include the file. autoitdll.dll Edited December 31, 2021 by markyrocks Spoiler "I Believe array math to be potentially fatal, I may be dying from array math poisoning" Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now