Check if 2d shape composed of block has been cut - arrays

I know that the title of this topic might be confusing, but I didn't know how to explain it in a single sentence!
I'll try to be more clear, I have a 2d array of boolean values, every value states if that particular position (or block) is alive or not.
Let's make an example:
1 1 1 1
1 1 1 1
1 1 1 1
1 1 1 1
This array contains 16 "alive" blocks, now I can "kill" some blocks, changing their state from 1 to 0.
What I would like to do is to know if after a "kill", the group splits in two or more separate groups, for example:
1 1 0 1
1 1 0 1
0 1 0 1
1 1 1 1
This shape is still "intact", since the group of 0 is not cutting any of the 1 groups, but in this case:
1 1 0 1
1 1 0 1
0 0 0 1
1 1 1 1
Now I've killed the only bit who was keeping all the 1 together, the shape has been divided in two smaller groups!
I've tried checking the neighbours of the last killed bit but then I can't be sure of other possible connection of the shape.
I've also tried a pathfinding algorithm but this operation should be very fast and a pathfinding is too complex.
How can I achieve this?

Pick any of the alive blocks and do a flood-fill and then check if it got to all the other live blocks.

Related

Sorting two dimensional array of objects with status

I have an array of objects with some status, like here.
1 1 1 1 0 1
1 0 1 1 0 1
0 0 1 1 0 0
x x x x x x
0 0 1 1 0 0
0 0 1 1 0 0
1 0 0 0 0 1
1 1 1 1 1 1
x is diff status of object, i want to change status to 2 for all 1 touching x and other 1 touching 1 touching x etc. So my result should look like this.
2 2 2 2 0 1
2 0 2 2 0 1
0 0 2 2 0 0
x x x x x x
0 0 2 2 0 0
0 0 2 2 0 0
1 0 0 0 0 1
1 1 1 1 1 1
Actually I would like to return array of objects which should change from 1 to 2.
I though about recursion function, function would check is touching object status equal to 1, if it is change status and do it for touching object with status 1. I cant imagine how this function may look, I never used recursion :/
If it matters I'm using TypeScript.
Your help will be Holy Grail for me.
You need to start Flood fill from x cells.
Recursive implementation is very simple (four-way connectivity):
Flood-fill (node, target-color, replacement-color):
1. If target-color is equal to replacement-color, return.
2. If the color of node is not equal to target-color, return.
3. Set the color of node to replacement-color.
4. Perform Flood-fill (one step to the south of node, target-color, replacement-color).
Perform Flood-fill (one step to the north of node, target-color, replacement-color).
Perform Flood-fill (one step to the west of node, target-color, replacement-color).
Perform Flood-fill (one step to the east of node, target-color, replacement-color).
5. Return.
but there are non-recursive implementations too.

Average of dynamic row range

I have a table of rows which consist of zeros and numbers like this:
A B C D E F G H I J K L M N
0 0 0 4 3 1 0 1 0 2 0 0 0 0
0 1 0 1 4 0 0 0 0 0 1 0 0 0
9 5 7 9 10 7 2 3 6 4 4 0 1 0
I want to calculate an average of the numbers including zeros, but starting from the first nonzero value and put it into column after tables end. E.g. for the first row first value is 4, so average - 11/11; for the second - 7/13; the last one is 67/14.
How could I using excel formulas do this? Probably OFFSET with nested IF?
This still needs to be entered as an array formula (ctrl-shift-enter) but it isn't volatile:
=AVERAGE(INDEX(($A2:$O2),MATCH(TRUE,$A2:$O2<>0,0)):$O2)
or, depending on location:
=AVERAGE(INDEX(($A2:$O2);MATCH(TRUE;$A2:$O2<>0;0)):$O2)
The sum is the same no matter how many 0's you include, so all you need to worry about is what to divide it by, which you could determine using nested IFs, or take a cue from this: https://superuser.com/questions/671435/excel-formula-to-get-first-non-zero-value-in-row-and-return-column-header
Thank you, Scott Hunter, for good reference.
I solved the problem using a huge formula, and I think it's a bit awkward.
Here it is:
=AVERAGE(INDIRECT(CELL("address";INDEX(A2:O2;MATCH(TRUE;INDEX(A2:O2<>0;;);0)));TRUE):O2)

3+ dimensional truth table in APL

