How can i get all possible combinations of football games in Javascript - combinations

Assuming you have an array of n games, I want to write a script that receives the number of games being played and returns a multidimensional array of all possible combinations.
Keep in mind that a game can either end in Home Win (1), draw (0) or Away Win (-1).
Example
When n = 2,
Games Outcomes
Game 1 => Q vs B: - Q wins (1) - Draw (0) - B Wins (-1)
Game 2 => C vs D: - C Wins (1) - Draw (0) - D wins (-1)
When given 2 games, you will end up with the following combinations:
{1,1}
{1,0}
{1,-1}
{0,1}
{0,0}
{-1,1}
{-1,0}
{-1,-1}

I will give you an equivalent in Java. I know this is an interview question for Infama Limited Kenya
`package com.oluoch.code;
import java.util.Arrays;
import java.util.Scanner;
public class TWODArray {
public static void main(String[] args) {
int arr[][] = { { 1, 1 }, { 1, 0 }, { 1, -1 }, { 0, 1 }, { 0, 0 }, { -1, 1 }, { -1, 0 }, { -1, -1 } };
for (int i = 0; i < 8; ++i)
{
for (int j = 0; j < 2; ++j)
System.out.print(arr[i][j] + " ");
}
}
}
`

Related

I'm having trouble with changing parts of an array

I'm currently working on a small game to play in the console. I'm trying to make player movement, but when I try to replace a certain element within the level array, it deletes the rest of the array.
The only movement in the code right now is moving right (type 2 in the console to move right)
#include <iostream>
using namespace std;
#define con std::cout <<
#define newline std::cout << '\n'
#define text std::cin >>
#define end return 0
#define repeat while (true)
int width, height;
int rprog;
int x, y, z;
int playerpos;
int input;
double level[] =
{1, 1, 1, 1, 1, 1,
1, 0, 0, 0, 0, 1,
1, 0, 2, 0, 0, 1,
1, 0, 0, 0, 0, 1,
1, 0, 0, 0, 0, 1,
1, 1, 1, 1, 1, 1};
const char *display[] = {" ", "[ ]", "[X]"};
int render () {
x = 1;
y = 1;
while (x < 37) {
z = level[x - 1];
con display[z];
x = x + 1;
y = y + 1;
if (y == 7) {
y = 1;
newline;
}
}
end;
}
int player () {
con "Please make your next move : w: 1, a: 2, s: 3, d: 4";
newline;
con "Current position: " << playerpos;
newline;
text input;
if (input == 2) {
level[playerpos] = 0;
playerpos = playerpos - 1;
level[playerpos] = 3;
}
end;
}
int main() {
playerpos = 15;
while (true) {
render ();
player ();
}
end;
}
I'm using this website for coding currently: https://www.programiz.com/cpp-programming/online-compiler/
This is the output:
[ ][ ][ ][ ][ ][ ]
[ ] [ ]
[ ] [X] [ ]
[ ] [ ]
[ ] [ ]
[ ][ ][ ][ ][ ][ ]
Please make your next move : w: 1, a: 2, s: 3, d: 4
Current position: 15
2
[ ][ ][ ][ ][ ][ ]
[ ] [ ]
[ ]
And then it cuts off rendering the level.
I'm confused. What am I doing wrong?
Arrays
Array indices start with 0 in C++.
You set the item at the new position to 3:
level[playerpos] = 3;
However, your array for the display types has only 3 elements (0, 1, 2):
const char *display[] = {" ", "[ ]", "[X]"};
Thus, you encounter undefined behaviour, as you have an out of bounds access.
Note also, that your initial array correctly uses a 2 for the player position, and thus works.
However, it also has a off-by-1 error: Your initialize the playerpos = 15, but place the 2 at index 14. Thus, the initial rendering is wrong. So the first movement will not be correct, and seem to stay on the same position.
Types
As #RemyLebeau mentions, why do you use a double array for the game state? Not only would other types be more appropriate, especially double can lead to serious, hard to debug probles. Not all integers are perfectly representable by a double, and type conversions could lead to different results.
Just for an example: if you add states 4 and 5, and imagine a double could not represent 5 exactely, but store it as 4.99999999999999999 instead. When accessing the array, integer conversion could render a state 4 instead.
Check this question and answer for details
Defines
As #KarenMelikyan mentioned in a comment, those #defines are a bad idea. It makes your code much harder to read for others, and is a bad a habit to develop. Better get aquainted with correct C++ syntax and use it.

How do you check if points within a grid are connected vertically/horizontally? (1 away from each other)

