Jump to content
rootx

Which is the fastest method to compare two array

Recommended Posts

rootx

I write this script to compare to array, well Do you have a better way to do it?

#include <Constants.au3>
#include <Array.au3>
#include <File.au3>
#include <MsgBoxConstants.au3>

$a = FileSelectFolder("seleziona cartella A",@ScriptDir)
$fold_A = _FileListToArrayRec($a,"*",2,1,0,1)

$b = FileSelectFolder("seleziona cartella B",@ScriptDir)

$fold_B = _FileListToArrayRec($b,"*",2,1,0,1)

$tota = UBound($fold_A)-1
$totb = UBound($fold_B)-1

If $tota > $totb Then
    findx($fold_A,$fold_B)
Else
    findx($fold_B,$fold_A)
EndIf


Func findx($min,$max)
    For $i = 0 To UBound($min)-1
        $found = _ArraySearch($max, $min[$i])
        If $found = -1 Then
            ConsoleWrite($min[$i]&@CRLF)
        EndIf
    Next
EndFunc

 

Share this post


Link to post
Share on other sites
SlackerAl

I'm a bit of an AutoIT novice, so excuse the lack of code examples. I think your problem depends on the relative sizes of the two arrays. If one of the arrays is small (2-10 items), then your method is quite effective, the problem will occur when the two arrays are of significant and similar sizes.

If you have a couple of arrays holding 100 000 items each, then that becomes a very large comparison. You could improve things quite a bit by sorting the arrays first and then dividing them into manageable buckets of data. For example, if your stored data is alpanumeric then make 36 arrays, depending on the first letter of your data 0-9 a-z. Then you only have to compare your "a" bucket to your "a" bucket. The overhead of creating the buckets versus your simplistic search of the entire range will depend on the data... 

Any help?

Edit: You don't need to split the smaller array into buckets, just the large one, then iterate the small one.

Second Edit (sorry!): Obviously this can be more sophisticated, if you don't have a uniform data distribution, change your strategy - you want to try and make the buckets near uniform size.

Edited by SlackerAl
  • Like 1

Problem solving step 1: Write a simple, self-contained, running, replicator of your problem.

Share this post


Link to post
Share on other sites
SlackerAl

Seems an intermediate solution (in terms of effort) would be to sort the large array and then use _ArrayBinarySearch perhaps?

  • Like 1

Problem solving step 1: Write a simple, self-contained, running, replicator of your problem.

Share this post


Link to post
Share on other sites
mikell

You might have a look at this thread. For comparing 1D arrays the Scripting.Dictionary way is by far much faster  :)

  • Like 1

Share this post


Link to post
Share on other sites
rootx

Like this..

 

#include <Constants.au3>
#include <Array.au3>
#include <File.au3>
#include <MsgBoxConstants.au3>

$a = FileSelectFolder("seleziona cartella A",@ScriptDir)
$fold_A = _FileListToArrayRec($a,"*",2,1,0,1)

$b = FileSelectFolder("seleziona cartella B",@ScriptDir)

$fold_B = _FileListToArrayRec($b,"*",2,1,0,1)

$tota = UBound($fold_A)-1
$totb = UBound($fold_B)-1

If $tota > $totb Then
    findx($fold_A,$fold_B)
Else
    findx($fold_B,$fold_A)
EndIf


Func findx($min,$max)
    _ArraySort($min, 0, 1)
    _ArraySort($max, 0, 1)
    For $i = 0 To UBound($min)-1
        $found = _ArrayBinarySearch($max, $min[$i], 1)
        If $found = -1 Then
            ConsoleWrite($i&" "&$min[$i]&@CRLF)
        EndIf
    Next
EndFunc

 

Share this post


Link to post
Share on other sites
junkew

not tested but something like below.

Better way is hard to say as that depends on your requirements, speed wanted etc. maybe powershell is quicker on the cmdline just comparing 2 folders.

#include <Constants.au3>
#include <Array.au3>
#include <File.au3>
#include <MsgBoxConstants.au3>

$a = FileSelectFolder("seleziona cartella A",@ScriptDir)
$fold_A = _FileListToArrayRec($a,"*",2,1,0,1)

$b = FileSelectFolder("seleziona cartella B",@ScriptDir)

$fold_B = _FileListToArrayRec($b,"*",2,1,0,1)

$tota = UBound($fold_A)-1
$totb = UBound($fold_B)-1

_ArraySort($fold_a, 0, 1)
_ArraySort($fold_b, 0, 1)

$i=1
$j=1
while ($i < $totA) or ($j<totB)
    if $fold_a[$i]=$fold_b[$j] then
       consolewrite("Equal")
       $i=$i+1
       $j=$j+1
    elseif $fold_a[$i]<$fold_b[$j] then
            consolewrite("Not Equal")
            $i=$i+1
    else
            consolewrite("Not Equal")
            $j=$j+1
    endif
wend

Share this post


Link to post
Share on other sites
jchd

