Jump to content
Sign in to follow this  
Phaser

Find matching indexe sets in 2d array

Recommended Posts

Phaser

Hi Guys

I am looking for certain patterns in an array, I have array columns that I loop through then perform a search on each column, each column contains the following data, I am looking for the groups of 1's

start [0,0,1,0,1,0,1,1,0,1,0,1,1,1,0,1,0,0] end

What I want to do is go from the start and get the following info

$first_single = 2

$first_double = 6 ; as 6&7 are ones

$first_triple = 11; as 11,12,&13 are ones

With Euphoria (I think) you can search an array with {1,1,1} to match the pattern. I can't find anything like that in the help file for Autoit so was wondering what is the best way to perform the above, hope that makes sense, _ArraySearch will only find the first 1, _ArrayFindAll returns all indexes with 1's so I end up with, for the above

[2,4,6,7,9,11,12,13,15]

Is there an easier way?

Share this post


Link to post
Share on other sites
Mat

My iniitial thoughts were something like: (untested code!)

#include <Array.au3>

Local $a[18] = [0,0,1,0,1,0,1,1,0,1,0,1,1,1,0,1,0,0]

Local $iMaxSequence
Local $aFirst[$iMaxSequence]
Local $iStart

For $i = 0 To UBound($a) - 1
    If $a[$i] = 1 Then
        If $iStart >= 0 Then
            If $i - $iStart <= $iMaxSequence Then
                If Not $aFirst[$i - $iStart - 1] Then
                    $aFirst[$i - $iStart - 1] = $iStart
                EndIf
        Else
            ; Set the start to current index.
            $iStart = $i
        EndIf
    EndIf
Next

_ArrayDisplay

But then I had this idea: (again, code not tested)

#include <Array.au3>

Local $a[18] = [0,0,1,0,1,0,1,1,0,1,0,1,1,1,0,1,0,0]
Local $s = _ArrayToString($a, "") ; "001010110101110100"

Local $first_single = StringInStr($s, "1")
Local $first_double = StringInStr($s, "11")
Local $first_triple = StringInStr($s, "111")

...

Share this post


Link to post
Share on other sites
Phaser

Hi Mat

Yes I also thought about arraytostring but will it work on a 2d array? I am looping through a 2d array 1 column at a time

Local $history[150][32]

$i = 0
Do
$a = _ArrayFindAll($history,1,0,150,0,0,$i);find all 1's
;it was a single
;it was a double
;it was a triple
$i = $i+1
Until $i = 32

Thats what I had in mind anyway, possible?

Share this post


Link to post
Share on other sites
Xenobiologist

Hi,

you can also convert them into strings

Global $Array[3][3] = [['a', 'b', 'c'],['d', 'e', 'f'],['g', 'h', 'i']]
Global $str = '', $str2 = ''
Global $trenn = ';'
For $i = 0 To UBound($Array) - 1
For $j = 0 To UBound($Array, 2) - 1
  $str &= $Array[$i][$j] & $trenn
Next
Next
$str = StringTrimRight($str, 1) ; letztes Trennzeichen wieder abschneiden
ConsoleWrite($str & @CRLF)
For $j = 0 To UBound($Array) - 1
For $i = 0 To UBound($Array, 2) - 1
  $str2 &= $Array[$i][$j] & $trenn
Next
Next
$str2 = StringTrimRight($str2, 1) ; letztes Trennzeichen wieder abschneiden
ConsoleWrite($str2& @CRLF)

Scripts & functions Organize Includes Let Scite organize the include files

Yahtzee The game "Yahtzee" (Kniffel, DiceLion)

LoginWrapper Secure scripts by adding a query (authentication)

_RunOnlyOnThis UDF Make sure that a script can only be executed on ... (Windows / HD / ...)

Internet-Café Server/Client Application Open CD, Start Browser, Lock remote client, etc.

MultipleFuncsWithOneHotkey Start different funcs by hitting one hotkey different times

Share this post


Link to post
Share on other sites
Phaser

Thanks Xenobiologist, but do you think its the right way for what I am after?

Share this post


Link to post
Share on other sites
Spiff59

And another (persons) stab at it:

Local $array[24][2] =  [[0,1],[0,1],[1,1],[0,1],[1,0],[0,1],[1,1],[1,1],[0,1],[1,1],[0,0],[1,1], _
      [1,1],[1,1],[0,1],[1,1],[0,1],[0,1],[1,1],[1,1],[1,0],[1,0],[1,0],[0,1]]
