Leaderboard
Popular Content
Showing content with the highest reputation on 12/25/2022 in all areas
-
Rotating values within an array [SOLVED]
pixelsearch reacted to TimRude for a topic
Suppose I have a 1-D array with a number of values in it such as Local $aArray[] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] Then I want to select one of the values that should become the new first element, with the other elements rotating into new positions while keeping the array size the same. For example, if I wanted $aArray[4] to become $aArray[0] and end up with an array that looks like this: 4 5 6 7 8 9 0 1 2 3 What would be the most efficient way to accomplish this, keeping in mind that the actual arrays I want to do this with will be much larger than this little sample one. Here's a working method I've come up with using _ArrayExtract and _ArrayConcatenate but I'm not sure if there's a better way. #include <Array.au3> Local $aArray[] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] _ArrayDisplay($aArray, "BEFORE rotation") _ArrayRotate($aArray, 4) _ArrayDisplay($aArray, "AFTER rotation") Exit Func _ArrayRotate(ByRef $aArray, $iMakeFirst) ; $aArray = array to be rotated ; $iMakeFirst = element number to be rotated into position [0] ; Returns True if successful, False if not If Not IsArray($aArray) Then Return False ; invalid array If ($iMakeFirst < 0) Or ($iMakeFirst > UBound($aArray) - 1) Then Return False ; $iMakeFirst parameter is out of bounds If $iMakeFirst = 0 Then Return True ; no rotation needed, it's already the first element Local $aFirst = _ArrayExtract($aArray, $iMakeFirst) Local $aLast = _ArrayExtract($aArray, 0, $iMakeFirst - 1) Local $iResult = _ArrayConcatenate($aFirst, $aLast) If $iResult <> -1 Then $aArray = $aFirst Return True Else Return False EndIf EndFunc ;==>_ArrayRotate1 point -
To complete the results: @jchd Your ArrMove method averaged 24.3164 ms @Werty Your method averaged 73.2607 ms - thanks for pulling me out of last place! 😁 The other methods that convert the array to a delimited string I'm going to rule out (for me) because of the danger of scrambled results due to a delimiter character possibly being within the array data. Those methods have certainly presented some interesting approaches, but I don't think they're 100% reliable. So in order of speed, with the fastest at the top, we've ended up with: pixelsearch jchd Danp2 TimRude Werty Also, it may be worth noting for posterity's sake that while I asked about doing this for a 1D array, the methods used by pixelsearch and myself will also handle 2D arrays, whereas the others work on 1D arrays only. Thanks everyone for your examples!1 point
-
Doubling the array... #Include <Array.au3> Local $aArray[] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] _ArrayRotate($aArray, 4) Func _ArrayRotate(ByRef $aArray, $iShift) Local $aArray2[] = $aArray _ArrayAdd($aArray2, $aArray) For $i = 0 To UBound($aArray) - 1 $aArray[$i] = $aArray2[$i + $iShift] Next EndFunc _ArrayDisplay($aArray)1 point
-
Local $aArray[] = ["000", "100", "200", "300", "400", "500", "600", "700", "800", "900"] _ArrayDisplay(__ArrayRotate($aArray, 4)) Func __ArrayRotate(ByRef $aArray, $iIndex, $sSeparator = '|') Return StringRegExp(StringRegExpReplace(_ArrayToString($aArray, $sSeparator), '(.*?)\'& $sSeparator &'(?=' & $aArray[$iIndex] & ')(.*)', _ '$2\' & $sSeparator & '$1'), '([^\' & $sSeparator & ']+)', 3) EndFunc1 point
-
My version uses only ArrayToString, ArrayFromString and string functions. It won't rotate if the default delimiter is found in the array. #include <Array.au3> Local $aArray[] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] _ArrayDisplay($aArray, "BEFORE rotation") If _ArrayRotate($aArray, 4) Then _ArrayDisplay($aArray, "AFTER rotation") Else MsgBox(Default, Default, "Array did not rotate!") EndIf Exit Func _ArrayRotate(ByRef $aArray, $iMakeFirst) ; $aArray = array to be rotated ; $iMakeFirst = element number to be rotated into position [0] ; Returns True if successful, False if not If Not IsArray($aArray) Then Return False ; invalid array If ($iMakeFirst < 0) Or ($iMakeFirst > UBound($aArray) - 1) Then Return False ; $iMakeFirst parameter is out of bounds If $iMakeFirst = 0 Then Return True ; no rotation needed, it's already the first element If StringInStr(_ArrayToString($aArray, ""), "|") Then Return False ; default delimiter found in array Local $sArray = _ArrayToString($aArray) Local $iPos = StringInStr($sArray, "|", $STR_NOCASESENSE, $iMakeFirst) Local $sFirst = StringLeft($sArray, $iPos - 1) Local $sLast = StringRight($sArray, StringLen($sArray) - $iPos) $aArray = _ArrayFromString($sLast & "|" & $sFirst) Return True EndFunc ;==>_ArrayRotate1 point
-
Leave the array alone and access its elements using an offset and Mod() the array size. Local $aOrig = [0,1,2,3,4,5,6,7,8,9] Func ArrOfs(ByRef $a, $iOfs, $iIdx) Return($a[Mod($iOfs + $iIdx, UBound($a))]) EndFunc ConsoleWrite("New element of $aOrig at index 0 is " & ArrOfs($aOrig, 4, 0) & @LF) ConsoleWrite("New element of $aOrig at index 7 is " & ArrOfs($aOrig, 4, 7) & @LF) ; if you really need to permanently change the array, elements index offset by $n: Func ArrMove(ByRef $a, $n) Local $iSize = UBound($a) Local $b[$iSize] For $i = 0 To $iSize - 1 $b[$i] = $a[Mod($i + $n, $iSize)] Next $a = $b EndFunc ArrMove($aOrig, 4) _ArrayDisplay($aOrig)1 point
-
Hi guys/girls! I'm gonna share this UDF I made today. It allows you to easily create TCP servers and set actions depending on three events: OnConnect, OnDisconnect and OnReceive. It is also multi client (you can set the clients limit) and you can also bind a Console-based executable to the socket (similar to -e parameter in NetCat). This feature is useful if you want to use some Console UDF to create your TCP server and don't want to mix it with the TCP functions. Also, as it runs on background just firing events, it won't pause your script while listening/receiving, so you can do anything else (stop and restart the server, allow the user to click buttons or just wait on an infinite loop) that your callbacks will be called once the event is fired. It's also very easy to use. See this examples: Example #1: A basic server By running this (then connecting to the server using Netcat), you will receive a message box telling you when some user connects or disconnects (the socket ID and his IP address is passed as parameter to your callback function) and also when the user sends something over the TCP socket (the data sent is passed as parameter). #cs Download netcat at https://eternallybored.org/misc/netcat/ Execute this script Run in CMD: nc -vv 127.0.0.1 8081 #ce #include "TCPServer.au3" ; First we set the callback functions for the three events (none of them is mandatory) _TCPServer_OnConnect("connected") _TCPServer_OnDisconnect("disconnect") _TCPServer_OnReceive("received") ; And some parameters _TCPServer_DebugMode(True) _TCPServer_SetMaxClients(10) ; Finally we start the server at port 8081 at any interface _TCPServer_Start(8081) Func connected($iSocket, $sIP) MsgBox(0, "Client connected", "Client " & $sIP & " connected!") _TCPServer_Broadcast('new client connected guys', $iSocket) _TCPServer_Send($iSocket, "Hey! Write something ;)" & @CRLF) _TCPServer_SetParam($iSocket, "will write") EndFunc ;==>connected Func disconnect($iSocket, $sIP) MsgBox(0, "Client disconnected", "Client " & $sIP & " disconnected from socket " & $iSocket) EndFunc ;==>disconnect Func received($iSocket, $sIP, $sData, $sPar) MsgBox(0, "Data received from " & $sIP, $sData & @CRLF & "Parameter: " & $sPar) _TCPServer_Send($iSocket, "You wrote: " & $sData) _TCPServer_SetParam($iSocket, 'will write again') EndFunc ;==>received While 1 Sleep(100) WEnd Example #2: A basic HTTP server (just one page, as it is just an example) In this example, we run this code and point our browser to the address mentioned on the comments. A basic "It works!" page is show. #cs Run this script Point your browser to http://localhost:8081/ #ce #include "TCPServer.au3" _TCPServer_OnReceive("received") _TCPServer_DebugMode(True) _TCPServer_SetMaxClients(10) _TCPServer_Start(8081) Func received($iSocket, $sIP, $sData, $sParam) _TCPServer_Send($iSocket, "HTTP/1.0 200 OK" & @CRLF & _ "Content-Type: text/html" & @CRLF & @CRLF & _ "<h1>It works!</h1>" & @CRLF & _ "<p>This is the default web page for this server.</p>" & @CRLF & _ "<p>However this server is just a 26-lines example.</p>") _TCPServer_Close($iSocket) EndFunc ;==>received While 1 Sleep(100) WEnd Example #3: A telnet-like server (Command Prompt bound to the socket after password requesting) By running this example and connecting with Netcat, we will be asked for a password, which is 12345 as we set on the script. If the password is correct, we will see the Command Prompt live-updated (try running a ping to some server, for example). #cs Download netcat at https://eternallybored.org/misc/netcat/ Execute this script Run in CMD: nc -vv 127.0.0.1 8081 #ce #include "TCPServer.au3" Global $sPassword = "12345" ; input server password here _TCPServer_OnConnect("connected") _TCPServer_OnDisconnect("disconnect") _TCPServer_OnReceive("received") _TCPServer_DebugMode(True) _TCPServer_SetMaxClients(10) _TCPServer_Start(8081) Func connected($iSocket, $sIP) _TCPServer_Send($iSocket, "Welcome! Please input password: ") _TCPServer_SetParam($iSocket, 'login') EndFunc ;==>connected Func disconnect($iSocket, $sIP) MsgBox(0, "Client disconnected", "Client " & $sIP & " disconnected from socket " & $iSocket) EndFunc ;==>disconnect Func received($iSocket, $sIP, $sData, $sParam) If $sParam = "login" Then If $sData <> $sPassword Then _TCPServer_Send($iSocket, "Wrong password. Try again: ") Return Else _TCPServer_SetParam($iSocket, 'command') _TCPServer_BindAppToSocket($iSocket, 'cmd.exe') EndIf ElseIf $sParam = "command" Then _TCPServer_SendToBound($iSocket, $sData) EndIf EndFunc ;==>received While 1 Sleep(100) WEnd The limit is your imagination? Well, no sure. We have this limit: You can't create more than one server with this UDF in the same script. However, you can pause and resume (read 'stop and start again') your server at any time in your script, without having to reset the server settings. And of course you can have many clients (or just one, it's your choice!) in the same server. Or run multiple instances.Functions list: _TCPServer_Start _TCPServer_Stop _TCPServer_Close _TCPServer_Send _TCPServer_Broadcast _TCPServer_SetParam _TCPServer_BindAppToSocket _TCPServer_SendToBound _TCPServer_UnBindAppToSocket _TCPServer_GetMaxClients _TCPServer_IsServerActive _TCPServer_ListClients _TCPServer_OnConnect _TCPServer_OnDisconnect _TCPServer_OnReceive _TCPServer_SetMaxClients _TCPServer_DebugMode _TCPServer_AutoTrim _TCPServer_SocketToIP _TCPServer_SocketToConnID _TCPServer_ConnIDToSocket Help file and more examples included! Latest version: 1.0.0.1 Download: TCPServer UDF.rar Changelog 1.0 - First release - 18/04/20151.0.0.1 - Bug fix __TCPServer_Accept internal function / help file recompiled - 26/04/2015Perhaps you will need to uncompress the file first, so the help file will work. Fork this on Github: http://github.com/jesobreira/TCPServerUDF TCPServer UDF.rar1 point
-
Upload Image WinHttp
zenmark22 reacted to MadaraUchiha for a topic
Its marked as solved but if you have a better solution please tell me:)1 point