I would like to enumerate all the combinations (tuples of values) of 3 or more finite-valued variables which satisfy a given condition. In math notation:
For example (inspired by Project Euler problem 9):
The truth tables for two variables at a time are easy enough:
a ∘.≤ b
1 1 1 1
0 1 1 1
0 0 1 1
b ∘.≤ c
1 1 1 1 1
0 1 1 1 1
0 0 1 1 1
0 0 0 1 1
After much head-scratching, I managed to combine them, by computing the ∧ of every 4-valued row of the former with each 4-valued column of the latter, and disclosing (⊃) on the correct axis, between 1 and 2:
⎕← tt ← ⊃[1.5] (⊂[2] a ∘.≤ b) ∘.∧ (⊂[1] b ∘.≤ c)
1 1 1 1 1
0 1 1 1 1
0 0 1 1 1
0 0 0 1 1
0 0 0 0 0
0 1 1 1 1
0 0 1 1 1
0 0 0 1 1
0 0 0 0 0
0 0 0 0 0
0 0 1 1 1
0 0 0 1 1
Then I could use its ravel to filter all possible tuples of values:
⊃ (,tt) / , a ∘., b ∘., c
1 1 1
1 1 2
1 1 3
1 1 4
1 1 5
1 2 2
1 2 3
...
3 3 5
3 4 4
3 4 5
Is this the best approach to this particular class of problems in APL?
Is there an easier or faster formula for this example, or for the general case?
More generally, comparing my (naïve?) array approach above to traditional scalar languages, I can see that I'm translating each loop into an additional dimension: 3 nested loops become a 3-rank truth table:
for c in 1..NC:
for b in 1..min(c, NB):
for a in 1..min(b, NA):
collect (a,b,c)
But in a scalar language one can effect optimizations along the way, for example breaking loops as soon as possible, or choosing the loop boundaries dynamically. In this case I don't even need to test for a ≤ b ≤ c, because it's implicit in the loop boundaries.
In this example both approaches have O(N³) complexity, so their runtime will only differ by a factor. But I'm wondering: how could I write the array solution in a more optimized way, if I needed to do so?
Are there any good books or online resources that address algorithmic issues or best practices in APL?
Here's an alternative approach. I'm not sure if it would run faster.
Following your algorithm for scalar languages, the possible values of c are
⎕IO←0
c←1+⍳NC
In the inner loops the values for b and a are
b←1+⍳¨NB⌊c
a←1+⍳¨¨NA⌊b
If we combine those
r←(⊂¨¨¨a,¨¨¨b),¨¨¨c
we get a nested array of (a,b,c) triplets which can be flattened and rearranged in a matrix
r←∊r
(((⍴r)÷3),3)⍴r
ADD:
Morten Kromberg sent me the following solution. On Dyalog APL it's ~ 30 times more efficient than the one above:
⎕IO←1
AddDim←{0≡⍵:⍪⍳⍺ ⋄ n←0⌈⍺-x←¯1+⊢/⍵ ⋄ (n⌿⍵),∊x+⍳¨n}
TTable←{⊃AddDim/⌽0,⍵}
TTable 3 4 5

Efficient way to "fill" a binary matrix to create smooth, connected zones

I have a large matrix of 1's and 0's, and am looking for a way to "fill" up areas that are locally dense with 1's.
I first did this task for an array, and counted the number of 1's within a certain radius of the element in questions. If the radius was 5, for example, and my threshold was 4, then a point that had 4 elements marked "1" within 5 elements to the left or right would be changed to a 1.
Basically I would like to generalized this to a two - dimensional array and have a resulting matrix that has "smooth" and "connected" regions of 1's and no "patchy" spots.
As an example, the matrix
1 0 0 1 0 0 0
0 0 1 0 1 0 0
0 1 0 1 0 0 0
0 0 1 1 1 0 0
would ideally be changed to
1 0 0 1 1 0 0
0 0 1 1 1 0 0
0 1 1 1 1 0 0
0 0 1 1 1 0 0
or something similar
For binary images, the morphologial operations that are implemented in MATLAB are perfect for manipulating the shape and size of connected regions. Specifically, the process of image closing is designed to fill holes in connected regions. In MATLAB, the function is imclose, which takes the image and a structuring element, similar to a filter kernel, for how neighboring pixels effect the filling of holes and gaps. A simple invocation of imclose is,
IM2 = imclose(IM,strel(ones(3)));
Larger gaps can be filled by increasing the area of the influence of of neighboring pixes, via larger structuring elements. For example, we an use a disk of radius 10 pixels:
IM2 = imclose(IM,strel('disk',10));
While, imclose supports grayscale and binary (0 and 1) images, the function bwmorph is designed for operation on binary images only but provides a generic interface to all of the morphological operations and various neat combinations of operations (e.g. 'bothat', 'tophat', etc.). The syntax for closing is simplified with bwmorph:
BW2 = bwmorph(BW,'close');
Here the structuring element is the standard ones(3).
A simple filter such as the following might do the trick:
h = [ 0 1 0
1 0 1
0 1 0];
img2=(imfilter(img,h)>2) | img;
For instance:
img =
1 0 0 1 0 0 0
0 0 1 0 1 0 0
0 1 0 1 0 0 0
0 0 1 1 1 0 0
img2 =
1 0 0 1 0 0 0
0 0 1 1 1 0 0
0 1 1 1 1 0 0
0 0 1 1 1 0 0
You can try different filters to modify the output img2.
This uses the image processing toolbox. If you don't have that, you may want to look up equivalent routines from the matlab exchange.

MPI: How to concatenate sub-arrays in multiple processors into a larger single array

I am using MPI in C. I was able to distribute parts of an array to different processors. And the different processors did all the manipulation I wanted. Now I am at the point where I wanted to combine all the sub-arrays that are in all the processors into one big array. For example if the different processors had sub-arrrays as follows:
Processor 1:
0 1 1 0
0 0 1 0
Processor 2:
0 0 1 0
1 1 0 1
Processor 3:
1 1 0 0
1 1 1 1
...
I want to be able to combine, or "concatenate", all the sub-arrays together. For example I would want the large array to be:
0 1 1 0
0 0 1 0
0 0 1 0
1 1 0 1
1 1 0 0
1 1 1 1
...
I was trying to use MPI_Reduce but I couldn't find an operation to do what I wanted to do. Is there another MPI method I could use to achieve what I am looking for?
You are looking for MPI_Gather:
Each process (root process included) sends the contents of its send buffer to the root process. The root process receives the messages and stores them in rank order.
For documentation and examples, see here and here. The section 5.5 in the MPI 2.2 Standard also has examples.

Resources