Local $arraylen = UBound($array), $cnt
For $col = 0 to 1; number of columns to search
 For $len = 1 to $arraylen ; check for patterns from 1 to max length of array
  $cnt = $len
  For $row = 0 to $arraylen - 1
   If $array[$row][$col] Then
    $cnt -= 1
   Else
    If $cnt = 0 Then ExitLoop
    $cnt = $len
   EndIf
  Next
  If $cnt = 0 Then
   ConsoleWrite("In column " & String($col) & ", the first " & $len & "-byte occurance was at position " & $row - $len & @CRLF)
  Endif
 Next
Next

Edit: I'd like to know how Mat is retaining the indentation and formatting on his pasted code snippets!

Manually editing them after the paste? I lose most of the spaces/tabs/blank lines :graduated:

Edit2: changed a couple lines to not expect matching groups to occur in order from smallest to largest (guessing at requirements)

Edited by Spiff59

Share this post


Link to post
Share on other sites
Xenobiologist

Why not? String functions are very fast in Autoit - FMPOV much faster than dealing with the array functions.

So, converting your arrays to strings and then search for the doubles and tribles and so on, should be a fine.


Scripts & functions Organize Includes Let Scite organize the include files

Yahtzee The game "Yahtzee" (Kniffel, DiceLion)

LoginWrapper Secure scripts by adding a query (authentication)

_RunOnlyOnThis UDF Make sure that a script can only be executed on ... (Windows / HD / ...)

Internet-Café Server/Client Application Open CD, Start Browser, Lock remote client, etc.

MultipleFuncsWithOneHotkey Start different funcs by hitting one hotkey different times

Share this post


Link to post
Share on other sites
Mat

For someone who works a lot with low level languages, I find it quite hard to get my head around using strings for everything. But there are enough examples on the forum of people using strings to speed things up that it is now pretty common practice to use strings. The only time people shy away from them is when you want to keep the data types, which is not the case here

Share this post


Link to post
Share on other sites
Phaser

Thanks guys, I am sure I will get it working with whats been posted, I agree strings are quicker, thanks again for all the help.

Share this post


Link to post
Share on other sites
Phaser

ok this isn't going to plan, strings wont work as they find the 1st 1 even if the 1 has anothe r1 after it. So I have returned to _ArrayFindAll but can't get my head around how to walk through it, heres what I have

#include <Array.au3>
Local $a[7] = [0,1,4,6,8,9,10] ; result of arrayfindall, for example purposes
 
  $j = 0
  Do
   If $a[$j]+1 = $a[$j+1] Then;find last single
  
   Else
    MsgBox(0,"box", " last single " & $j+1 )
    $j = 149
   EndIf
  
  $j = $j+1
  Until $j = 150 Or $j = UBound($a)-1
; find 2 together
; find 3 together

As the result of arrayfindall has returned the indexes where 1's were found 0,1,4,6,8,9,10

I would expect/like my results to be

$last_single = 3 ; the 4 was found

$last_double = 1 ; 0,1 means numerically they were good

$last_triple = 5 ; 8,9,10 are a sequence of 3

Note: the 150 is the amount of data rows my main array will eventually hold, with 32 columns across, I hope this makes sense to someone

Edited by Phaser

Share this post


Link to post
Share on other sites
Xenobiologist

Hi,

it is no problem with strings to find the 1 even if there is a 1 after that.

Mega


Scripts & functions Organize Includes Let Scite organize the include files

Yahtzee The game "Yahtzee" (Kniffel, DiceLion)

LoginWrapper Secure scripts by adding a query (authentication)

_RunOnlyOnThis UDF Make sure that a script can only be executed on ... (Windows / HD / ...)

Internet-Café Server/Client Application Open CD, Start Browser, Lock remote client, etc.

MultipleFuncsWithOneHotkey Start different funcs by hitting one hotkey different times

Share this post


Link to post
Share on other sites
Mat

Do you mean you want to find the last single, double, triple, ...

If so then StringInStr will work if you set the occurrence parameter to -1

Share this post


Link to post
Share on other sites
Spiff59

Did you try the code in post #6?

Granted, string functions may be faster than array functions, but they (almost*) assuredly aren't faster than no functions.

(* = what portion is running natively, and how much is interpreted, could affect the accuracy of my statement)

Edit: have you reversed your requirement from the first post? last group instead of first?

Edited by Spiff59

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
Sign in to follow this  

×