It all depends on what you call "equal" applied to arrays.

In my book, [London", "Paris", "Melbourne"] is definitely not equal to [London", "Melbourne", "Paris"]. Both arrays contain the same elements but they are certainly not equal. Similarly to itineraries, a picture on screen isn't equal to the same picture once flipped or with all pixels moved around.

It's only when you consider 1D arrays and call them sets that {4, 31, 9} = {9, 4, 31}


This wonderful site allows debugging and testing regular expressions (many flavors available). An absolute must have in your bookmarks.
Another excellent RegExp tutorial. Don't forget downloading your copy of up-to-date pcretest.exe and pcregrep.exe here
RegExp tutorial: enough to get started
PCRE v8.33 regexp documentation latest available release and currently implemented in AutoIt beta.

SQLitespeed is another feature-rich premier SQLite manager (includes import/export). Well worth a try.
SQLite Expert (freeware Personal Edition or payware Pro version) is a very useful SQLite database manager.
An excellent eBook covering almost every aspect of SQLite3: a must-read for anyone doing serious work.
SQL tutorial (covers "generic" SQL, but most of it applies to SQLite as well)
A work-in-progress SQLite3 tutorial. Don't miss other LxyzTHW pages!
SQLite official website with full documentation (may be newer than the SQLite library that comes standard with AutoIt)

Share this post


Link to post
Share on other sites
rootx

I just have to compare the contents of two folders. With a sort of arrays before the loop for the comparison gets fast, _ArrayBinarySearch run very fats, 4 example in this moment I run a diff for to folders with 26.186 files, 172 folders TOT 249 GB I have a correct result in a few seconds.

With winmerge.... after 15 min I have 50% of total process....

Another method could be the C++ memcmp function.

Thx guys.

Share this post


Link to post
Share on other sites
mikell

?

#include <Constants.au3>
#include <Array.au3>
#include <File.au3>

$a = FileSelectFolder("seleziona cartella A",@ScriptDir)
$fold_A = _FileListToArrayRec($a,"*",2,1,0,1)

$b = FileSelectFolder("seleziona cartella B",@ScriptDir)
$fold_B = _FileListToArrayRec($b,"*",2,1,0,1)

local $big = (UBound($fold_A)>UBound($fold_B)) ? $fold_A : $fold_B
local $small = (UBound($fold_A)<=UBound($fold_B)) ? $fold_A : $fold_B
findx($small, $big)

Func findx($min, $max)
  Local $sd = ObjCreate("Scripting.Dictionary")
  $sd.CompareMode = 1   ; case insensitive
  For $i In $max
      $sd.Item($i)
  Next
  For $i In $min
      If $sd.Exists($i) Then $sd.Remove($i)
  Next
  $asd = $sd.Keys()
  _ArrayDisplay($asd, "$asd")
EndFunc

 

  • Like 1

Share this post


Link to post
Share on other sites
rootx

Your approach is a bit faster, it would be nice to do a test with a huge amount and variety of data to understand the differences in practical terms. :drool:

Share this post


Link to post
Share on other sites
water
18 minutes ago, rootx said:

I just have to compare the contents of two folders. With a sort of arrays before the loop for the comparison gets fast, _ArrayBinarySearch run very fats, 4 example in this moment I run a diff for to folders with 26.186 files, 172 folders TOT 249 GB I have a correct result in a few seconds.

With winmerge.... after 15 min I have 50% of total process....

15 minutes?
Does this mean you not just compare the file and directory names but the file contents as well?
Just comparing the file/directory names should happen in under a minute.


My UDFs and Tutorials:

Spoiler

UDFs:
Active Directory (NEW 2018-06-01 - Version 1.4.9.0) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX (2018-01-27 - Version 1.3.3.1) - Download - General Help & Support - Example Scripts - Wiki
ExcelChart (2015-04-01 - Version 0.4.0.0) - Download - General Help & Support - Example Scripts
Excel - Example Scripts - Wiki
Word - Wiki
PowerPoint (2015-06-06 - Version 0.0.5.0) - Download - General Help & Support

Tutorials:
ADO - Wiki

 

Share this post


Link to post
Share on other sites
mikell

If the amount of data is really huge then maybe it's worth a try to the SQLite way (untested, possible typos...)

#include <SQLite.au3>
;#include <SQLite.dll.au3>
#include <Array.au3>

$a = FileSelectFolder("seleziona cartella A",@ScriptDir)
$fold_A = _FileListToArrayRec($a,"*",2,1,0,1)

$b = FileSelectFolder("seleziona cartella B",@ScriptDir)
$fold_B = _FileListToArrayRec($b,"*",2,1,0,1)

 $res = _ArrayCompareAndGetData($fold_A, $fold_B, 1)
 _ArrayDisplay($res)
 $res = _ArrayCompareAndGetData($fold_A, $fold_B, 0)
 _ArrayDisplay($res)


