Swift: Sort Array with NSRange - arrays

I have an array with some NSRanges and want to sort them depending on their location.
var rangeArr = Array<NSRange>()
rangeArr.append(NSMakeRange(14, 4))
rangeArr.append(NSMakeRange(1, 3))
rangeArr.append(NSMakeRange(5, 5))
print(rangeArr)
...results in:
(14, 4), (1, 3), (5, 5)
But I need a result like:
(1, 3), (5, 5), (14, 4)

rangeArr.sortInPlace {$0.location < $1.location}

Related

Build array iterating over multiple indices in Julia

I want to obtain the following result with a more elegant syntax
julia> collect(Iterators.flatten([[(x,y) for y in 1:x] for x in 1:3]))
6-element Array{Tuple{Int64,Int64},1}:
(1, 1)
(2, 1)
(2, 2)
(3, 1)
(3, 2)
(3, 3)
I tried something like [(x,y) for y in 1:x, x in 1:3] but I get ERROR: UndefVarError: x not defined.
Just reverse the order of variables like this:
julia> [(x,y) for x in 1:3 for y in 1:x]
6-element Array{Tuple{Int64,Int64},1}:
(1, 1)
(2, 1)
(2, 2)
(3, 1)
(3, 2)
(3, 3)
I used to have also been struggled to remember the variable order. Until one day someone told me a secret: just treat the order of for loop in the list comprehension as usual except that the body is moved to the front.
For example, in normal order we write:
for x in 1:3
for y in 1:x
# do sth
end
end
Now we move the body part to the front and we have [ #= do sth =# for x in 1:3 for y in 1:x]

Find total number of ways possible to create an array of size M

Suppose I have M = 2 and N = 5 and K = 2 where
M = size of array
N = Maximum number that can be present as an array element
K = Minimum number that can be present as an array element.
So how do I find the number of possible ways to create an array using the above conditions. Also the current number should be not be greater than the previous element.
The arrays created using the above conditions are
[5,5],[5,4],[5,3],[5,2],[4,4],[4,3],[4,2],[3,3],[3,2],[2,2]
i.e 10 array can be created from the above conditions.
I tried doing it by using combinations and factorials, but not getting the desired output. Any help would be appreciated.
Assuming you are just interested in the number of combinations the formula is -
(N-K+M)!/(M!(N-K+1)!)
See more here
This is known as a combinations_with_replacement: combination because the order doesn't matter (or it would be a permutation), and with replacement because elements can be repeated, like [5, 5].
list(itertools.combinations_with_replacement(range(2, 6), 2))
# [(2, 2), (2, 3), (2, 4), (2, 5), (3, 3), (3, 4), (3, 5), (4, 4), (4, 5), (5, 5)]
If you want the exact ones you listed, you will have to reverse each element, and the list itself.
list(reversed([tuple(reversed(element)) for element in itertools.combinations_with_replacement(range(2,6), 2)]))

Kotlin - index of duplicate elements in an array

Is there an easy way to get the index of matching elements in an array without writing a for loop and then collecting the index?
Eg: val arr = arrayOf<Int>(2,3,4,2,5,2,6,3,2)
Output: For element 2, output should be (0,3,5,8) and For element 3, output should be (1,7)
Kotlin provides indexOf(element) which returns first index and then lastIndexOf(element) which will give me last index. Am looking for an easy way to get indexes of all matching elements.
My solution: Standard solution of iterating over the array and collecting index.
var indexArrOf2 = mutableListOf<Int>()
var indexArrOf3 = mutableListOf<Int>()
for(i in arr.indices) {
if (arr[i] == 2) {
indexArrOf2.add(i)
}
if (arr[i] == 3) {
indexArrOf3.add(i)
}
}
Yes, you can use mapIndexedNotNull:
arr.mapIndexedNotNull { index, elem -> if (elem == 2) index else null }
A little convoluted but returns a map Map<Element, List<Indices>> to use as desired.
arr.mapIndexed { index, i -> i to index } //List<Pair<Int, Int>> - [(2, 0), (3, 1), (4, 2), (2, 3), (5, 4), (2, 5), (6, 6), (3, 7), (2, 8)]
.groupBy { it.first } //Map<Int, List<Pair<Int, Int>>> - {2=[(2, 0), (2, 3), (2, 5), (2, 8)], 3=[(3, 1), (3, 7)], 4=[(4, 2)], 5=[(5, 4)], 6=[(6, 6)]}
.mapValues { it.value.map { it.second } } //Map<Int, List<Int>> - {2=[0, 3, 5, 8], 3=[1, 7], 4=[2], 5=[4], 6=[6]}
I'd use the withIndex() extension function to add the index.  You can then select the matching items, and get their indices:
val arr = arrayOf(2, 3, 4, 2, 5, 2, 6, 3, 2)
println(arr.withIndex().filter{ it.value == 2 }.map{ it.index })
// prints '[0, 3, 5, 8]'

Grouping lines considering intersections of each line using python

There are 5 lines. I want to group them considering whether they intersect or not by limiting to the two end points of each line.
I want to get the logic for any of the lines, not being limited to the given scenario.
Array of 5 lines (coordinates of end points).
lines_all = [[(1, 10), (5, 10)],[(3, 5), (5, 5)],[(3, 10), (3, 13)],[(5,10),(5,13)],[(3,13),(4,13)]]
Then finally I want to get the following array list.
result = [[[(1, 10), (5, 10)], [(3, 10), (3, 13)],[(3, 13), (4, 13)]], [[(1, 10), (5, 10)], [(5, 10), (5, 13)]],[(3, 5), (5, 5)]]
To find all line segment intersections, you can use Bentley-Ottmann algorithm.
Arbitrary found Python implementation

Finding a list of all largest open rectangles in a grid by only examining a list of "open" indices

I have a 2D grid that has some obstacles in it.
[x][x][ ]
[ ][ ][ ]
[ ][ ][x]
I want to be able to find all the largest spaces of "open" grid cells.
[x][x][ ] [x][x][ ]
[1][1][ ] [2][2][2]
[1][1][x] and [ ][ ][x]
I saw the question here which is similar; however, the data I have access to is not a 2D array of values. I have a list of only the open/available indices, and this is stored in a single-dimensional array. Using the above example, my data looks like this:
[0,2]
[1,0]
[1,1]
[1,2]
[2,0]
[2,1]
I could translate it to a 2-D array, but I don't want to have to loop over all the items again to do that. I have a feeling there is some really simple solution to this, but I can't seem to find it.
Is there a way to find all the largest rectangles by only examining a list of the open indices?
EDIT
I just decided to change the array of open indices into a 2D array representing the entire grid, then use the algorithm I linked to. This works efficiently enough for my initial tests; however, I am interested to read about other possible solutions, should I need to alter my implementation for performance or space concerns.
Of course.
To find a rectangle:
Start with any free cell. Assume this is going to be the upper-left corner.
See if it can be extended horizontally.
See if it can be extended vertically.
Backtrack.
I'll ellaborate on this later, but thought this could give you a jump-start.
The list of available coordinates is sorted.
So have a global, upto-now maximum rectangle, as list too.
Do a list walk, and for every item call a function with the sublist starting at the item. To find the largest rectangle starting top-left with that item.
public List<Coord> getMaxRectangle(List<Coord> openCoords) {
List<Coord> currentMaxRectangle = null;
for (int i = 0; i < openCoords.size(); ++i) {
// Handle all rectangles starting here:
currentMaxRectangle = maxRectangleStartingAt(i, currentMaxRectangle);
}
return currentMaxRectangle;
}
public List<Coord> maxRectangleStartingAt(int i, List<Coord> openCoords) {
// Now the interesting part:
// Take the maximal width list first: standing for all widths 1, ... max width.
List<Coord> rect = new ArrayList<>();
for (int j = i; j < openCoords.size()
&& openCoords.get(j).y == openCoords.get(i).y
&& openCoords.get(j).x - openCoords.get(i).x == j - i;
++j) {
rect.add(openCoords.get(j);
}
int maxWidth = rect.size();
// Now we can look for next lines below rect.get(0), ... get(maxWidth - 1),
// continuously diminishing maxWidth till 0.
// When we need to diminish maxWidth, we can look wether the original
// maxWidth by (currentY - 1) is a maximum result.
...
}
So we walk:
+-------------+ 1st rect
| |
| | 2nd rect
| | 3rd rect
| | 4th rect
Demonstration of O(N²) complexity:
public static void main(String[] args) {
int[][] openCoords = {
{0, 2},
{1, 0},
{1, 1},
{1, 2},
{2, 0},
{2, 1}
};
new MaxRectFinder().find(openCoords);
}
private int[] maximumTopLeft;
private int[] maximumSize;
private void find(int[][] openCoords) {
maximumTopLeft = null;
maximumSize = new int[2];
for (int topLeftCandidateI = 0; topLeftCandidateI < openCoords.length; ++topLeftCandidateI) {
int yOrig = openCoords[topLeftCandidateI][0];
int xOrig = openCoords[topLeftCandidateI][1];
int y = yOrig;
int x = xOrig + 1;
int j = topLeftCandidateI + 1;
while (j < openCoords.length
&& openCoords[j][0] == y
&& openCoords[j][1] == x) {
++x;
++j;
}
// Now we have a maximum x.
for (;;) {
// Skip after right side on current line:
while (j < openCoords.length
&& openCoords[j][0] == y) {
++j;
}
++y;
// Check for maximum:
if (maximumTopLeft == null || (y - yOrig)*(x - xOrig) > maximumSize[0] * maximumSize[1]) {
maximumSize[0] = y - yOrig;
maximumSize[1] = x - xOrig;
maximumTopLeft = openCoords[topLeftCandidateI];
}
// Skip before left side below origin:
while (j < openCoords.length
&& openCoords[j][0] == y
&& openCoords[j][1] < x) {
++j;
}
if (j >= openCoords.length
|| openCoords[j][0] != y
|| openCoords[j][1] != x) {
break;
}
// Register rectangle part:
int x2 = xOrig;
while (j < openCoords.length
&& openCoords[j][0] == y
&& openCoords[j][1] == x2
&& x2 <= x) {
++x2;
++j;
}
x = x2;
}
}
if (maximumTopLeft == null) {
System.out.println("No solution found, not even 1x1.");
} else {
System.out.printf("At [%d, %d] with size [%d, %d].%n",
maximumTopLeft[0], maximumTopLeft[1], maximumSize[0], maximumSize[1]);
}
}
My previous answer was the simple approach. This a completely different one.
Algorithm
Identify horizontal runs and transform to rectangle notation.
Initialize currRects list with rectangles in row 0.
Set currRow to 1.
For each rectangle b in currRects, find intersections with horizontal runs a in row currRow. An intersect operation i is defined as
r(axi-axt,ayi-ayt) i r(bxi-bxt,byi-byt)
Its relevance is how both rectangle's y range intersect. Depicting it graphically:
bbb
aa| | No intersect
aa|aa | Partial intersect
aa|aaa| a contains b
aa|aaa|a a contains b
|aa | b contains a
|aaa| a equal b
|aaa|a a contains b
| aa| b contains a
| aa|a Partial intersect
| |aa No intersect
The necessary logic to determine each case is based in ayi, ayt, byi, and byt and simple, thus not described here.
This function will return a list of up to 2 rectangles and a flag.
No intersect ([],true)
Partial intersect: ([red,a],true)
b contains a: ([red],true)
a contains b: ([pres,a],false)
a equal b: ([pres],false)
red and pres are the result of combining the previous rectangle b with the incoming a. It can be preserving the width (in the sense of y coordinates) of the rectangle, or reducing it, but the difference is not important algorithmically.
The core of step 4 is to keep a list nextCurrRects with all the rectangles returned by function intersect. nextCurrRects should be initially empty, of course. Additionally, if for a rectangle b in the previous currRects the returned flag is never false, then b needs to be put in the final resulting list (or just printed or "yielded").
Make currRects equal to nextCurrRects. Iterate if currRow has not reached the end.
All rectangles still in currRects also belong to the result.
Example
1) inRects= [ r(0-0,2-2), r(1-1,0-2), r(2-2,0-1) ]
2) currRects= [ r(0-0,2-2) ]
3) currRow= 1
4)
nextCurrRects= []
r(1-1,0-2) i r(0-0,2-2) {a contains b} == ( [ r(0-1,2-2), r(1-1,0-2)] ], false )
nextCurrRects == [ r(0-1,2-2), r(1-1,0-2)] ]
5) currRects == [ r(0-1,2-2), r(1-1,0-2)] ]
4)
nextCurrRects= []
r(2-2,0-1) i r(0-1,2-2) {No intersect} == ( [], true )
Never false -> result= [ r(0-1,2-2) ]
r(2-2,0-1) i r(1-1,0-2) {Partial intersect} == ( r(1-2,0-1), true )
nextCurrRects= [ r(1-2,0-1) ]
Never false -> result= [ r(0-1,2-2) , r(1-2,0-1) ]
5) currRects= [ r(1-2,0-1) ]
6) result= [ r(0-1,2-2) , r(1-2,0-1) , r(1-2,0-1) ]
In fact, the algorithm just "discovered" that there is a 3rd resulting rectangle not considered in the original example:
[x][x][3]
[ ][ ][3]
[ ][ ][x]
Code
class Range:
def __init__(self,start,end=None):
self.start= start
self.end= end if end is not None else start
def isEmpty(self):
return self.start > self.end
def isUnit(self):
return self.start == self.end
def intersect(self,other):
return Range( max(self.start,other.start) , min(self.end,other.end) )
def contains(self,other):
return self.start <= other.start and self.end >= other.end
def __repr__(self):
return "Range(%d,%d)" % ( self.start, self.end )
class Rect:
def __init__(self,xRange,yRange):
self.xRange= xRange
self.yRange= yRange
def isEmpty(self):
return self.xRange.isEmpty() or self.yRange.isEmpty()
def isUnit(self):
return self.xRange.isUnit() and self.yRange.isUnit()
def intersect(self,other):
return Range( max(self.start,other.start) , min(self.end,other.end) )
def contains(self,other):
return self.xRange.contains(other.xRange) and self.yRange.contains(other.yRange)
def __repr__(self):
return "Rect(%s,%s)" % ( self.xRange, self.yRange )
def intersect(a,b):
r= Rect( Range(b.xRange.start,a.xRange.end) , a.yRange.intersect(b.yRange) )
brokenB= not a.yRange.contains(b.yRange)
fullyAbsorbedA= b.yRange.contains(a.yRange)
return (r,brokenB,fullyAbsorbedA)
def findOpenRectangles(freeElements,pastRowNum):
# From `freeElements`, compute free runs into `freeRunsPerRow`
from collections import defaultdict
freeRunsPerRow= defaultdict(set)
rowNum= -1
currRun= None
for fe in freeElements :
if fe[0] != rowNum :
if currRun is not None:
freeRunsPerRow[rowNum]|= { Rect(Range(rowNum),currRun) }
currRun= Range(fe[1],fe[1])
rowNum= fe[0]
elif fe[1] == currRun.end + 1 :
currRun= Range(currRun.start,fe[1])
else:
freeRunsPerRow[rowNum]|= { Rect(Range(rowNum),currRun) }
currRun= Range(fe[1],fe[1])
if currRun is not None:
freeRunsPerRow[rowNum]|= { Rect(Range(rowNum),currRun) }
currRun= None
for freeRuns in freeRunsPerRow.items() :
print( freeRuns )
# Yield open rectangles
currRects= set()
for currRow in range(0,pastRowNum) :
continuingRects= set()
startingRects= set( freeRunsPerRow[currRow] )
for b in currRects :
brokenB= True
for a in freeRunsPerRow[currRow] :
modifiedContinuingRect, t_brokenB, t_absorbedA= intersect(a,b)
if not modifiedContinuingRect.isEmpty() and not [ x for x in continuingRects if x.contains(modifiedContinuingRect) ] :
continuingRects-= { x for x in continuingRects if modifiedContinuingRect.contains(x) }
continuingRects|= {modifiedContinuingRect}
if not t_brokenB : brokenB= False
if t_absorbedA : startingRects-= {a}
if brokenB and not b.isUnit() : yield b
currRects= continuingRects
currRects|= startingRects
for b in currRects :
if not b.isUnit() : yield b
Test/Example
Using the following test code:
input= []
input.append(" X ")
input.append(" ")
input.append(" X ")
input.append(" X X")
input.append(" ")
input.append(" ")
input.append(" X ")
input.append(" X X ")
input.append(" X X")
# Translates input into a list of coordinates of free elements
freeElements= []
for rowNum, row in enumerate(input):
for colNum, element in enumerate(row):
if element == " " :
freeElements.append( (rowNum,colNum) )
for fe in freeElements :
print( fe )
# Find and print open rectangles
for openRect in findOpenRectangles(freeElements,len(input)) :
print( openRect )
Output is the following (some formatting to save space and titles added):
freeElements
(0, 0), (0, 1), (0, 2), (0, 4), (0, 5), (0, 6), (0, 7)
(1, 0), (1, 1), (1, 2), (1, 3), (1, 4), (1, 5), (1, 6), (1, 7)
(2, 0), (2, 2), (2, 3), (2, 4), (2, 5), (2, 6), (2, 7)
(3, 0), (3, 1), (3, 2), (3, 3), (3, 4), (3, 6)
(4, 0), (4, 1), (4, 2), (4, 3), (4, 4), (4, 5), (4, 6), (4, 7)
(5, 0), (5, 1), (5, 2), (5, 3), (5, 4), (5, 5), (5, 6), (5, 7)
(6, 0), (6, 1), (6, 2), (6, 3), (6, 5), (6, 6), (6, 7)
(7, 0), (7, 1), (7, 2), (7, 4), (7, 5), (7, 7)
(8, 0), (8, 2), (8, 3), (8, 4), (8, 5), (8, 6)
freeRunsPerRow
(0, {Rect(Range(0,0),Range(0,2)), Rect(Range(0,0),Range(4,7))})
(1, {Rect(Range(1,1),Range(0,7))})
(2, {Rect(Range(2,2),Range(2,7)), Rect(Range(2,2),Range(0,0))})
(3, {Rect(Range(3,3),Range(6,6)), Rect(Range(3,3),Range(0,4))})
(4, {Rect(Range(4,4),Range(0,7))})
(5, {Rect(Range(5,5),Range(0,7))})
(6, {Rect(Range(6,6),Range(5,7)), Rect(Range(6,6),Range(0,3))})
(7, {Rect(Range(7,7),Range(7,7)), Rect(Range(7,7),Range(4,5)), Rect(Range(7,7),Range(0,2))})
(8, {Rect(Range(8,8),Range(0,0)), Rect(Range(8,8),Range(2,6))})
findOpenRectangles(freeElements,len(input))
Rect(Range(0,1),Range(0,2))
Rect(Range(1,1),Range(0,7))
Rect(Range(0,2),Range(4,7))
Rect(Range(1,2),Range(2,7))
Rect(Range(3,5),Range(0,4))
Rect(Range(0,5),Range(4,4))
Rect(Range(4,5),Range(0,7))
Rect(Range(1,5),Range(2,4))
Rect(Range(1,6),Range(2,3))
Rect(Range(4,6),Range(5,7))
Rect(Range(0,6),Range(6,6))
Rect(Range(3,6),Range(0,3))
Rect(Range(3,7),Range(0,2))
Rect(Range(4,7),Range(7,7))
Rect(Range(8,8),Range(2,6))
Rect(Range(7,8),Range(4,5))
Rect(Range(0,8),Range(2,2))
Rect(Range(4,8),Range(5,5))
Rect(Range(0,8),Range(0,0))
Test/Example Conclusion
Output is correct. All non-trivial rectangles are present.

Resources