Let's just use 1 as there is a point, and 0 if nothing.
For example, the grid:
0 0 0 0 0
1 1 1 1 1
0 0 0 0 0
1 1 1 1 1
would not be connected together, while
0 0 1 0 0
0 1 1 0 0
0 0 1 1 0
0 0 0 1 1
is.
I feel as if using something like BFS would be horribly inefficient for something that should probably be fairly simple; is there any other option?
The best asymptotic complexity for this kind of problem comes from the union find algorithm using rank and path compression.
Union find associates each new point with a group name that is either unique, taken from left or top neighbor, or unifies the groups (by making a link from one group to the other).
In the end all parents of all initially unique groups point to same item, in which case the set is connected.
Further reading with c++ source code
Further reading for image processing
#include "catch.hpp"
#include <vector>
template <typename T>
T parent(std::vector<T> &links, T item)
{
if (item == 0)
return item;
while (links[(size_t)item - 1] != item)
item = links[(size_t)item - 1];
// Should implement path compression
return item;
}
template <typename T, int N, int M>
bool is_connected(T(&array)[N][M])
{
// Assumption is that the type T is large enough to hold N*M/2 distinct entries
// Thus we can use/modify the array itself to record (roots) of distinct labels
// Of course we could copy the array into a vector of type size_t
std::vector<T> parents;
for (auto j = 0; j < N; j++)
{
for (auto i = 0; i < M; i++)
{
T &current = array[j][i];
if (!current)
continue;
T left = i ? parent(parents, array[j][i - 1]) : 0;
T above = j ? parent(parents, array[j - 1][i]) : 0;
if (left == 0)
{
if (above)
current = above;
else
parents.emplace_back(current = (T)(parents.size() + 1));
}
else
{
// Todo: implement rank based selection of joining the sets
current = left;
if (above != 0 && above != left)
parents[(size_t)above - 1] = left;
}
}
}
// Check that all intermediate disjoint sets have now a single root
if (parents.size() == 0)
return false; // is empty set connected or not?
auto last_item = parents.back();
auto root = parent(parents, last_item);
parents.pop_back();
for (auto &group : parents)
{
if (root != parent(parents, group))
return false;
}
return true;
}
SCENARIO("Is connected")
{
int arr[4][4] = {
{ 1, 0, 1, 0 },
{ 1, 0, 1, 0 },
{ 1, 0, 1, 0 },
{ 1, 1, 1, 1 }
};
auto foo = is_connected(arr);
CHECK(foo == true);
arr[3][1] = 0;
CHECK(is_connected(arr) == false);
}
BFS or DFS is indeed the proper solution. The rest is just a matter of taking advantage of properties of rectilinear grid (raster) for implementing such search algorithms in more efficient manner, preferably more efficient than a "straightforward" implementation. For example, some classic 4-way raster scanline flood-fill algorithm is a good approach for searching connected components in your grid (see the "Scanline fill" section).

Recursive Backtracking in c++

