Splitting a Two Dimensional Array

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
MaxAstro
Posts: 557
Joined: 05 Oct 2016, 13:00

Splitting a Two Dimensional Array

20 Jul 2017, 14:57

I've got a problem that's hard to visualize, much less program. I have a script that reads text on the screen and parses it into a two-dimensional array that "maps" the text - that is, each "0" in the array represents a pixel that isn't part of the text, and each "1" represents a pixel that is part of the text. The array is "vertical" instead of "horizontal", because it's easier to parse that way. In other words, a visualization of the array might look like this:

Code: Select all

1,1,1,1,1,1,1
0,0,0,1,0,0,0
0,0,0,1,0,0,0
1,1,1,1,1,1,1
0,0,0,0,0,0,0
1,0,0,0,0,0,1
1,1,1,1,1,1,1
1,0,0,0,0,0,1
0,0,0,0,0,0,0
If you kinda turn your head and squint you can see that says "HI". What I need to do now is split the array into a set of arrays - one for each character. So an "H" array and an "I" array. Each character is always separated by a row of 0's. I also need to preserve a couple pieces of information: How many characters there are, and the position in the original array at which each character starts.

Even just working with two dimensional arrays makes me head hurt, and I'm starting to worry I might need a three-dimensional array to keep track of all this... Can anyone help me at least get started? Just figuring out a good way to split the original array into characters would be extremely helpful.
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

Re: Splitting a Two Dimensional Array

20 Jul 2017, 15:27

I did stuff like this using string manipulation. I replaced multiple 'blank lines' i.e. '0 lines' (or columns) with a special character. But then I went back and replace some of those lines with zeros again. E.g. blank rows/columns equals space between lines/characters. E.g. problem characters = :.

However, an array solution may have advantages perhaps. I hope you get some good responses.

Anyway here's some fun bits of script:

Code: Select all

q::
vText = ;continuation section
(
1,1,1,1,1,1,1
0,0,0,1,0,0,0
0,0,0,1,0,0,0
1,1,1,1,1,1,1
0,0,0,0,0,0,0
1,0,0,0,0,0,1
1,1,1,1,1,1,1
1,0,0,0,0,0,1
0,0,0,0,0,0,0
)
vText := StrReplace(vText, "0", "_")
vText := StrReplace(vText, "1", "#")
vText := StrReplace(vText, ",", "")
MsgBox, % vText
MsgBox, % JEE_StrTranspose(vText)
return

;==================================================

JEE_StrTranspose(vText)
{
	Loop, Parse, vText, `n, `r
	{
		vLen := StrLen(A_LoopField)
		if (A_Index = 1) || (vLen > vMax)
			vMax := vLen
	}
	StrReplace(vText, "`n", "", vCount), vCount += 1
	oArray := {}
	Loop, % vCount
		oArray[A_Index] := ""
	Loop, Parse, vText, `n, `r
	{
		vTemp := A_LoopField
		Loop, % vMax
			oArray[A_Index] .= SubStr(vTemp, A_Index, 1)
	}
	vOutput := ""
	VarSetCapacity(vOutput, StrLen(vText)*2)
	Loop, % vMax
		vOutput .= (A_Index=1?"":"`r`n") oArray[A_Index]
	return vOutput
}
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
MaxAstro
Posts: 557
Joined: 05 Oct 2016, 13:00

Re: Splitting a Two Dimensional Array

20 Jul 2017, 15:55

That's clever, but my goal is not to render the text graphically; rather, I am trying to convert the original image into a text string stored in a variable. Basically the script I am working on is intended to work by saving each character as an array, and then comparing that to an ini file full of known character arrays in order to figure out what the text says. OCR, in short, although in a clunky and limited way.
Helgef
Posts: 4709
Joined: 17 Jul 2016, 01:02
Contact:

Re: Splitting a Two Dimensional Array

20 Jul 2017, 15:57

Example,

Code: Select all

txt=
(
1,1,1,1,1,1,1
0,0,0,1,0,0,0
0,0,0,1,0,0,0
1,1,1,1,1,1,1
0,0,0,0,0,0,0
1,0,0,0,0,0,1
1,1,1,1,1,1,1
1,0,0,0,0,0,1
0,0,0,0,0,0,0
)
arr:=strsplit(txt,"`n")
for i, v in arr
	arr[i]:=strsplit(v,",")
