2D array - checking for column with most "on" values - ios

So I have a 2D array of "1" and "0" values, a value is either on or off, this can generate shapes and I want to check for vertical lines, for example:
[0,0,1,0,1,0,0,0]
[0,0,0,0,1,0,0,0]
[0,1,0,0,1,0,0,0]
[0,0,0,0,1,0,0,0]
[1,0,0,0,1,0,0,0]
[0,0,0,0,1,0,0,0]
that has a vertical line in column 5 so we will return those ones and strip all other results (change the 1's that aren't part of that line to 0's...)
[0,0,0,0,1,0,0,0]
[0,0,0,0,1,0,0,0]
[0,0,0,0,1,0,0,0]
[0,0,0,0,1,0,0,0]
[0,0,0,0,1,0,0,0]
[0,0,0,0,1,0,0,0]
My 2 dimensional array is much more complex, it is about a 300x600 2D array. In-order to visually see the values I generated UIViews with red background and stuck them on the screen in a view the size of my array. This is what the returned image was (the blue arrow was later photoshopped in to indicate the longest vertical line (the values we want to keep)
So what's a good method to find the longest vertical line (of "1" values) in a 2 dimensional array and change all other values to zero. (So that if I render the array in a visual graph format again only this is displayed (other red dots are fading out because they have been changed from "1" values to "0" values.)
I was thinking maybe something along the lines of generating a for-loop that would keep track of all of the "1" values in each column and a set of maybe any given 6 columns that are consecutively next to each other that have the largest amount of "1" values is the area (6 columns wide) where the longest vertical line is most likely located, but I can see a few issues with this, also I don't know how to get the rows that are part of that line after I have the columns.... hmmmm
*Note: I am making my "2 dimensional array" by just have a variable for the fixed number of columns and then I have an array that just has all of the values for all column/row combinations. For example a 3x3 board would be [0,0,0,0,1,0,0,0,0] which I can then understand means this:
[0,0,0]
[0,1,0]
[0,0,0]
Because I know there is always 3 columns per row.
[row1column1,row1column2,row1column3,row2column1,row2column2,row2column3,row3column1,row3column2,row3column3]

Here's some sample code (you'll need to take care of the allocations and some semantics - e.g: assigning one array to another)
int array2d[]; // which is 1d from what I understood - this holds your initial values
int columnCount; // you already have the number of columns, this is the var that's holding it
int maxColumn[], column[]; // these will hold the values of the maximum column and the current looped column
int maxIndex = 0, max=0; // used to determine which of the columns is the longest
int rowCount = array2d.count/columnCount; // find out how many rows there are
// first loop through the entire array, set everything to '0', while storing the values of the longest column (so far) in a different array
for(int i=0; i<columnCount; i++){
int columnSum = 0;
int index = i;
// go through every row of the column i
for(int j=0; j<rowCount; j++, index+=rowCount){
columnSum=columnSum+array2d[index];
column[j]=array2d[index];
array2d[index]=0;
}
if(columnSum>max){
max = columnSum;
maxIndex = i; // the column index
maxColumn = column;
}
}
// we found the longest column (maxIndex), now we need to set its values back to what they were previously
int index = maxIndex;
for(int j=0; j<rowCount; j++, index+=rowCount){
array2d[index]=maxColumn[j];
}
Since you want to find the longest of 6 consecutive columns, I believe that setting columnCount/=6; should work (it'll also make the rowCount=rowCount*6)

Your requirements aren't very precise, which makes me think you need to think harder about what you want, or state it more clearly. Take a look at the attached figure:
It's six pixels wide, so I image you could get this sort of a chain in your image. There's no connected sequence of 1's longer than 4 in any of the columns, yet the chain itself is 18 pixels long. Would you need to deal with a situation like this? If yes, then just summing over individual columns isn't enough; you need a more sophisticated method, like finding "connected components".

Related

Column and row names missing in a bipartite network web visualization using plotweb() in Rstudio

When I plot my web, which has column and row names, the lables on the visualisation show up as col1 and row 1 etc.
This is despite the fact that ?plotweb states that the defualt is to show full lables:
high.lablength number of characters of upper labels that should be plotted. If zero no labels are shown, default is NULL which plots the complete labels.
and
low.lablength number of characters of lower labels that should be plotted. If zero no labels are shown, default is NULL which plots the complete labels.
Can anyone point me in the direction of where I might have gone wrong?
This is the code I wrote:
cn_dfWEB_summer <- frame2webs(cn_df_summer, varnames = c("Plant", "Pollinator_order", "WebID", "Weight"), type.out = "array", emptylist = FALSE)
plotweb(cn_dfWEB_summer, empty = FALSE)
When I produce the plot, it looks fine, apart from the fact that none of the edges show their proper names. Only col and row numbers. I cannot find an argument that will fix it.
I had the same problem. I had to transform my data frame to an array of integers to solve it.
spxvisitOK <- as.matrix(sapply(spxvisit, as.integer))
Then add the row names and that's it. (columns names were already loaded on my data)
row.names(spxvisitOK)<-c("Abelia sp",
"Bougainvillea sp",
"Bulbine frutescens")
When I compared the properties of my data frame with the test data (safariland), I realized that the package loaded and saw they were slightly different.
I hope you were able to solve it.

Condition Formatting, changing the ranges colour depending on the total of that range

I want to conditional format some cells so that if the added value of those cells = 0 it goes green and then a separate one if the sum does not equal 0. Currently, I am using a total cell to determine this (BALANCE LEVEL), but I want to eliminate the use of this and have the format rule to sum the values and determine the colour without the use of this cell.
Custom formula is
=SUM(AQ39:AQ48)=0
This to turn the column green
and then another rule with this formula
=SUM(AQ39:AQ48)<>0
This to turn the column red
I expected this to change the column green if the total of all the values in that column = 0, and red if the sum does not. It only changes some of the cells, even though the range I have applied it to is that whole column.
Please clear any existing CF from your range, fill it 'standard' red fill and apply this CF formula rule with green fill:
=SUM(AQ$39:AQ$48)=0
Beware of floating point errors.

Google sheets; Arbitrary range as string

How to convert a range of arbitrary size, to it's string representation, to be later used using INDIRECT ?
ADDRESS only works for a single cell.
No scripting please :)
Only formulas.
EDIT 1 ;
Also assume the range is computed through a complex formula. So no cell addresses are available.
EDIT 2 ;
=ArrayFormula(IF((OFFSET(INDIRECT(PayStaff),0,10)>PayrollStart)*(OFFSET(INDIRECT(PayStaff),0,10)<=PayrollEnd),(OFFSET(INDIRECT(PayStaff),0,10)-PayrollStart),0)+IF((OFFSET(INDIRECT(PayStaff),0,11)>=PayrollStart)*(OFFSET(INDIRECT(PayStaff),0,11)<PayrollEnd),(PayrollEnd-OFFSET(INDIRECT(PayStaff),0,11)),0))
No sample sheet as this is a hypothetical type question.
Above is an actual formula I'm using, one of many in my efforts at fully automation. At any time, the range string in "PayStaff" can change, coupled with repeated but identical OFFSET calls, soon makes the formula unreadable. One of my ideas to solve the readability is to get the range-string of (eg: OFFSET(INDIRECT(PayStaff),0,10) ) and reuse it, shortening the formula and increasing readability. Also note, the example does NOT have size increase of range which I require as well.
But lets suppose that PayStaff = "A1:A10", where the number of rows can vary. Considering that OFFSET has 4 parameters, how to get the resultant range as a string? Is this possible?
I just used this to do something similar, hope this helps:
// <range here> = is the range you want to describe,
// can be output of some other formula but has to be a
// rectangle for this to work.
// Remove // comments and line breaks before pasting to sheet.
// concatenate top left corner with colon and bottom right corner.
=CONCATENATE(
// use address to get top left corner
ADDRESS(ROW(<range here>), COLUMN(<range here>)),
":",
// use address to get bottom right corner
ADDRESS(
ROW(<range here>)+ROWS(<range here>)-1,
COLUMN(<range here>)+COLUMNS(<range here>)-1
)
)
This would give you the start of the range as a string:
=cell("Address",OFFSET(INDIRECT(PayStaff),0,10))
The end of the range is more awkward - you would have to add the number of rows in the range (-1) to the row offset:
=cell("Address",OFFSET(INDIRECT(PayStaff),rows(indirect(PayStaff))-1,10))

How to generate a certain amount of numbers and spread them randomly across a grid?

I want to generate the number 2 5 times and the number 1 10 times. I'm trying to spread these across a String Grid in Delphi randomly. I also want to fill the rest of the grid that isn't 1 or 2, with 0's. I have no idea how to even start here.
It would look something like this (P stands for player and there would only be 5 2's and 10 1's): https://gyazo.com/aeef05c3a92ce7847c0f42ad40faa733
Given a grid with dimensions m×n, create an array of length m * n. Put five 2's and 10 1's in the array, and fill the remainder with 0's. (We'll assume the product of m and n is at least 15.) Shuffle the array. Copy each element of the shuffled array into successive cells in the grid.
While the approach represented in Robs answer will do the job I personally think it is way to complicated for it's purpose.
So what would be more simpler approach?
Well your goal is to place these numbers at random positions in grid.
How do you determine position of some object in a grid? You do it by its X (Column) and Y (Row) coordinates.
So how do you get random position in a grid? Simple chose two random values for X and Y coordinates.
As for placing certain numbers of number 1 and number 2 use two simple loops.

Get all characters before a whitespace in LUA (ROBLOX)

I have a 5x5 grid of tiles that are number like:
Numerical order Row number(eg: 1 1 would be the first tile on the first row and 6 2 would be the first tile on the second row)
I need to get the blocks around a clicked tile (above, below, left and right), I thought about doing this by taking off numbers from the numerical order and row number. I wrote this:
local ab = tostring(tonumber(v.Name)-5)..tostring(tonumber(string.sub(v.Name,-1))-1)
local be = tostring(tonumber(v.Name)+5)..tostring(tonumber(string.sub(v.Name,-1))+1)
ab being the tile above and be being the tile below. I ran into a problem where I cannot get the first two letters of a tile who's numerical order is two digits using one line (I don't want to use if statements since I'm pretty sure there's a one line solution)
I came up with a solution and that is to get all the characters before the whitespace (which separates the order from the row number) but I have no idea how to write it.
Just ask for all non-whitespace characters from the beginning of the string:
print(("test123 more456"):match("^(%S+)"))
This should print test123.

Resources