I am trying to write a program that will use backtracking to create a Sudoku solver. I have been able to create a black Sudoku grid and I can check to see if a move is a valid move. My program works fine until there are more than one choice of numbers for a square.
Problem: Will you look at my Solve method and see how I could modify it to backtrack, change the answer and move forward again. I gave the names of all of my other methods above and every one of those work.
Example input:
int board[ROWS][COLS] = {
{ 6, 0, 3, 0, 2, 0, 0, 9, 0 },
{ 0, 0, 0, 0, 5, 0, 0, 8, 0 },
{ 0, 2, 0, 4, 0, 7, 0, 0, 1 },
{ 0, 0, 6, 0, 1, 4, 3, 0, 0 },
{ 0, 0, 0, 0, 8, 0, 0, 5, 6 },
{ 0, 4, 0, 6, 0, 3, 2, 0, 0 },
{ 8, 0, 0, 2, 0, 0, 0, 0, 7 },
{ 0, 1, 0, 0, 7, 5, 8, 0, 0 },
{ 0, 3, 0, 0, 0, 6, 1, 0, 5 }
};
bool sudokuBoard::emptyCell(int i, int j);
bool sudokuBoard::isValidCol(int i, int j, int number);
bool sudokuBoard::isValidRow(int i, int j, int number);
bool sudokuBoard::isValidSquare(int i, int j, int number);
bool sudokuBoard::validMove(int i, int j, int number);
void sudokuBoard::solvePuzzle(int row, int col) {
for (int i = 1; i < 10; i++) {
if (validMove(row, col, i)) {
board[row][col] = i;
showBoard();
}
}
if (row < 8 && col < 8) {
if (col < 8) {
solvePuzzle(row, col + 1);
}
else {
col = 0;
solvePuzzle(row + 1, col);
}
}
}
Example current output:
6 5 3| 1 2 8| 4 9 0|
0 0 0| 0 5 0| 0 8 0|
0 2 0| 4 0 7| 0 0 1|
--------------------------------
0 0 6| 0 1 4| 3 0 0|
0 0 0| 0 8 0| 0 5 6|
0 4 0| 6 0 3| 2 0 0|
--------------------------------
8 0 0| 2 0 0| 0 0 7|
0 1 0| 0 7 5| 8 0 0|
0 3 0| 0 0 6| 1 0 5|
my program stops at the last 0 of the first row since there is no solution unless that previous 4 changes to a 7, the program terminates.
Backtracking can be hard to wrap your mind around the first time so we will take this step by step starting with some pseudocode of about what you have now :
while(puzzlenotsolved)
{
foreach row
{
findEmptySquare
{
findValidMove(1-9)
}
}
}
This of course gets stuck once no valid move can be found for a square because of a previously chosen value.
To counter this we need to return false when we run out of valid moves in a square, we also need to unassign our guess to make the square empty again. We then need to resume looping in the previous square where we left off.
So our find valid move function (Solve puzzle in your case) could look something like this :
bool findValidMove
{
if(noEmptySquare) {return true;} //important bit
findEmptySquare()
for (1-9)
{ if (isvalidMove )
{
assignMoveToSquare
}
if (findValidMove) {return true} //important bit
unassignMoveFromSquare
}
return false; //no values valid in this square, a previous square has a wrong value
}
Now this is considered a brute force approach, and can be optimized, but for your question lets get backtracking working and you can worry about speed optimizations later if you wish.
Note the two places I commented as important bits, the first is a signifier that there are no empty squares left. Since your program only assigns valid moves the puzzle should be complete and correct here, so the program returns true. This is the base case, In general recursive functions need a base case.
The second important bit is where the function recursively calls itself. Take note that it is still within the loop, so when a call returns false, it will resume looping in a previous call. Each call stacks onto the other like in this example except our example returns back into a loop.
Notice that the cell does not get unassigned until after the recursive function returns, this allows you to not worry about adding 1 to your rows and columns as you mentioned in your comment. All you have to do is have a reliable findEmptySquare method and recursion takes care of the rest.
Your showBoard(); method will be invaluable for debugging, i'd say put it right after assignMoveToSquare
Hopefully this helps, you are really close so I think it will. If you have further questions feel free to comment on this and I'll try to get to you when I have time.
This is what solved it for me. Thank you for all your help.
bool sudokuBoard::solvePuzzle() {
int row, col;
if (emptyCell(row, col) == false) {
return true;
}
for (int i = 1; i < 10; i++) {
cout << "Trying " << i << " in spot [" << row << "][" << col << "]" << endl;
if (validMove(row, col, i)) {
board[row][col] = i;
showBoard();
if (solvePuzzle()) {
return true;
}
board[row][col] = 0;
}
}
return false;
}

Largest Area Axis-Aligned Rectangle Inside Convex Polygon [duplicate]

