Jump to content

Find matching indexe sets in 2d array


 Share

Recommended Posts

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?

Link to comment
Share on other sites

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")

...
Link to comment
Share on other sites

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?

Link to comment
Share on other sites

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

Link to comment
Share on other sites

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
Link to comment
Share on other sites

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

Link to comment
Share on other sites

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

Link to comment
Share on other sites

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
Link to comment
Share on other sites

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

Link to comment
Share on other sites

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
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...