;==============================================================
; $flag = 1 : return items from array1 which don't exist in array2 (with index)
; $flag = 2 : return items from array2 which don't exist in array1 (with index)
; $flag = 0 : return both
;==============================================================

Func _ArrayCompareAndGetData($array1, $array2, $flag = 0)
  If (not IsArray($array1) AND $array1<>"") OR _ 
    (not IsArray($array2) AND $array2<>"") Then Return SetError(1, 0, 0)
  If $flag < 0 OR $flag > 2 Then $flag = 0
  If $array2 = "" Then $flag = 1  ;Return SetError(2, 0, $array1)
  If $array1 = "" Then Return SetError(3, 0, $array2)
  Local $array, $aTemp, $iRows, $iColumns
  _SQLite_Startup()
  _SQLite_Open()   ; ':memory:'
  _SQLite_Exec (-1, "CREATE TABLE table1 (id, items1); CREATE TABLE table2 (id, items2);") 
  _SQLite_Exec(-1, "Begin;")
  For $i = 0 to UBound($array1)-1
        _SQLite_Exec(-1, "INSERT INTO table1 VALUES (" & $i & ", " & _SQLite_FastEscape($array1[$i]) & ");")
  Next
  For $i = 0 to UBound($array2)-1
        _SQLite_Exec(-1, "INSERT INTO table2 VALUES (" & $i & ", " & _SQLite_FastEscape($array2[$i]) & ");")
  Next
  _SQLite_Exec(-1, "Commit;")

 Switch $flag
   Case 1
     _SQLite_GetTable2d(-1, "SELECT * FROM table1 WHERE items1 NOT IN (SELECT items2 FROM table2) ;", $array, $iRows, $iColumns)   
      $array[0][0] = UBound($array)-1
      $array[0][1] = ""

   Case 2
     _SQLite_GetTable2d(-1, "SELECT * FROM table2 WHERE items2 NOT IN (SELECT items1 FROM table1) ;", $array, $iRows, $iColumns)  
      $array[0][0] = UBound($array)-1
      $array[0][1] = ""

   Case 0
     _SQLite_GetTable2d(-1, "SELECT * FROM table1 WHERE items1 NOT IN (SELECT items2 FROM table2) ;", $array, $iRows, $iColumns)   
     _SQLite_GetTable2d(-1, "SELECT * FROM table2 WHERE items2 NOT IN (SELECT items1 FROM table1) ;", $aTemp, $iRows, $iColumns)  
     Local $n = UBound($array)-1, $m = UBound($aTemp)-1
      Local $s = ($n > $m) ? $n : $m
      Redim $array[$s+1][4]
      For $i = 0 to $m
        $array[$i][2] = $aTemp[$i][0]
        $array[$i][3] = $aTemp[$i][1]
      Next
      $array[0][0] = $n
      $array[0][1] = ""
      $array[0][2] = $m
      $array[0][3] = ""

 EndSwitch

  _SQLite_Close()
  _SQLite_Shutdown()
    Return $array
EndFunc

 

Share this post


Link to post
Share on other sites
iamtheky

@junkew got me thinking powershell

#include <AutoItConstants.au3>

$folderA="'DIRTEST\A'"
$folderB="'DIRTEST\B'"

$iPid = run("cmd /c powershell $dir1 = " & $folderA & " ; $dir2 = " & $folderB & " ; $d1 = get-childitem -path $dir1 -recurse ; $d2 = get-childitem -path $dir2 -recurse ; (compare-object $d1 $d2)" ,"" ,@SW_HIDE, $STDOUT_CHILD)

$sOut = ""

While 1
    $sOut &= StdoutRead($iPID)
    If @error Then ExitLoop
WEnd

msgbox(0, '' , $sOut)

DiffTwoDirectories.PNG

Edited by iamtheky