Given an NxN binary matrix (containing only 0's or 1's), how can we go about finding largest rectangle containing all 0's?
Example:
I
0 0 0 0 1 0
0 0 1 0 0 1
II->0 0 0 0 0 0
1 0 0 0 0 0
0 0 0 0 0 1 <--IV
0 0 1 0 0 0
IV
For the above example, it is a 6×6 binary matrix. the return value in this case will be Cell 1:(2, 1) and Cell 2:(4, 4). The resulting sub-matrix can be square or rectangular. The return value can also be the size of the largest sub-matrix of all 0's, in this example 3 × 4.
Here's a solution based on the "Largest Rectangle in a Histogram" problem suggested by #j_random_hacker in the comments:
[Algorithm] works by iterating through
rows from top to bottom, for each row
solving this problem, where the
"bars" in the "histogram" consist of
all unbroken upward trails of zeros
that start at the current row (a
column has height 0 if it has a 1 in
the current row).
The input matrix mat may be an arbitrary iterable e.g., a file or a network stream. Only one row is required to be available at a time.
#!/usr/bin/env python
from collections import namedtuple
from operator import mul
Info = namedtuple('Info', 'start height')
def max_size(mat, value=0):
"""Find height, width of the largest rectangle containing all `value`'s."""
it = iter(mat)
hist = [(el==value) for el in next(it, [])]
max_size = max_rectangle_size(hist)
for row in it:
hist = [(1+h) if el == value else 0 for h, el in zip(hist, row)]
max_size = max(max_size, max_rectangle_size(hist), key=area)
return max_size
def max_rectangle_size(histogram):
"""Find height, width of the largest rectangle that fits entirely under
the histogram.
"""
stack = []
top = lambda: stack[-1]
max_size = (0, 0) # height, width of the largest rectangle
pos = 0 # current position in the histogram
for pos, height in enumerate(histogram):
start = pos # position where rectangle starts
while True:
if not stack or height > top().height:
stack.append(Info(start, height)) # push
elif stack and height < top().height:
max_size = max(max_size, (top().height, (pos - top().start)),
key=area)
start, _ = stack.pop()
continue
break # height == top().height goes here
pos += 1
for start, height in stack:
max_size = max(max_size, (height, (pos - start)), key=area)
return max_size
def area(size):
return reduce(mul, size)
The solution is O(N), where N is the number of elements in a matrix. It requires O(ncols) additional memory, where ncols is the number of columns in a matrix.
Latest version with tests is at https://gist.github.com/776423
Please take a look at Maximize the rectangular area under Histogram and then continue reading the solution below.
Traverse the matrix once and store the following;
For x=1 to N and y=1 to N
F[x][y] = 1 + F[x][y-1] if A[x][y] is 0 , else 0
Then for each row for x=N to 1
We have F[x] -> array with heights of the histograms with base at x.
Use O(N) algorithm to find the largest area of rectangle in this histogram = H[x]
From all areas computed, report the largest.
Time complexity is O(N*N) = O(N²) (for an NxN binary matrix)
Example:
Initial array F[x][y] array
0 0 0 0 1 0 1 1 1 1 0 1
0 0 1 0 0 1 2 2 0 2 1 0
0 0 0 0 0 0 3 3 1 3 2 1
1 0 0 0 0 0 0 4 2 4 3 2
0 0 0 0 0 1 1 5 3 5 4 0
0 0 1 0 0 0 2 6 0 6 5 1
For x = N to 1
H[6] = 2 6 0 6 5 1 -> 10 (5*2)
H[5] = 1 5 3 5 4 0 -> 12 (3*4)
H[4] = 0 4 2 4 3 2 -> 10 (2*5)
H[3] = 3 3 1 3 2 1 -> 6 (3*2)
H[2] = 2 2 0 2 1 0 -> 4 (2*2)
H[1] = 1 1 1 1 0 1 -> 4 (1*4)
The largest area is thus H[5] = 12
Here is a Python3 solution, which returns the position in addition to the area of the largest rectangle:
#!/usr/bin/env python3
import numpy
s = '''0 0 0 0 1 0
0 0 1 0 0 1
0 0 0 0 0 0
1 0 0 0 0 0
0 0 0 0 0 1
0 0 1 0 0 0'''
nrows = 6
ncols = 6
skip = 1
area_max = (0, [])
a = numpy.fromstring(s, dtype=int, sep=' ').reshape(nrows, ncols)
w = numpy.zeros(dtype=int, shape=a.shape)
h = numpy.zeros(dtype=int, shape=a.shape)
for r in range(nrows):
for c in range(ncols):
if a[r][c] == skip:
continue
if r == 0:
h[r][c] = 1
else:
h[r][c] = h[r-1][c]+1
if c == 0:
w[r][c] = 1
else:
w[r][c] = w[r][c-1]+1
minw = w[r][c]
for dh in range(h[r][c]):
minw = min(minw, w[r-dh][c])
area = (dh+1)*minw
if area > area_max[0]:
area_max = (area, [(r-dh, c-minw+1, r, c)])
print('area', area_max[0])
for t in area_max[1]:
print('Cell 1:({}, {}) and Cell 2:({}, {})'.format(*t))
Output:
area 12
Cell 1:(2, 1) and Cell 2:(4, 4)
Here is J.F. Sebastians method translated into C#:
private Vector2 MaxRectSize(int[] histogram) {
Vector2 maxSize = Vector2.zero;
int maxArea = 0;
Stack<Vector2> stack = new Stack<Vector2>();
int x = 0;
for (x = 0; x < histogram.Length; x++) {
int start = x;
int height = histogram[x];
while (true) {
if (stack.Count == 0 || height > stack.Peek().y) {
stack.Push(new Vector2(start, height));
} else if(height < stack.Peek().y) {
int tempArea = (int)(stack.Peek().y * (x - stack.Peek().x));
if(tempArea > maxArea) {
maxSize = new Vector2(stack.Peek().y, (x - stack.Peek().x));
maxArea = tempArea;
}
Vector2 popped = stack.Pop();
start = (int)popped.x;
continue;
}
break;
}
}
foreach (Vector2 data in stack) {
int tempArea = (int)(data.y * (x - data.x));
if(tempArea > maxArea) {
maxSize = new Vector2(data.y, (x - data.x));
maxArea = tempArea;
}
}
return maxSize;
}
public Vector2 GetMaximumFreeSpace() {
// STEP 1:
// build a seed histogram using the first row of grid points
// example: [true, true, false, true] = [1,1,0,1]
int[] hist = new int[gridSizeY];
for (int y = 0; y < gridSizeY; y++) {
if(!invalidPoints[0, y]) {
hist[y] = 1;
}
}
// STEP 2:
// get a starting max area from the seed histogram we created above.
// using the example from above, this value would be [1, 1], as the only valid area is a single point.
// another example for [0,0,0,1,0,0] would be [1, 3], because the largest area of contiguous free space is 3.
// Note that at this step, the heigh fo the found rectangle will always be 1 because we are operating on
// a single row of data.
Vector2 maxSize = MaxRectSize(hist);
int maxArea = (int)(maxSize.x * maxSize.y);
// STEP 3:
// build histograms for each additional row, re-testing for new possible max rectangluar areas
for (int x = 1; x < gridSizeX; x++) {
// build a new histogram for this row. the values of this row are
// 0 if the current grid point is occupied; otherwise, it is 1 + the value
// of the previously found historgram value for the previous position.
// What this does is effectly keep track of the height of continous avilable spaces.
// EXAMPLE:
// Given the following grid data (where 1 means occupied, and 0 means free; for clairty):
// INPUT: OUTPUT:
// 1.) [0,0,1,0] = [1,1,0,1]
// 2.) [0,0,1,0] = [2,2,0,2]
// 3.) [1,1,0,1] = [0,0,1,0]
//
// As such, you'll notice position 1,0 (row 1, column 0) is 2, because this is the height of contiguous
// free space.
for (int y = 0; y < gridSizeY; y++) {
if(!invalidPoints[x, y]) {
hist[y] = 1 + hist[y];
} else {
hist[y] = 0;
}
}
// find the maximum size of the current histogram. If it happens to be larger
// that the currently recorded max size, then it is the new max size.
Vector2 maxSizeTemp = MaxRectSize(hist);
int tempArea = (int)(maxSizeTemp.x * maxSizeTemp.y);
if (tempArea > maxArea) {
maxSize = maxSizeTemp;
maxArea = tempArea;
}
}
// at this point, we know the max size
return maxSize;
}
A few things to note about this:
This version is meant for use with the Unity API. You can easily make this more generic by replacing instances of Vector2 with KeyValuePair. Vector2 is only used for a convenient way to store two values.
invalidPoints[] is an array of bool, where true means the grid point is "in use", and false means it is not.
Solution with space complexity O(columns) [Can be modified to O(rows) also] and time complexity O(rows*columns)
public int maximalRectangle(char[][] matrix) {
int m = matrix.length;
if (m == 0)
return 0;
int n = matrix[0].length;
int maxArea = 0;
int[] aux = new int[n];
for (int i = 0; i < n; i++) {
aux[i] = 0;
}
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
aux[j] = matrix[i][j] - '0' + aux[j];
maxArea = Math.max(maxArea, maxAreaHist(aux));
}
}
return maxArea;
}
public int maxAreaHist(int[] heights) {
int n = heights.length;
Stack<Integer> stack = new Stack<Integer>();
stack.push(0);
int maxRect = heights[0];
int top = 0;
int leftSideArea = 0;
int rightSideArea = heights[0];
for (int i = 1; i < n; i++) {
if (stack.isEmpty() || heights[i] >= heights[stack.peek()]) {
stack.push(i);
} else {
while (!stack.isEmpty() && heights[stack.peek()] > heights[i]) {
top = stack.pop();
rightSideArea = heights[top] * (i - top);
leftSideArea = 0;
if (!stack.isEmpty()) {
leftSideArea = heights[top] * (top - stack.peek() - 1);
} else {
leftSideArea = heights[top] * top;
}
maxRect = Math.max(maxRect, leftSideArea + rightSideArea);
}
stack.push(i);
}
}
while (!stack.isEmpty()) {
top = stack.pop();
rightSideArea = heights[top] * (n - top);
leftSideArea = 0;
if (!stack.isEmpty()) {
leftSideArea = heights[top] * (top - stack.peek() - 1);
} else {
leftSideArea = heights[top] * top;
}
maxRect = Math.max(maxRect, leftSideArea + rightSideArea);
}
return maxRect;
}
But I get Time Limite exceeded excpetion when I try this on LeetCode. Is there any less complex solution?
I propose a O(nxn) method.
First, you can list all the maximum empty rectangles. Empty means that it covers only 0s. A maximum empty rectangle is such that it cannot be extended in a direction without covering (at least) one 1.
A paper presenting a O(nxn) algorithm to create such a list can be found at www.ulg.ac.be/telecom/rectangles as well as source code (not optimized). There is no need to store the list, it is sufficient to call a callback function each time a rectangle is found by the algorithm, and to store only the largest one (or choose another criterion if you want).
Note that a proof exists (see the paper) that the number of largest empty rectangles is bounded by the number of pixels of the image (nxn in this case).
Therefore, selecting the optimal rectangle can be done in O(nxn), and the overall method is also O(nxn).
In practice, this method is very fast, and is used for realtime video stream analysis.
Here is a version of jfs' solution, which also delivers the position of the largest rectangle:
from collections import namedtuple
from operator import mul
Info = namedtuple('Info', 'start height')
def max_rect(mat, value=0):
"""returns (height, width, left_column, bottom_row) of the largest rectangle
containing all `value`'s.
Example:
[[0, 0, 0, 0, 0, 0, 0, 0, 3, 2],
[0, 4, 0, 2, 4, 0, 0, 1, 0, 0],
[1, 0, 1, 0, 0, 0, 3, 0, 0, 4],
[0, 0, 0, 0, 4, 2, 0, 0, 0, 0],
[0, 0, 0, 2, 0, 0, 0, 0, 0, 0],
[4, 3, 0, 0, 1, 2, 0, 0, 0, 0],
[3, 0, 0, 0, 2, 0, 0, 0, 0, 4],
[0, 0, 0, 1, 0, 3, 2, 4, 3, 2],
[0, 3, 0, 0, 0, 2, 0, 1, 0, 0]]
gives: (3, 4, 6, 5)
"""
it = iter(mat)
hist = [(el==value) for el in next(it, [])]
max_rect = max_rectangle_size(hist) + (0,)
for irow,row in enumerate(it):
hist = [(1+h) if el == value else 0 for h, el in zip(hist, row)]
max_rect = max(max_rect, max_rectangle_size(hist) + (irow+1,), key=area)
# irow+1, because we already used one row for initializing max_rect
return max_rect
def max_rectangle_size(histogram):
stack = []
top = lambda: stack[-1]
max_size = (0, 0, 0) # height, width and start position of the largest rectangle
pos = 0 # current position in the histogram
for pos, height in enumerate(histogram):
start = pos # position where rectangle starts
while True:
if not stack or height > top().height:
stack.append(Info(start, height)) # push
elif stack and height < top().height:
max_size = max(max_size, (top().height, (pos - top().start), top().start), key=area)
start, _ = stack.pop()
continue
break # height == top().height goes here
pos += 1
for start, height in stack:
max_size = max(max_size, (height, (pos - start), start), key=area)
return max_size
def area(size):
return size[0] * size[1]
To be complete, here's the C# version which outputs the rectangle coordinates.
It's based on dmarra's answer but without any other dependencies.
There's only the function bool GetPixel(int x, int y), which returns true when a pixel is set at the coordinates x,y.
public struct INTRECT
{
public int Left, Right, Top, Bottom;
public INTRECT(int aLeft, int aTop, int aRight, int aBottom)
{
Left = aLeft;
Top = aTop;
Right = aRight;
Bottom = aBottom;
}
public int Width { get { return (Right - Left + 1); } }
public int Height { get { return (Bottom - Top + 1); } }
public bool IsEmpty { get { return Left == 0 && Right == 0 && Top == 0 && Bottom == 0; } }
public static bool operator ==(INTRECT lhs, INTRECT rhs)
{
return lhs.Left == rhs.Left && lhs.Top == rhs.Top && lhs.Right == rhs.Right && lhs.Bottom == rhs.Bottom;
}
public static bool operator !=(INTRECT lhs, INTRECT rhs)
{
return !(lhs == rhs);
}
public override bool Equals(Object obj)
{
return obj is INTRECT && this == (INTRECT)obj;
}
public bool Equals(INTRECT obj)
{
return this == obj;
}
public override int GetHashCode()
{
return Left.GetHashCode() ^ Right.GetHashCode() ^ Top.GetHashCode() ^ Bottom.GetHashCode();
}
}
public INTRECT GetMaximumFreeRectangle()
{
int XEnd = 0;
int YStart = 0;
int MaxRectTop = 0;
INTRECT MaxRect = new INTRECT();
// STEP 1:
// build a seed histogram using the first row of grid points
// example: [true, true, false, true] = [1,1,0,1]
int[] hist = new int[Height];
for (int y = 0; y < Height; y++)
{
if (!GetPixel(0, y))
{
hist[y] = 1;
}
}
// STEP 2:
// get a starting max area from the seed histogram we created above.
// using the example from above, this value would be [1, 1], as the only valid area is a single point.
// another example for [0,0,0,1,0,0] would be [1, 3], because the largest area of contiguous free space is 3.
// Note that at this step, the heigh fo the found rectangle will always be 1 because we are operating on
// a single row of data.
Tuple<int, int> maxSize = MaxRectSize(hist, out YStart);
int maxArea = (int)(maxSize.Item1 * maxSize.Item2);
MaxRectTop = YStart;
// STEP 3:
// build histograms for each additional row, re-testing for new possible max rectangluar areas
for (int x = 1; x < Width; x++)
{
// build a new histogram for this row. the values of this row are
// 0 if the current grid point is occupied; otherwise, it is 1 + the value
// of the previously found historgram value for the previous position.
// What this does is effectly keep track of the height of continous avilable spaces.
// EXAMPLE:
// Given the following grid data (where 1 means occupied, and 0 means free; for clairty):
// INPUT: OUTPUT:
// 1.) [0,0,1,0] = [1,1,0,1]
// 2.) [0,0,1,0] = [2,2,0,2]
// 3.) [1,1,0,1] = [0,0,1,0]
//
// As such, you'll notice position 1,0 (row 1, column 0) is 2, because this is the height of contiguous
// free space.
for (int y = 0; y < Height; y++)
{
if (!GetPixel(x, y))
{
hist[y]++;
}
else
{
hist[y] = 0;
}
}
// find the maximum size of the current histogram. If it happens to be larger
// that the currently recorded max size, then it is the new max size.
Tuple<int, int> maxSizeTemp = MaxRectSize(hist, out YStart);
int tempArea = (int)(maxSizeTemp.Item1 * maxSizeTemp.Item2);
if (tempArea > maxArea)
{
maxSize = maxSizeTemp;
maxArea = tempArea;
MaxRectTop = YStart;
XEnd = x;
}
}
MaxRect.Left = XEnd - maxSize.Item1 + 1;
MaxRect.Top = MaxRectTop;
MaxRect.Right = XEnd;
MaxRect.Bottom = MaxRectTop + maxSize.Item2 - 1;
// at this point, we know the max size
return MaxRect;
}
private Tuple<int, int> MaxRectSize(int[] histogram, out int YStart)
{
Tuple<int, int> maxSize = new Tuple<int, int>(0, 0);
int maxArea = 0;
Stack<Tuple<int, int>> stack = new Stack<Tuple<int, int>>();
int x = 0;
YStart = 0;
for (x = 0; x < histogram.Length; x++)
{
int start = x;
int height = histogram[x];
while (true)
{
if (stack.Count == 0 || height > stack.Peek().Item2)
{
stack.Push(new Tuple<int, int>(start, height));
}
else if (height < stack.Peek().Item2)
{
int tempArea = (int)(stack.Peek().Item2 * (x - stack.Peek().Item1));
if (tempArea > maxArea)
{
YStart = stack.Peek().Item1;
maxSize = new Tuple<int, int>(stack.Peek().Item2, (x - stack.Peek().Item1));
maxArea = tempArea;
}
Tuple<int, int> popped = stack.Pop();
start = (int)popped.Item1;
continue;
}
break;
}
}
foreach (Tuple<int, int> data in stack)
{
int tempArea = (int)(data.Item2 * (x - data.Item1));
if (tempArea > maxArea)
{
YStart = data.Item1;
maxSize = new Tuple<int, int>(data.Item2, (x - data.Item1));
maxArea = tempArea;
}
}
return maxSize;
}
An appropriate algorithm can be found within Algorithm for finding the largest inscribed rectangle in polygon (2019).
I implemented it in python:
import largestinteriorrectangle as lir
import numpy as np
grid = np.array([[0, 0, 0, 0, 1, 0],
[0, 0, 1, 0, 0, 1],
[0, 0, 0, 0, 0, 0],
[1, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 1],
[0, 0, 1, 0, 0, 0]],
"bool")
grid = ~grid
lir.lir(grid) # [1, 2, 4, 3]
the result comes as x, y, width, height