for i in arr {
	for j in arr
		str.=arr[j,i]
	str.= "`n" 
}
MsgBox % str
MaxAstro
Posts: 557
Joined: 05 Oct 2016, 13:00

Re: Splitting a Two Dimensional Array

20 Jul 2017, 16:02

@Helgef As I said above, rotating the array is not what I am trying to do, but thanks. Although this does make me realize that maybe I should just use a string to store the raw data instead of an array...
Helgef
Posts: 4709
Joined: 17 Jul 2016, 01:02
Contact:

Re: Splitting a Two Dimensional Array

20 Jul 2017, 16:25

You can store relevant substrings in an array,

Code: Select all


txt=
(
1,1,1,1,1,1,1
0,0,0,1,0,0,0
0,0,0,1,0,0,0
1,1,1,1,1,1,1
0,0,0,0,0,0,0
1,0,0,0,0,0,1
1,1,1,1,1,1,1
1,0,0,0,0,0,1
0,0,0,0,0,0,0
1,1,1,1,1,1,1
0,0,0,1,0,0,0
0,0,0,1,0,0,0
1,1,1,1,1,1,1
)
txt:=RegexReplace(txt,"\R[0,]+\R","a") ; remove leading / trailing zero lines first
txtArray:=strsplit(txt,"a")
for k, v in txtArray
	str.="Array " k ":`n" v "`n"  "`n" 
msgbox % str
MaxAstro
Posts: 557
Joined: 05 Oct 2016, 13:00

Re: Splitting a Two Dimensional Array

20 Jul 2017, 16:39

Getting much warmer! I wasn't aware of Strsplit, this is getting much closer to what I need. There's only a couple bits left:

The first part is that sometimes there are multiple rows of empty pixels, and that needs to not confuse it about how many characters there are. The second, and much more complex part, is that I need to record what row number each character starts at. So for the above, I need (1:1, 2:6, 3:10) to be stored somewhere. Maybe if I could somehow assign each array to a key# equal to the array's line number? Not sure how to do that, though.

I'm currently working on another possible solution which is basically just to use a parse loop to go through the string and build it that way.
Helgef
Posts: 4709
Joined: 17 Jul 2016, 01:02
Contact:

Re: Splitting a Two Dimensional Array

20 Jul 2017, 17:37

I'm currently working on another possible solution which is basically just to use a parse loop to go through the string and build it that way.
That is probably easiest. :thumbup:
If you just want to read what the 0,...,1,... text says, you just need instr. Define the symbols you are interested in and search. Example,

Code: Select all

txt=
(
0,0,0,0,0,0,0
1,1,1,1,1,1,1
0,0,0,1,0,0,0
0,0,0,1,0,0,0
1,1,1,1,1,1,1
0,0,0,0,0,0,0
0,0,0,0,0,0,0
0,0,0,0,0,0,0
0,0,0,0,0,0,0
1,0,0,0,0,0,1
1,1,1,1,1,1,1
1,0,0,0,0,0,1
0,0,0,0,0,0,0
1,1,1,1,1,1,1
0,0,0,1,0,0,0
0,0,0,1,0,0,0
1,1,1,1,1,1,1
0,0,0,0,0,0,0

)
H=
(
1,1,1,1,1,1,1
0,0,0,1,0,0,0
0,0,0,1,0,0,0
1,1,1,1,1,1,1
)
I=
(
1,0,0,0,0,0,1
1,1,1,1,1,1,1
1,0,0,0,0,0,1
)
space=
(
0,0,0,0,0,0,0
)
alphabet:={h:H,i:I,(A_Space):space}
p:=1
readOut:=[]
for sym, m in alphabet{
	p:=1
	while (q:=inStr(txt,m,,p))
		readOut[q]:=sym, p:=q+strlen(m)-1
}
for q, v in readOut
	str.=v
msgbox, % "The text says:`n" str

Return to “Ask for Help (v1)”

Who is online

Users browsing this forum: septrinus and 303 guests