Search the Community
Showing results for tags 'heap'.
-
At my work I was creating a music player (truly the project is bigger than it but it doesn't come to the case right now) and, given some conditions, it should start playing songs randomly. I've used Random() function to sort any song from the list, but the "random wasn't so random" sometimes, and some songs used to repeat multiple times, although the song list wasn't so small. So I needed to keep a list of all the played songs. However, I couldn't feed up an array forever as this system I'm working on is meant to work 24/7 with no pause and the array could really reach huge values, while just the latest X values would really be used (to check if a random song was played recently before playing it). So I managed to create this simple stack/buffer/heap script. It works just like Assembly stacks (although the target is totally different). You'll have an array, you can define its max size and start adding items into it. Once the array limit is reached, the first added item is automatically removed, all the other items are reindexed and your new item will then be added. You can also change the array (stack) limit at any time, reset it as well as pull/remove or read the last added item. In the best Assembly stack way, you shouldn't be able to read all the items, except the last added item. But, well, we are talking about AutoIt arrays. It's just a list, where the 0 index brings the actual items count. This means you can easily create loops and read the array as you want (just be very careful if you want to modify the array without _Buffer* functions). It's also useful if you want to generate random values with Random() with repeating values, but they're repeating more than you want (instead of "1-2-2-2-3-1-2-3-4" you would have "1-3-2-4-3-1-2-4" - the values would only start repeating after it's too long since they were generated in last). Here's an example: #inclcude 'buffer.au3' ; the lib #include <Array.au3> ; needed only to do _ArrayDisplay ; Example 1 $aBuffer = _BufferCreate(3) _BufferPush($aBuffer, 12) _BufferPush($aBuffer, 23) _BufferPush($aBuffer, 34) _BufferPush($aBuffer, 45) MsgBox(0, '', _BufferPull($aBuffer)) ; 45 (and remove it) _BufferPush($aBuffer, 56) _BufferPush($aBuffer, 67) _ArrayDisplay($aBuffer) ; Example 2 $aBuffer = _BufferCreate(3) _BufferPush($aBuffer, 12) _BufferPush($aBuffer, 23) _BufferPush($aBuffer, 34) _BufferPush($aBuffer, 45) _BufferChangeLimit($aBuffer, 6) _BufferPush($aBuffer, 56) _BufferPush($aBuffer, 67) _ArrayDisplay($aBuffer) MsgBox(0, "", "Buffer items count: " & _BufferItemsCount($aBuffer) & @CRLF & "Buffer max size: " & _BufferLimit($aBuffer) & @CRLF & "Last item (without pulling/removing it): " & _BufferGetLastItem($aBuffer)) ; Example 3 $aBuffer = _BufferCreate(3) _BufferPush($aBuffer, 'ab') _BufferPush($aBuffer, 'cd') _BufferPush($aBuffer, 'ef') _BufferPush($aBuffer, 'gh') _ArrayDisplay($aBuffer) _BufferReset($aBuffer) _ArrayDisplay($aBuffer) ; Example 4 $aBuffer = _BufferCreate(2) _BufferPush($aBuffer, 'Song 1') _BufferPush($aBuffer, 'Music 2') _BufferPush($aBuffer, 'Hit 3') If _BufferCheckValue($aBuffer, 'Song 1') Then ; False MsgBox(0, "", "Song 1 was played too recently.") EndIf If _BufferCheckValue($aBuffer, 'Music 2') Then ; True MsgBox(0, "", "Music 2 was played too recently.") EndIf The lib source code: #include-once #cs Buffer/stack/heap UDF made by Jefrey <jefrey[at]jefrey.ml> Licensed under WTFPL: http://www.wtfpl.net/txt/copying/ #ce ; Creates a new buffer ; Arguments: $iSize - size of the buffer (limit) Func _BufferCreate($iSize) Local $aBuffer[$iSize+1] $aBuffer[0] = 0 Return $aBuffer EndFunc ; Adds an item to the buffer ; If the buffer limit was reached, then the first item will be removed. ; Arguments: $aBuffer - buffer to change (reference) / $mItem - item to add Func _BufferPush(ByRef $aBuffer, $mItem) If $aBuffer[0]+1 > UBound($aBuffer)-1 Then ; remove first item and reindex $aBuffer[1] = Null For $i = 2 To $aBuffer[0] $aBuffer[$i - 1] = $aBuffer[$i] Next Else $aBuffer[0] += 1 EndIf $aBuffer[$aBuffer[0]] = $mItem Return $aBuffer EndFunc ; Removes the last added item of the buffer and returns its value ; Arguments: $aBuffer - buffer to change (reference) Func _BufferPull(ByRef $aBuffer) If $aBuffer[0] = 0 Then Return $mReturn = $aBuffer[$aBuffer[0]] $aBuffer[$aBuffer[0]] = Null $aBuffer[0] -= 1 Return $mReturn EndFunc ; Returns the actual items count (how many items were added to the buffer, and not its limit) ; Arguments: $aBuffer - the buffer Func _BufferItemsCount($aBuffer) Return $aBuffer[0] EndFunc ; Returns the actual items count (how many items were added to the buffer, and not its limit) ; Arguments: $aBuffer - the buffer Func _BufferGetLastItem($aBuffer) Return $aBuffer[$aBuffer[0]] EndFunc ; Returns the buffer limits (that were set by you) ; Arguments: $aBuffer - the buffer Func _BufferLimit($aBuffer) Return UBound($aBuffer)-1 EndFunc ; Changes a buffer limit ; Arguments: $aBuffer - the buffer to change / $iSize - new buffer size Func _BufferChangeLimit(ByRef $aBuffer, $iSize) ReDim $aBuffer[$iSize + 1] Return $aBuffer EndFunc ; Resets a buffer (removes all items) ; Arguments: $aBuffer - the buffer to change Func _BufferReset(ByRef $aBuffer) Local $j = UBound($aBuffer)-1 For $i = 1 To $j $aBuffer[$i] = Null Next $aBuffer[0] = 0 EndFunc ; Checks if a value exists in a buffer ; Returns: 0 if not found or index (>0) of where it was found Func _BufferCheckValue($aBuffer, $mValue) If Not $aBuffer[0] Then Return 0 For $i = 1 To $aBuffer[0] If $aBuffer[$i] = $mValue Then Return $i Next Return 0 EndFunc