Generating all possible permutations for a given base and number of digits

I'm sure this is pretty simple, but I'm stumped for a way to do this. Essentially if I have an array with P collumns and V^P rows, how can I fill in all the combinations, that is, essentially, all possible numbers in base V of P digits. For example, for P=3 and V=2:
000
001
010
011
100
101
110
111
Keep in mind that this is an 2 dimensional array, not an array of ints.
For P=4 and V=3.
0000
0001
0002
0010
0011
0012
....
Having this array generated, the rest of work for what I'm trying to devolop is trivial. So having some code/tips on how to do this would be greatly appreciated. Thanks.
Taking your example with P=3 and V=2, in the first column you need this sequence of numbers:
0, 0, 0, 0, 1, 1, 1, 1
So you essentially want four 0's followed by four 1's.
In the second column you need:
0, 0, 1, 1, 0, 0, 1, 1
So you want two 0's followed by two 1's, followed by the same again.
In general, in column number n, you need V^(P-n) of each digit, repeated V^(n-1) times.
Example when P=3 and V=2:
Column 1: We need V^(P-n) = 2^(3-1) = 4 of each digit, repeated V^(n-1) = 2^0 = 1 times:
[0, 0, 0, 0, 1, 1, 1, 1]
Column 2: We need V^(P-n) = 2^(3-2) = 2 of each digit, repeated V^(n-1) = 2^1 = 2 times:
[0, 0, 1, 1], [0, 0, 1, 1]
Column 3: We need V^(P-n) = 2^(3-3) = 1 of each digit, repeated V^(n-1) = 2^2 = 4 times:
[0, 1], [0, 1], [0, 1], [0, 1]
Some Python code that generates this sequence:
def sequence(v, p, column):
subsequence = []
for i in range(v):
subsequence += [i] * v**(p - column)
return subsequence * v**(column - 1)
Basically this is making a list of vp numbers from 0 to the largest number of digit width p in base v. numpy.base_repr can be used to do this in Python:
from numpy import base_repr
def base_of_size(base, size):
for i in range(base ** size):
yield base_repr(i, base).rjust(size, "0")
Additionally, itertools.product(range(v), repeat=p) is another Python builtin that does the job (it turns out most efficiently--see benchmark below).
Here's the algorithm from numpy.base_repr translated to C# (Convert.ToString() is very selective about bases):
using System;
using System.Collections.Generic;
class Converter
{
public static IEnumerable<string> BaseOfSize(int baseN, int size)
{
for (int i = 0; i < Math.Pow(baseN, size); i++)
{
yield return BaseRepr(i, baseN).PadLeft(size, '0');
}
}
public static string BaseRepr(int n, int baseN)
{
string digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
var res = new List<char>();
for (int num = Math.Abs(n); num > 0; num /= baseN)
{
res.Add(digits[num%baseN]);
}
if (n < 0) res.Add('-');
res.Reverse();
return string.Join("", res);
}
public static void Main(string[] args)
{
foreach (var n in BaseOfSize(2, 3))
{
Console.WriteLine(n);
}
Console.WriteLine();
foreach (var n in BaseOfSize(3, 4))
{
Console.WriteLine(n);
}
}
}
Output:
000
001
010
011
100
101
110
111
0000
0001
0002
0010
0011
0012
0020
...
2220
2221
2222
Although the numpy version is simple to use and iterative, it's also slow. Using a recursive DFS approach means we don't have to compute each number from scratch, but can simply increment the previous number until we reach a new leaf. These versions don't use generators, but it's an easy adjustment:
Python:
def base_of_size(base, size):
def recurse(res, row, i=0):
if i >= size:
res.append(row[:])
else:
for j in range(base):
row[i] = j
recurse(res, row, i + 1)
return res
return recurse([], [None] * size)
C#:
using System;
using System.Collections.Generic;
class Converter
{
public static List<List<int>> BaseOfSize(int v, int p)
{
var res = new List<List<int>>();
BaseOfSize(v, p, 0, new List<int>(new int[p]), res);
return res;
}
private static void BaseOfSize(int v, int p, int i, List<int> row, List<List<int>> res)
{
if (i >= p)
{
res.Add(new List<int>(row));
}
else
{
for (int j = 0; j < v; j++)
{
row[i] = j;
BaseOfSize(v, p, i + 1, row, res);
}
}
}
}
Quick benchmark (with generators):
from itertools import product
from time import time
from numpy import base_repr
def base_of_size(base, size):
def recurse(res, row, i=0):
if i >= size:
yield row[:]
else:
for j in range(base):
row[i] = j
yield from recurse(res, row, i + 1)
return res
yield from recurse([], [None] * size)
def base_of_size2(base, size):
for i in range(base ** size):
yield base_repr(i, base).rjust(size, "0")
if __name__ == "__main__":
start = time()
list(base_of_size(10, 6))
end = time()
print("dfs:", end - start)
start = time()
list(base_of_size2(10, 6))
end = time()
print("base_repr:", end - start)
start = time()
list(product(range(10), repeat=6))
end = time()
print("product:", end - start)
Output:
dfs: 4.616123676300049
base_repr: 9.795292377471924
product: 0.5925478935241699
itertools.product wins by a long shot.
If there is varying number of options in each "digit", this code can be used.
Maybe in some optimization tool there exist algorithm to do this, because it could be useful for brute force method. Code below adds a column which shows "the value of biggest digit", it can be ignored:
import numpy as np
val=np.arange(15)
options=[2,2,3]
print(val)
print(options)
opt = options + [1] # Assumes options to be a list
opt_cp = np.flip(np.cumprod(np.flip(np.array(opt))))
ret = np.floor_divide(val[:,np.newaxis], opt_cp[np.newaxis,:])
ret[:,1:] = np.remainder(ret[:,1:], np.array(opt[:-1])[np.newaxis,:])
inds = ret[:,1:]
print(inds)
You could also use numpy's N-dimensional mesh grid functions.
E.g.
np.mgrid[0:2,0:2,0:2].reshape((3, 8)).T
array([[0, 0, 0],
[0, 0, 1],
[0, 1, 0],
[0, 1, 1],
[1, 0, 0],
[1, 0, 1],
[1, 1, 0],
[1, 1, 1]])
or
np.stack(np.meshgrid(range(2), range(2), range(2), indexing='ij')).reshape(3, -1).T
or in general for any P, V:
np.mgrid[[slice(0, V)]*P].reshape((P, -1)).T
or
np.stack(np.meshgrid(*[range(V)]*P, indexing='ij')).reshape((P, -1)).T
There must be a more obvious way but I can't think what.