Jump to content

All permutations of a collections of bit flags.


Zinthose
 Share

Recommended Posts

Greetings,

I'm trying to determine all the possible permutations of a collection of bit flags so I have all the possible values that Altiris.

Currently I'm using a method to iterate through all int32 values performing a BitAnd looking for matches. This is very inefficient and also takes a long time. Anyone have any tips to speed up the process?

;## Determine all permutations of Bit Flags
#Include <Array.au3>

Global $BaseFlag = 512
Global $SuccessFlags = 0x4 + 0x10 + 0x2000 + 0x20000 + 0x40000

ConsoleWrite("! " & _Permutations($BaseFlag, $SuccessFlags) & @CRLF)

Func _Permutations ($BaseFlag, $SuccessFlags)
    Local $SuccessCodes = ""
    Local $TestNumber = 1
    Local $TestBit = 0
    Local $Pattern = ""
    
    ConsoleWrite("! Please Wait...  This can take a very long time to calculate all possible permutations." & @CRLF)
    
    While True
        $TestBit = BitAND($SuccessFlags, $TestNumber) + $BaseFlag
        $TestBit = BitOR($TestBit, $BaseFlag)
        
        If $TestBit <> 0 Then
            $Pattern = "(\A|,)" & String($TestBit) & "(\z|,)"
            If StringRegExp($SuccessCodes, $Pattern) = 0 Then 
                If $SuccessCodes <> "" Then $SuccessCodes &= ","
                $SuccessCodes &= String($TestBit)
            EndIf
        EndIf
        
        ;$TestBit = BitShift($TestBit, -1)
        If $TestNumber = 0x7FFFFFFF  Or $TestNumber >= $SuccessFlags Then ExitLoop; <== Added "Or $TestNumber >= $SuccessFlags" which will shorten the process time as long as no high value bit flag is in use or even the negative bit.
        $TestNumber += 1
    WEnd

    Return $SuccessCodes
EndFunc
Edited by Zinthose

--- TTFN

Link to comment
Share on other sites

Greetings,

I'm trying to determine all the possible permutations of a collection of bit flags so I have all the possible values that Altiris.

Currently I'm using a method to iterate through all int32 values performing a BitAnd looking for matches. This is very inefficient and also takes a long time. Anyone have any tips to speed up the process?

;## Determine all permutations of Bit Flags
#Include <Array.au3>

Global $BaseFlag = 512
Global $SuccessFlags = 0x4 + 0x10 + 0x2000 + 0x20000 + 0x40000

ConsoleWrite("! " & _Permutations($BaseFlag, $SuccessFlags) & @CRLF)

Func _Permutations ($BaseFlag, $SuccessFlags)
    Local $SuccessCodes = ""
    Local $TestNumber = 1
    Local $TestBit = 0
    Local $Pattern = ""
    
    ConsoleWrite("! Please Wait...  This can take a very long time to calculate all possible permutations." & @CRLF)
    
    While True
        $TestBit = BitAND($SuccessFlags, $TestNumber) + $BaseFlag
        $TestBit = BitOR($TestBit, $BaseFlag)
        
        If $TestBit <> 0 Then
            $Pattern = "(\A|,)" & String($TestBit) & "(\z|,)"
            If StringRegExp($SuccessCodes, $Pattern) = 0 Then 
                If $SuccessCodes <> "" Then $SuccessCodes &= ","
                $SuccessCodes &= String($TestBit)
            EndIf
        EndIf
        
    ;$TestBit = BitShift($TestBit, -1)
        If $TestNumber = 0x7FFFFFFF  Or $TestNumber >= $SuccessFlags Then ExitLoop; <== Added "Or $TestNumber >= $SuccessFlags" which will shorten the process time as long as no high value bit flag is in use or even the negative bit.
        $TestNumber += 1
    WEnd

    Return $SuccessCodes
EndFunc
You only need a bit per value to permutate (5 bits = 32 permutations = .003sec on my computer):
Global $BaseFlag = 512
Global $SuccessFlags[5] = [0x4, 0x10, 0x2000, 0x20000, 0x40000]
$Results = ""
$iTimer = TimerInit()
For $n = 0 To (2^5) - 1
    $Test = $BaseFlag
    For $b = 0 To 4
        If BitAND(2^$b, $n) Then $Test += $SuccessFlags[$b]
    Next
    $Results &= "0x" & Hex($Test,5) & @CRLF
Next
$Results = StringTrimRight($Results, 1)
$nTimer = Round(TimerDiff($iTimer)/1000, 3)
ConsoleWrite("$Results in " & $nTimer & "sec" & @LF & $Results & @LF)

:)

Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law
Link to comment
Share on other sites

You only need a bit per value to permutate (5 bits = 32 permutations = .003sec on my computer):

Global $BaseFlag = 512
Global $SuccessFlags[5] = [0x4, 0x10, 0x2000, 0x20000, 0x40000]
$Results = ""
$iTimer = TimerInit()
For $n = 0 To (2^5) - 1
    $Test = $BaseFlag
    For $b = 0 To 4
        If BitAND(2^$b, $n) Then $Test += $SuccessFlags[$b]
    Next
    $Results &= "0x" & Hex($Test,5) & @CRLF
Next
$Results = StringTrimRight($Results, 1)
$nTimer = Round(TimerDiff($iTimer)/1000, 3)
ConsoleWrite("$Results in " & $nTimer & "sec" & @LF & $Results & @LF)

>_<

Sweet! This is allot faster... now I just need to pick it apart to understand it. :)

--- TTFN

Link to comment
Share on other sites

To enhance your example to make it more visual, added binary output.

Global $BaseFlag = 512
Global $SuccessFlags[5] = [0x4, 0x10, 0x2000, 0x20000, 0x40000]
$Results = ""
$iTimer = TimerInit()
For $n = 0 To (2 ^ 5) - 1
    $Test = $BaseFlag
    For $b = 0 To 4
        If BitAND(2 ^ $b, $n) Then $Test += $SuccessFlags[$b]
    Next
    $Results &= "0x" & Hex($Test, 5) & " = " & Hex2Bin("0x" & Hex($Test, 5)) & @CRLF
Next
;$Results = StringTrimRight($Results, 1)
$nTimer = Round(TimerDiff($iTimer) / 1000, 3)
ConsoleWrite("$Results in " & $nTimer & "sec" & @LF & $Results)

Func Hex2Bin($hex)
    Local $b = ""
    For $i = 1 To 32
        $b = BitAND($hex, 1) & $b
        $hex = BitShift($hex, 1)
    Next
    Return $b
EndFunc   ;==>Hex2Bin
Link to comment
Share on other sites

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 account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...