,-. .--. ________ .-. .-. ,---. ,-. .-. .-. .-.
|(| / /\ \ |\ /| |__ __||| | | || .-' | |/ / \ \_/ )/
(_) / /__\ \ |(\ / | )| | | `-' | | `-. | | / __ \ (_)
| | | __ | (_)\/ | (_) | | .-. | | .-' | | \ |__| ) (
| | | | |)| | \ / | | | | | |)| | `--. | |) \ | |
`-' |_| (_) | |\/| | `-' /( (_)/( __.' |((_)-' /(_|
'-' '-' (__) (__) (_) (__)

Share this post


Link to post
Share on other sites
jchd
6 hours ago, rootx said:

With a sort of arrays before the loop for the comparison gets fast, _ArrayBinarySearch run very fast.

With initial sorting you don't even have to use dichotomy (_ArrayBinarySearch) for comparing contents, as just a linear scan of both arrays in parallel will do. You gain a log2 N factor.


This wonderful site allows debugging and testing regular expressions (many flavors available). An absolute must have in your bookmarks.
Another excellent RegExp tutorial. Don't forget downloading your copy of up-to-date pcretest.exe and pcregrep.exe here
RegExp tutorial: enough to get started
PCRE v8.33 regexp documentation latest available release and currently implemented in AutoIt beta.

SQLitespeed is another feature-rich premier SQLite manager (includes import/export). Well worth a try.
SQLite Expert (freeware Personal Edition or payware Pro version) is a very useful SQLite database manager.
An excellent eBook covering almost every aspect of SQLite3: a must-read for anyone doing serious work.
SQL tutorial (covers "generic" SQL, but most of it applies to SQLite as well)
A work-in-progress SQLite3 tutorial. Don't miss other LxyzTHW pages!
SQLite official website with full documentation (may be newer than the SQLite library that comes standard with AutoIt)

Share this post


Link to post
Share on other sites
LarsJ

If there is only one row in one of the arrays and 100,000 rows in the other array, I doubt that a linear search is faster on average.

Even with the same number of rows in the two arrays, it's easy to make examples where a binary search is faster. It depends on the data.

  • Like 1

Share this post


Link to post
Share on other sites
jchd

I do mean what I wrote: "a linear scan of both arrays in parallel".


This wonderful site allows debugging and testing regular expressions (many flavors available). An absolute must have in your bookmarks.
Another excellent RegExp tutorial. Don't forget downloading your copy of up-to-date pcretest.exe and pcregrep.exe here
RegExp tutorial: enough to get started
PCRE v8.33 regexp documentation latest available release and currently implemented in AutoIt beta.

SQLitespeed is another feature-rich premier SQLite manager (includes import/export). Well worth a try.
SQLite Expert (freeware Personal Edition or payware Pro version) is a very useful SQLite database manager.
An excellent eBook covering almost every aspect of SQLite3: a must-read for anyone doing serious work.
SQL tutorial (covers "generic" SQL, but most of it applies to SQLite as well)
A work-in-progress SQLite3 tutorial. Don't miss other LxyzTHW pages!
SQLite official website with full documentation (may be newer than the SQLite library that comes standard with AutoIt)

Share this post


Link to post
Share on other sites
junkew

Lot of focus on the solution comparing 2 arrays not sure if the solution is right to the problem

But looking at the problem it seems to be

  • n folders with m files
  • find the duplicates and report the folder?

Solution direction with 1 array

dir c: /b /s > c_files.txt

or

dir c:\folder1 /b /s > files.txt
dir c:\folder2 /b /s >> files.txt

and then some code as a solution direction to validate (not run/tested)

  • missing part to sort it first (but then i need 2 columns: one with filename and 1 with foldername)
#include <Constants.au3>
#include <Array.au3>
#include <File.au3>
#include <MsgBoxConstants.au3>

Run(@ComSpec & " /k dir c:\tmp")

$sFilePath = @TempDir & "\filedata.txt"

FileReadToArray($sFilePath, $aRetArray)

$totA = ubound($aRetArray)

$i=1
while ($i < $totA-1)
    if $aRetArray[$i]=$aRetArray[$i+1] then
       consolewrite("Duplicate file")
       $i=$i+1
    endif
wend

 

Share this post


Link to post
Share on other sites
LarsJ

Comparing two arrays in two ways: Binary search and linear scan:

;#AutoIt3Wrapper_UseX64=y

#AutoIt3Wrapper_Au3Check_Parameters=-d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6

Opt( "MustDeclareVars", 1 )

;#include <Array.au3>

Example()

Func Example()
  ; Read 10,000 unique ascendingly sorted strings into $aAr1
  Local $aAr1 = FileReadToArray( "tst00.txt" )
  Local $iRows = UBound( $aAr1 )
  ;_ArrayDisplay( $aAr1 )

  For $i = 0 To $iRows - 2
    If $aAr1[$i] = $aAr1[$i+1] Then ConsoleWrite( "Strings " & $i & " and " & $i + 1 & " are identical" & @CRLF )
  Next

  ; Copy 100 uniformly distributed strings from $aAr1 into $aAr2
  ; Add a "x" to every second string to make them different
  ; $aAr2 is also unique and ascendingly sorted
  ; 50 identical strings in $aAr1 and $aAr2
  ; 50 different strings in $aAr1 and $aAr2
  Local $aAr2[100]
  For $i = 0 To 99
    $aAr2[$i] = $aAr1[$i*100+99]
    If Mod( $i, 2 ) Then $aAr2[$i] &= "x"
  Next
  ;_ArrayDisplay( $aAr2 )

  Local $hTimer, $t, $t1 = 0, $t2 = 0
  Local $s, $lo, $hi, $mi
  Local $iTests = 10

  For $k = 0 To $iTests - 1

    ; Compare $aAr1 and $aAr2 through
    ; a binary search and a linear scan.
    ; It's utilized that both arrays are sorted.

    ; Binary search
    $mi = -1
    $hTimer = TimerInit()
    For $i = 0 To 99
      $s = $aAr2[$i]
      For $j = $mi + 1 To $iRows - 1
        $lo = $j
        $hi = $iRows - 1
        Do
          $mi = Int( ( $lo + $hi ) / 2 )
          Switch StringCompare( $s, $aAr1[$mi] )
            Case -1
              $hi = $mi - 1
            Case  1
              $lo = $mi + 1
            Case  0
              ;ConsoleWrite( "Found OK: $i, $mi, $s = " & $i & ", " & $mi & ", " & $s & @CRLF )
              ExitLoop 2
          EndSwitch
        Until $lo > $hi
        ;ConsoleWrite( "Found NO: $i, $mi, $s = " & $i & ", " & $mi & ", " & $s & @CRLF )
        ExitLoop
      Next
    Next
    $t = TimerDiff( $hTimer )
    ConsoleWrite( "Test " & $k & " Binary search: " & $t & @CRLF )
    $t1 += $t

    ; Linear scan
    $j = -1
    $hTimer = TimerInit()
    For $i = 0 To 99
      $s = $aAr2[$i]
      For $j = $j + 1 To $iRows - 1
        Switch StringCompare( $aAr1[$j], $s )
          Case  0
            ;ConsoleWrite( "Found OK: $i, $j, $s = " & $i & ", " & $j & ", " & $s & @CRLF )
            ExitLoop
          Case 1
            ;ConsoleWrite( "Found NO: $i, $j, $s = " & $i & ", " & $j & ", " & $s & @CRLF )
            ExitLoop
        EndSwitch
      Next
    Next
    $t = TimerDiff( $hTimer )
    ConsoleWrite( "Test " & $k & " Linear scan:   " & $t & @CRLF )
    $t2 += $t

  Next

  ConsoleWrite( @CRLF )
  ConsoleWrite( "Average Binary search: " & $t1/$iTests & @CRLF )
  ConsoleWrite( "Average Linear scan:   " & $t2/$iTests & @CRLF )
EndFunc

 

Console output:

Test 0 Binary search: 2.74602585342339
Test 0 Linear scan:   10.0892624626688
Test 1 Binary search: 2.6498927853102
Test 1 Linear scan:   9.90807794812693
Test 2 Binary search: 3.73727691310346
Test 2 Linear scan:   12.7233639370786
Test 3 Binary search: 2.68950958283235
Test 3 Linear scan:   10.5594002626344
Test 4 Binary search: 2.70751721806969
Test 4 Linear scan:   10.0164008000931
Test 5 Binary search: 4.07360413122856
Test 5 Linear scan:   9.97927736744995
Test 6 Binary search: 2.5834030552031
Test 6 Linear scan:   9.90918611029538
Test 7 Binary search: 2.49724344660598
Test 7 Linear scan:   9.86818411006267
Test 8 Binary search: 2.49004039251104
Test 8 Linear scan:   9.85100759645166
Test 9 Binary search: 2.56511837942365
Test 9 Linear scan:   9.85322392078857

Average Binary search: 2.87396317577114
Average Linear scan:   10.275738451565

 

Anything wrong with code or results?

tst00.au3 and tst00.txt: Arrays.7z

 

What about 2D arrays?

Edited by LarsJ

Share this post


Link to post
Share on other sites
czardas

Binary search only works if the elements have been  sorted. Since initial sorting is required, then a linear scan (comparison) should be faster. How can it be otherwise?

Edit: I believe the problem with the code is that you start the linear scan at element 0 on each run. You are testing the same elements over and over again.

Edited by czardas

Share this post


Link to post
Share on other sites
LarsJ

From around post 5 it has been assumed that both arrays are sorted.

I do not start the linear scan at element 0 on each run. I'm not testing the same elements over and over again. Read the code.

And I'm pretty sure nothing is wrong with the code. It was a rhetorical question.

Share this post


Link to post
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

  • Similar Content

    • HardXOR
      By HardXOR
      Hello AutoIt community
      I run into speed problem in my script wich i cant solve myself, problem is with decoding texture loop - for better explanation, you need extract from file pallete (16x 16 RGB color) and picture data (224 * 128 byte), then use correct color for your picture data.... nothing extra hard and also texture is quite small 224*256
      it is for my car model viewer/later maybe editor GranTurismo 2 from Playstation 1, so its old dataformat and i cant understand why AutoIt take so long to decode texture when good old Playstation almost 2,5 decades old can do that nearly immediately (when you list through cars in shop or garage)
      My first atempt was create all trought dllstructure, because its easier approach, but it was soooo slow (40-50s for create textures) then i upgrade my routine via arrays, first 3D arrays later only 1D, next i put decoding colors outside loop but it is still not enough, my last version took cca 15s wich is still unacceptable for car model viewer when you click on one carmodel from listview (1100 cars for whole game) and you must wait 15-16s for model to load....  oh and i forgot mention some cars have more then 1 color (much more... 8-9-10 etc) soloading take 8-9-10 times more time
      in attachment i post texture file from GranTurismo 2 for one car (contain only 1 color) and also my dll struct version and array version code
      dll struct version - ± 40 sec (33 without saving)
      #include <FileConstants.au3> Global $IMDT[256][256][4] LoadTexture("ufs9r.cdp") Func LoadTexture($file) $fileHandle = FileOpen($file, $FO_BINARY) $header = FileRead($fileHandle, 0x20) ConsoleWrite("header> " & $header & @CRLF) $PAL = FileRead($fileHandle, 0x200) ConsoleWrite("PAL> " & $PAL & @CRLF) FileSetPos($fileHandle, 0x43A0, $FILE_BEGIN) $IMD = FileRead($fileHandle, 0x7000) ConsoleWrite("IMD> " & $IMD & @CRLF) $st = DllStructCreate("BYTE[512]") DllStructSetData($st, 1, $PAL) $struct_PAL = DllStructCreate("WORD[16];WORD[16];WORD[16];WORD[16];WORD[16];WORD[16];WORD[16];WORD[16];WORD[16];WORD[16];WORD[16];WORD[16];WORD[16];WORD[16];WORD[16];WORD[16]", DllStructGetPtr($st)) $struct_IMD = DllStructCreate("BYTE[" & 0x7000 & "]") DllStructSetData($struct_IMD, 1, $IMD) $start = TimerInit() For $i = 0 To 15 For $j = 0 To 223 $cn = 0 For $k = 0 To 127 $bt = DllStructGetData($struct_IMD, 1, $j * 128 + $k + 1) $blue = BitShift(DllStructGetData($struct_PAL, $i + 1, BitAND($bt, 0x0F) + 1), 7) $IMDT[$j][$cn][0] = $blue $green = BitShift(DllStructGetData($struct_PAL, $i + 1, BitAND($bt, 0x0F) + 1), 2) $IMDT[$j][$cn][1] = $green $red = BitShift(DllStructGetData($struct_PAL, $i + 1, BitAND($bt, 0x0F) + 1), - 3) $IMDT[$j][$cn][2] = $red If DllStructGetData($struct_PAL, $i + 1, BitAND($bt, 0x0F) + 1) = 0 Then $IMDT[$j][$cn][3] = 0x00 Else $IMDT[$j][$cn][3] = 0xFF EndIf $cn += 1 $blue = BitShift(DllStructGetData($struct_PAL, $i + 1, BitShift($bt, 4) + 1), 7) $IMDT[$j][$cn][0] = $blue $green = BitShift(DllStructGetData($struct_PAL, $i + 1, BitShift($bt, 4) + 1), 2) $IMDT[$j][$cn][1] = $green $red = BitAND(BitShift(DllStructGetData($struct_PAL, $i + 1, BitShift($bt, 4) + 1), - 3), 0xFF) $IMDT[$j][$cn][2] = $red If DllStructGetData($struct_PAL, $i + 1, BitShift($bt, 4) + 1) = 0 Then $IMDT[$j][$cn][3] = 0x00 Else $IMDT[$j][$cn][3] = 0xFF EndIf $cn += 1 Next Next saveTGA($i) Next ConsoleWrite("t " & TimerDiff($start) & @CRLF) ; +- 40 seconds FileClose($fileHandle) EndFunc Func saveTGA($name) Local $tga[18] = [0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x20, 0x20] Local $data for $i = 0 To 17 $data &= Hex($tga[$i], 2) Next For $i = 0 To 255 For $j = 0 To 255 For $k = 0 To 3 $data &= hex($IMDT[$i][$j][$k], 2) Next Next Next $binary = FileOpen("test\" & $name & ".tga", BitOR($FO_BINARY, $FO_OVERWRITE, $FO_CREATEPATH)) FileWrite($binary, "0x" & $data) FileClose($binary) EndFunc  
      array version - ± 15 sec (under 10s without saving)
      #include <FileConstants.au3> LoadTexture2("ufs9r.cdp") Func LoadTexture2($file) $fileHandle = FileOpen($file, $FO_BINARY) $a = TimerInit() Global $header[0x20] For $i = 0 To UBound($header) - 1 $header[$i] = Int(String(FileRead($fileHandle, 1))) ; read 0x20 bytes Next ConsoleWrite("header " & TimerDiff($a) & @CRLF) $a = TimerInit() Global $PAL[0x100] For $i = 0 To UBound($PAL) - 1 $PAL[$i] = Number(FileRead($fileHandle, 2)) ; read 0x200 (16*16) words Next Global $PALcolor[16 * 16 * 4] For $i = 0 To UBound($PAL) - 1 $PALcolor[$i * 4 + 0] = BitShift($PAL[$i], 7) $PALcolor[$i * 4 + 1] = BitShift($PAL[$i], 2) $PALcolor[$i * 4 + 2] = BitShift($PAL[$i], -3) If $PAL[$i] = 0 Then $PALcolor[$i * 4 + 3] = 0x00 Else $PALcolor[$i * 4 + 3] = 0xFF EndIf Next ConsoleWrite("PAL " & TimerDiff($a) & @CRLF) $a = TimerInit() FileSetPos($fileHandle, 0x43A0, $FILE_BEGIN) Global $IMD[0x7000] For $i = 0 To UBound($IMD) - 1 $IMD[$i] = Int(String(FileRead($fileHandle, 1))) ; read 0x7000 bytes Next ConsoleWrite("IMD " & TimerDiff($a) & @CRLF) Global $IMDT[256*256*4] $a = TimerInit() For $i = 0 To 15 For $j = 0 To 223 $cn = 0 For $k = 0 To 127 $byte = $IMD[$j * 128 + $k] ; byte for decode $index = $j * 1024 + $cn * 4 $index2 = $i * 0x40 + BitAND($byte, 0x0F) * 4 $IMDT[$index + 0] = $PALcolor[$index2 + 0] ; blue $IMDT[$index + 1] = $PALcolor[$index2 + 1] ; green $IMDT[$index + 2] = $PALcolor[$index2 + 2] ; red $IMDT[$index + 3] = $PALcolor[$index2 + 3] ; alpha $cn += 1 $index = $j * 1024 + $cn * 4 $index2 = $i * 0x40 + BitShift($byte, 4) * 4 $IMDT[$index + 0] = $PALcolor[$index2 + 0] ; blue $IMDT[$index + 1] = $PALcolor[$index2 + 1] ; green $IMDT[$index + 2] = $PALcolor[$index2 + 2] ; red $IMDT[$index + 3] = $PALcolor[$index2 + 3] ; alpha $cn += 1 Next Next ;~ $b = TimerInit() saveTGA2($i) ;~ ConsoleWrite("save TGA " & TimerDiff($b) & @CRLF) Next ConsoleWrite("full time " & TimerDiff($a) & @CRLF) ; 16 seconds FileClose($fileHandle) EndFunc Func saveTGA2($name) Local $tga[18] = [0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x20, 0x20] Local $data For $i = 0 To 17 $data &= Hex($tga[$i], 2) Next For $i = 0 To UBound($IMDT) - 1 $data &= Hex($IMDT[$i], 2) Next $binary = FileOpen("test\" & $name & ".tga", BitOR($FO_BINARY, $FO_OVERWRITE, $FO_CREATEPATH)) FileWrite($binary, "0x" & $data) FileClose($binary) EndFunc if anyone can optimize my code I would be very grateful, or pointing me to better solution, thx
      ufs9r.cdp
    • FMS
      By FMS
      Hello,
      Does somebody knows a quick way to split eash word to an array in a text?
      I've a text and want to have each word in that text in an array.

      I tried to get in some way multiple seperators inside stringsplit but couldn't get it to work.
      I hope to get an array like :
      $aArray[0] = "PARIJS"
      $aArray[1] = "AFN"
      $aArray[2] = "Air"
      ....
      sample text: PARIJS (AFN) - Air France-KLM heeft de financieel directeur van het Franse nuts- en vervoersbedrijf Veolia, Philipe Capron, in het vizier om de nieuwe topman van de luchtvaartcombinatie te worden. Volgens de krant La Tribune wordt Capron als favoriet beschouwd om de topfunctie te gaan vervullen. AdChoices Advertentie Volgens bronnen tegen La Tribune is de keuze voor Capron zelfs al gemaakt door Air France-KLM en zal zijn voordracht volgende week worden voorgelegd aan de raad van toezicht bij het bedrijf. Capron zou dan de opvolger worden van de opgestapte topman Jean-Marc Janaillac. In mei trad Janaillac af nadat het hem niet was gelukt buiten de bonden om zaken te doen met het eigen personeel. Sindsdien heeft een interim-bestuur de dagelijkse leiding. De zestigjarige Capron is sinds 2014 financieel directeur bij Veolia. Daarvoor werkte hij onder meer bij mediaconcern Vivendi. Minder macht Overigens zijn er ook geruchten dat de nieuwe topman van Air France-KLM direct een zetel zou krijgen in de raad van commissarissen van KLM. Binnen de Nederlandse divisie, die juist alles op alles zet om minder macht naar Parijs te laten vloeien, is men volgens ingewijden verbolgen over die gang van zaken. ,,Stank voor dank", zo klinkt het in de wandelgangen. Eerder zou Janaillac ook al hebben geprobeerd om een dikkere vinger in de pap te krijgen bij KLM, dat door de bank genomen beter presteert dan haar Franse zustermaatschappij. Dit lukte eerder niet, onder meer door inmenging van het Nederlandse kabinet. AdChoices Advertentie Geruchten Een woordvoerder van Air France-KLM wilde niet reageren op de geruchtenstroom. Het concern gaat er vanuit dat binnen afzienbare tijd een nieuwe bestuursvoorzitter benoemd zal worden. Minister Cora van Nieuwenhuizen (Infrastructuur) wilde evenmin ingaan op geruchten. ,,Ik heb hierover nog geen contact gehad met KLM, dus dat wil ik eerst even afwachten'', zei ze. Tweede Kamerleden spraken deze week tijdens een debat nog maar eens hun zorg uit over de ontwikkelingen bij Air France-KLM. Zij drongen aan op herbevestiging van oude afspraken over de relatief zelfstandige positie van KLM binnen de groep.>Exit code: 0 Time: 28.52  
    • VollachR
      By VollachR
      Hi,
      I'm looking for a way to take a number value from a Row2 of a 2D array and according to this check if files that appear in rows 3-11 in the array exists.
      For example, if the number in Row2 is 5 I need to check for the files in Row 3-6 only, if it is 6 than rows 3-7 and so on.
      I thought on using a FOR loop but I have very little experience with those.
      Can you suggest the best way to do what I need?
      BTW, the files in Rows 3-11 will usually have blank value for any row above the number in Row2 (e.g. Row2 = 5 so Rows3-6 will have values but 8-11 be empty), The values I need are in Column 1 of the array, the name of the key from the INI file that the array was created from is in Column 0.
      Full Example:
      Row2 of Array:
      Col0 = Games# - Col1 = 5
      Rows3-6
      Col0 = Exe2 - Col1 = Path To File
      Col0 = Exe3 - Col1 = Path To File
      Col0 = Exe4 - Col1 = Path To File
      Col0 = Exe5 - Col1 = Path To File
      I need that if Row2 is 5 to check these above for rows if the file exists, if it was 6 then the next row as well and so on up until number 10 in Row2 as it can't go above 10.
      So basically for whatever number in Row2 from 2-10 need to check 1-9 rows from 3-11 to see if the files in Col1 exists and if any of them don't exist it should call a function that shows an error message.
      I'm pretty sure I have the first line of the for look correct:
      For $i = 1 To $aAIO[2][1] Just not sure how to continue from there, also not sure if $i should be equal 1 or 2.
      Help will be appreciated.
    • FMS
      By FMS
      Hello,
      I'm trying to get data from twitter to an array and so far I found an Twitter UDF whish lookes very intresting but couldn't get it to work.
      It lookes not supported any more(2010) and buggy when i read all te replies.
      More around this subject (autoit and twitter) i couldn't find on this forum.
      Is there sombody who know's a good way to get live data from twitter to an array inside autoit?
      (I kinda doubt that this isn't tackled before)
      In the end I was hoping to get all tweets from date to date from an specific subject inside a 2D array to work whit.
    • AndreasNWWWWW
      By AndreasNWWWWW
      I got a question:  i am trying to run different functions based upon what i select in these radio buttons.(code below)
      it needs to check server 1. then run function 1 or function 2 after what i selected in the checkbox.
      once that function is done it moves to the next one, until it has been trough all 5 
       
      iv'e tried using while loops with different while $i equals to something but then i manualy need to go in and edit the script every time.
      #include <ButtonConstants.au3> #include <GUIConstantsEx.au3> #include <StaticConstants.au3> #include <WindowsConstants.au3> #Region ### START Koda GUI section ### Form= $Form1 = GUICreate("Form1", 615, 437, 192, 124) $Server2 = GUICtrlCreateLabel("Server2", 216, 95, 41, 17) $server1 = GUICtrlCreateLabel("Server1", 216, 72, 41, 17) $server4 = GUICtrlCreateLabel("Server4", 216, 144, 41, 17) $server3 = GUICtrlCreateLabel("Server3", 216, 119, 41, 17) $server5 = GUICtrlCreateLabel("Server5", 216, 170, 41, 17) $Start = GUICtrlCreateButton("Start", 240, 248, 147, 25) $Checkbox1 = GUICtrlCreateCheckbox("function1", 288, 72, 97, 17) $Checkbox2 = GUICtrlCreateCheckbox("function2", 392, 72, 97, 17) $Checkbox3 = GUICtrlCreateCheckbox("function1", 288, 96, 97, 17) $Checkbox4 = GUICtrlCreateCheckbox("function2", 392, 96, 97, 17) $Checkbox5 = GUICtrlCreateCheckbox("function1", 288, 120, 97, 17) $Checkbox6 = GUICtrlCreateCheckbox("function2", 392, 120, 97, 17) $Checkbox7 = GUICtrlCreateCheckbox("function1", 288, 144, 97, 17) $Checkbox8 = GUICtrlCreateCheckbox("function2", 392, 144, 97, 17) $Checkbox9 = GUICtrlCreateCheckbox("function1", 288, 170, 97, 17) $Checkbox10 = GUICtrlCreateCheckbox("function2", 392, 170, 97, 17) GUISetState(@SW_SHOW) #EndRegion ### END Koda GUI section ### While 1 $nMsg = GUIGetMsg() Switch $nMsg Case $GUI_EVENT_CLOSE Exit EndSwitch WEnd  
×