I have a function called Crossed1 that I'm trying to implement to collect values into an array.
Then from that array I want to find the highest value of the last 5 bars.
int Crossed1()
{
static int CurrentDirection1=0;
static int LastDirection1=0;
static bool FirstTime1=true;
//----
if((BB20DO<BB30DO)&& (CandleCLOSE<BB20DO) && (CandleCLOSEp<BB20DOp) && (RSIi< 30))
CurrentDirection1=1; // line1 above line2
if(BB20DO>BB30DO)
CurrentDirection1=2; // line1 below line2
//----
if(FirstTime1==true) // Need to check if this is the first time the function is run
{
FirstTime1=false; // Change variable to false
LastDirection1=CurrentDirection1; // Set new direction
return (0);
}
if(CurrentDirection1!=LastDirection1 && FirstTime1==false) // If not the first time and there is a direction change
{
LastDirection1=CurrentDirection1; // Set new direction
return(CurrentDirection1); // 1 for up, 2 for down
}
else
{
return(0); // No direction change
}
}
Arraymax to retrieve the max value
int ArrayCalcMax()
{
int bars = 5;
int malookback=bars;
double madaily[5];
double dllv;
for(int i = 0; i < malookback; i++)
madaily[i] = Crossed1();
Print(" array[",i,"] = ",madaily[i]);
int maxPos = ArrayMaximum(madaily,malookback,0); // Check the "maxPos" to make sure it is in range as it could be "-1" if it fails
Print(" maxPos = ", maxPos );
if( maxPos >= 0 )
{
dllv = madaily[maxPos]; // Please note that "dllv" is a local variable that will be discarded as soon as you return
Print(" dllv = ", dllv );
}
else
Print("Something is wrong!");
return(dllv);
}
I think as the code is currently, I'm only collecting the current value in the array, is that correct?
If i try to include the i, it returns the error Wrong parameters count
How can I solve this?
These lines:
for(int i = 0; i < malookback; i++)
madaily[i] = Crossed1();
Print(" array[",i,"] = ",madaily[i]);
don't do what you think they do.
They translate to
for(int i = 0; i< malookback; i++)
{
madaily[i] = Crossed1();
}
Print(" array[",i,"] = ",madaily[i]); // Error because i has been destructed
When writing loop statements in C++, you have to include curly braces {} around its contents if it contains more than one line of code.
Change those lines to
for(int i = 0; i < malookback; i++)
{
madaily[i] = Crossed1();
Print(" array[",i,"] = ",madaily[i]);
}
and it will work as intended.
Thank you JensB.
as you said it worked OK.
nonetheless the value doesn't store in the next calculation:
17:10:44.622 2019.08.23 12:20:00 BBReverse V1 EURUSD,H4: array[0] = 1
0 17:10:44.622 2019.08.23 12:20:00 BBReverse V1 EURUSD,H4: array[1] = 0
0 17:10:44.622 2019.08.23 12:20:00 BBReverse V1 EURUSD,H4: array[2] = 0
0 17:10:44.622 2019.08.23 12:20:00 BBReverse V1 EURUSD,H4: array[3] = 0
0 17:10:44.622 2019.08.23 12:20:00 BBReverse V1 EURUSD,H4: array[4] = 0
0 17:10:44.622 2019.08.23 12:20:00 BBReverse V1 EURUSD,H4: maxPos = 0
0 17:10:44.622 2019.08.23 12:20:00 BBReverse V1 EURUSD,H4: dllv = 1
the result for the array [1] should be 1 and it appears the value zero.
17:10:44.622 2019.08.23 12:40:00 BBReverse V1 EURUSD,H4: array[0] = 0
0 17:10:44.622 2019.08.23 12:40:00 BBReverse V1 EURUSD,H4: array[1] = 0
0 17:10:44.622 2019.08.23 12:40:00 BBReverse V1 EURUSD,H4: array[2] = 0
0 17:10:44.622 2019.08.23 12:40:00 BBReverse V1 EURUSD,H4: array[3] = 0
0 17:10:44.622 2019.08.23 12:40:00 BBReverse V1 EURUSD,H4: array[4] = 0
0 17:10:44.622 2019.08.23 12:40:00 BBReverse V1 EURUSD,H4: maxPos = 0
0 17:10:44.622 2019.08.23 12:40:00 BBReverse V1 EURUSD,H4: dllv = 0
Thanks
André
Related
Given an N X M binary matrix ( every element is either 1 or 0) , find the minimum number of moves to convert it to an all 0 matrix.
For converting a matrix, one can choose squares of any size and convert the value of that square. '1' changes to '0' and '0' changes to '1'.This process can be done multiple times with square of the same size. Converting any square counts as 1 move.
Calculate minimum number of moves required..
Example :
input matrix
0 1 1
0 0 0
0 1 1
we need to calculate minimum moves to convert this to all '0' matrix
0 0 0
0 0 0
0 0 0
Here,
For square of size 1 ( 1 X 1 or single element sub-matrix), the total number of moves required to convert this matrix is 4 . he converts elements for position (1,2),(1,3),(3,2),(3,3)
For square of size 2 ( 2 X 2 or single element sub-matrix), it takes 2 moves to convert the matrix
First we can convert elements from (1,2) to (2,3) and the matrix becomes, {{0 0 0}, {0 1 1}, {0 1 1}}
And then we convert elements from (2,2)to (3,3) and the matrix becomes ``{{0 0 0}, {0 0 0}, {0 0 0}}```
So minimum is 2.
Could some help in designing an approach to this ?
I attempted to solve it using Gaussian elimination for every possible square size. But the result is not correct here. There must be some gap in my approach to this problem.
package com.practice.hustle;
import java.util.Arrays;
public class GaussianElimination {
public static void main(String[] args) {
int countMoves = Integer.MAX_VALUE;
byte[][] inputMatrix = new byte[3][3];
inputMatrix[0][0] = 0;
inputMatrix[0][1] = 1;
inputMatrix[0][2] = 1;
inputMatrix[1][0] = 0;
inputMatrix[1][1] = 0;
inputMatrix[1][2] = 0;
inputMatrix[2][0] = 0;
inputMatrix[2][1] = 1;
inputMatrix[2][2] = 1;
int N = inputMatrix.length;
int M = inputMatrix[0].length;
int maxSize = Math.min(N, M);
for (int j = 2; j <= maxSize; ++j) { // loop for every possible square size
byte[][] a = new byte[N * M][(N * M) + 1];
for (int i = 0; i < N * M; i++) { // logic for square wise toggle for every element of N*M elements
byte seq[] = new byte[N * M + 1];
int index_i = i / M;
int index_j = i % M;
if (index_i <= N - j && index_j <= M - j) {
for (int c = 0; c < j; c++) {
for (int k = 0; k < j; k++) {
seq[i + k + M * c] = 1;
}
}
a[i] = seq;
} else {
if (index_i > N - j) {
seq = Arrays.copyOf(a[i - M], N * M + 1);
} else {
seq = Arrays.copyOf(a[i - 1], N * M + 1);
}
}
seq[N * M] = inputMatrix[index_i][index_j];
a[i] = seq;
}
System.out.println("\nSolving for square size = " + j);
print(a, N * M);
int movesPerSquareSize = gaussian(a);
if (movesPerSquareSize != 0) { // to calculate minimum moves
countMoves = Math.min(countMoves, movesPerSquareSize);
}
}
System.out.println(countMoves);
}
public static int gaussian(byte a[][]) {
// n X n+1 matrix
int N = a.length;
for (int k = 0; k < N - 1; k++) {
// Finding pivot element
int max_i = k, max_value = a[k][k];
for (int i = k + 1; i < N; i++) {
if (a[i][k] > max_value) {
max_value = a[i][k];
max_i = i;
}
}
// swap max row with kth row
byte[] temp = a[k];
a[k] = a[max_i];
a[max_i] = temp;
// convert to 0 all cells below pivot in the column
for (int i = k+1; i < N; i++) {
// int scalar = a[i][k] + a[k][k]; // probability of a divide by zero
if (a[i][k] == 1) {
for (int j = 0; j <= N; j++) {
if (a[i][j] == a[k][j]) {
a[i][j] = 0;
} else {
a[i][j] = 1;
}
}
}
}
}
System.out.println("\n\tAfter applying gaussian elimination : ");
print(a, N);
int count = 0;
for (int i = 0; i < N; i++) {
if (a[i][N] == 1)
++count;
}
return count;
}
private static void print(byte[][] a, int N) {
for (int i = 0; i < N; i++) {
System.out.print("\t ");
for (int j = 0; j < N + 1; j++) {
System.out.print(a[i][j] + " ");
}
System.out.println(" ");
}
}
}
Its giving final reduced Euler matrix formed is incorrect and thereby the result is also incorrect.
I think its failing due to the logic used for element like - the cell at index-(2,3) , for that we are not sure which square would it be a part of ( either the square from (1,2) to (2,3) or the square from ( 2,2) to (3,3))
here the input matrix to Gaussian algo is having exactly same sequence at 2nd and 3rd row which could be the culprit of incorrect results.
1 1 0 1 1 0 0 0 0 0
* 0 1 1 0 1 1 0 0 0 1 *
* 0 1 1 0 1 1 0 0 0 1 *
0 0 0 1 1 0 1 1 0 0
0 0 0 0 1 1 0 1 1 0
0 0 0 0 1 1 0 1 1 0
0 0 0 1 1 0 1 1 0 0
0 0 0 0 1 1 0 1 1 1
0 0 0 0 1 1 0 1 1 1
for a sqaure size 2, the above program prints :
Solving for square size = 2
The input to Gaussian algo :
1 1 0 1 1 0 0 0 0 0
0 1 1 0 1 1 0 0 0 1
0 1 1 0 1 1 0 0 0 1
0 0 0 1 1 0 1 1 0 0
0 0 0 0 1 1 0 1 1 0
0 0 0 0 1 1 0 1 1 0
0 0 0 1 1 0 1 1 0 0
0 0 0 0 1 1 0 1 1 1
0 0 0 0 1 1 0 1 1 1
After applying gaussian elimination :
1 0 1 0 0 0 1 0 1 1
0 1 1 0 0 0 0 1 1 0
0 0 0 0 0 0 0 0 0 0
0 0 0 1 0 1 1 0 1 0
0 0 0 0 1 1 0 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 0 1
0 0 0 0 0 0 0 0 0 1
Problem (THE QUESTION)
Strokes to paint
Alex wants to paint a picture. In one stroke, Alex can only paint the same colored cells which are joined via some edge.
Given the painting as a 2-dimensional array of letters indicating colors, determine the minimum number of strokes to completely paint the picture.
Example: The canvas height, h = 3 and width, w = 5 is to be painted with picture=["aabba", "aabba", "aaacb"]. The diagram below shows the 5 strokes needed to paint the canvas. It takes two strokes each for colors a and b, and one for c
a a b b a
a a b b a
a a a c b
Function Description Complete the function strokesRequired in the editor below. The function must return an integer, the minimum number of strokes required to paint the canvas.
strokesRequired has the following parameter(s): picture[picture[0],...picture[h-1]] an array of strings where each string represents one row of the picture to be painted
Constraints
1 <= h <= 10^5
1<= w <= 10^5
1 <= h*w <= 10^5
len(pictureffl) = w (where 0 <= i < h)
picture[i][j] <- (a, b, c) (where 0 <= i < h and 0 <= j < w)
Hello.. so i attended one company interview and they asked me this problem and iam not getting any ideas please help
class Paint:
def __init__(self, row, col, arr):
self.ROW = row
self.COL = col
self.arr = arr
def visit(self, i, j, visited):
ele = self.arr[i][j]
for k in range(i,self.ROW):
for l in range(j, self.COL):
if self.arr[k][l]==ele:
visited[k][l]=True
v=l
if l>0 and self.arr[k][l-1]==ele and not visited[k][l-1]:
self.visit(k, l-1, visited)
if k>0 and self.arr[k-1][l]==ele and not visited[k-1][l]:
self.visit(k-1, l, visited)
elif l>=v:
break
# 2D matrix
def count_cells(self):
# Make an array to mark visited cells.
# Initially all cells are unvisited
visited = [[False for j in range(self.COL)]for i in range(self.ROW)]
# Initialize count as 0 and travese
count = 0
for i in range(self.ROW):
for j in range(self.COL):
# If a cell value false then not visited yet
# then visit
if visited[i][j] == False:
# Visit all cells in the array
self.visit(i, j, visited)
print(visited)
count += 1
return count
arr = ["aabba", "aabba", "aaacb"]
row = len(arr)
col = len(arr[0])
p = Paint(row, col, arr)
print (p.count_cells())
function visit(picture, i, j, visitedBoxes) {
const currentElem = picture[i][j];
if (picture[i][j] === currentElem) {
visitedBoxes[i][j] = true;
// go in four directions
// south
if (i + 1 < picture.length && picture[i+1][j] === currentElem && visitedBoxes[i+1][j] === false) {
visit(picture, i+1, j, visitedBoxes);
}
// west
if (j+ 1 < picture[i].length && picture[i][j+1] === currentElem && visitedBoxes[i][j+1] === false) {
visit(picture, i, j+1, visitedBoxes);
}
// north
if (i > 0 && picture[i-1][j] === currentElem && visitedBoxes[i-1][j] === false) {
visit(picture, i-1, j, visitedBoxes);
}
// west
if (j > 0 && picture[i, j-1] === currentElem && visitedBoxes[i, j-1] === false) {
visit(picture, i, j-1, visitedBoxes);
}
}
}
function countStrokes(picture) {
const visitedBoxes = [];
for (let i = 0; i < picture.length; i++) {
visitedBoxes[i] = [];
for(let j = 0; j < picture[i].length; j++) {
visitedBoxes[i][j] = false;
}
}
let srokesCount = 0;
for (let i = 0; i < picture.length; i++) {
for (let j = 0; j < picture[i].length; j++) {
if (!visitedBoxes[i][j]) {
visit(picture, i, j, visitedBoxes);
srokesCount++;
}
}
}
console.log('Strokes Count', srokesCount);
}
countStrokes(['aaaba', 'ababa', 'aacba']);
This will output 5.
Also you can use
function printVisited(visitedBoxes) {
for (let i = 0; i < visitedBoxes.length; i++) {
let str = ''
for(let j = 0; j < visitedBoxes[i].length; j++) {
str += visitedBoxes[i][j] ? '1 ': '0 ';
}
console.log(str);
}
console.log('-------------');
}
to print after each loop.
Output
1 1 1 0 0
1 0 1 0 0
1 1 0 0 0
-------------
1 1 1 1 0
1 0 1 1 0
1 1 0 1 0
-------------
1 1 1 1 1
1 0 1 1 1
1 1 0 1 1
-------------
1 1 1 1 1
1 1 1 1 1
1 1 0 1 1
-------------
1 1 1 1 1
1 1 1 1 1
1 1 1 1 1
-------------
Strokes Count 5
You are given a set of integers and your task is the following: split them into 2 subsets with an equal sum in such way that these sums are maximal. You are allowed not to use all given integers, that's fine. If it's just impossible, report error somehow.
My approach is rather straightforward: at each step, we pick a single item, mark it as visited, update current sum and pick another item recursively. Finally, try skipping current element.
It works on simpler test cases, but it fails one:
T = 1
N = 25
Elements: 5 27 24 12 12 2 15 25 32 21 37 29 20 9 24 35 26 8 31 5 25 21 28 3 5
One can run it as follows:
1 25 5 27 24 12 12 2 15 25 32 21 37 29 20 9 24 35 26 8 31 5 25 21 28 3 5
I expect sum to be equal 239, but it the algorithm fails to find such solution.
I've ended up with the following code:
#include <iostream>
#include <unordered_set>
using namespace std;
unordered_set<uint64_t> visited;
const int max_N = 50;
int data[max_N];
int p1[max_N];
int p2[max_N];
int out1[max_N];
int out2[max_N];
int n1 = 0;
int n2 = 0;
int o1 = 0;
int o2 = 0;
int N = 0;
void max_sum(int16_t &sum_out, int16_t sum1 = 0, int16_t sum2 = 0, int idx = 0) {
if (idx < 0 || idx > N) return;
if (sum1 == sum2 && sum1 > sum_out) {
sum_out = sum1;
o1 = n1;
o2 = n2;
for(int i = 0; i < n1; ++i) {
out1[i] = p1[i];
}
for (int i = 0; i < n2; ++i) {
out2[i] = p2[i];
}
}
if (idx == N) return;
uint64_t key = (static_cast<uint64_t>(sum1) << 48) | (static_cast<uint64_t>(sum2) << 32) | idx;
if (visited.find(key) != visited.end()) return;
visited.insert(key);
p1[n1] = data[idx];
++n1;
max_sum(sum_out, sum1 + data[idx], sum2, idx + 1);
--n1;
p2[n2] = data[idx];
++n2;
max_sum(sum_out, sum1, sum2 + data[idx], idx + 1);
--n2;
max_sum(sum_out, sum1, sum2, idx + 1);
}
int main() {
int T = 0;
cin >> T;
for (int t = 1; t <= T; ++t) {
int16_t sum_out;
cin >> N;
for(int i = 0; i < N; ++i) {
cin >> data[i];
}
n1 = 0;
n2 = 0;
o1 = 0;
o2 = 0;
max_sum(sum_out);
int res = 0;
int res2 = 0;
for (int i = 0; i < o1; ++i) res += out1[i];
for (int i = 0; i < o2; ++i) res2 += out2[i];
if (res != res2) cerr << "ERROR: " << "res1 = " << res << "; res2 = " << res2 << '\n';
cout << "#" << t << " " << res << '\n';
visited.clear();
}
}
I have the following questions:
Could someone help me to troubleshoot the failing test? Are there any obvious problems?
How could I get rid of unordered_set for marking already visited sums? I prefer to use plain C.
Is there a better approach? Maybe using dynamic programming?
Another approach is consider all the numbers till [1,(2^N-2)].
Consider the position of each bit to position of each element .Iterate all numbers from [1,(2^N-2)] then check for each number .
If bit is set you can count that number in set1 else you can put that number in set2 , then check if sum of both sets are equals or not . Here you will get all possible sets , if you want just one once you find just break.
1) Could someone help me to troubleshoot the failing test? Are there any obvious problems?
The only issue I could see is that you have not set sum_out to 0.
When I tried running the program it seemed to work correctly for your test case.
2) How could I get rid of unordered_set for marking already visited sums? I prefer to use plain C.
See the answer to question 3
3) Is there a better approach? Maybe using dynamic programming?
You are currently keeping track of whether you have seen each choice of value for first subset, value for second subset, amount through array.
If instead you keep track of the difference between the values then the complexity significantly reduces.
In particular, you can use dynamic programming to store an array A[diff] that for each value of the difference either stores -1 (to indicate that the difference is not reachable), or the greatest value of subset1 when the difference between subset1 and subset2 is exactly equal to diff.
You can then iterate over the entries in the input and update the array based on either assigning each element to subset1/subset2/ or not at all. (Note you need to make a new copy of the array when computing this update.)
In this form there is no use of unordered_set because you can simply use a straight C array. There is also no difference between subset1 and subset2 so you can only keep positive differences.
Example Python Code
from collections import defaultdict
data=map(int,"5 27 24 12 12 2 15 25 32 21 37 29 20 9 24 35 26 8 31 5 25 21 28 3 5".split())
A=defaultdict(int) # Map from difference to best value of subset sum 1
A[0] = 0 # We start with a difference of 0
for a in data:
A2 = defaultdict(int)
def add(s1,s2):
if s1>s2:
s1,s2=s2,s1
d = s2-s1
if d in A2:
A2[d] = max( A2[d], s1 )
else:
A2[d] = s1
for diff,sum1 in A.items():
sum2 = sum1 + diff
add(sum1,sum2)
add(sum1+a,sum2)
add(sum1,sum2+a)
A = A2
print A[0]
This prints 239 as the answer.
For simplicity I haven't bothered with the optimization of using a linear array instead of the dictionary.
A very different approach would be to use a constraint or mixed integer solver. Here is a possible formulation.
Let
x(i,g) = 1 if value v(i) belongs to group g
0 otherwise
The optimization model can look like:
max s
s = sum(i, x(i,g)*v(i)) for all g
sum(g, x(i,g)) <= 1 for all i
For two groups we get:
---- 31 VARIABLE s.L = 239.000
---- 31 VARIABLE x.L
g1 g2
i1 1
i2 1
i3 1
i4 1
i5 1
i6 1
i7 1
i8 1
i9 1
i10 1
i11 1
i12 1
i13 1
i14 1
i15 1
i16 1
i17 1
i18 1
i19 1
i20 1
i21 1
i22 1
i23 1
i25 1
We can easily do more groups. E.g. with 9 groups:
---- 31 VARIABLE s.L = 52.000
---- 31 VARIABLE x.L
g1 g2 g3 g4 g5 g6 g7 g8 g9
i2 1
i3 1
i4 1
i5 1
i6 1
i7 1
i8 1
i9 1
i10 1
i11 1
i12 1
i13 1
i14 1
i15 1
i16 1
i17 1
i19 1
i20 1
i21 1
i22 1
i23 1
i24 1
i25 1
If there is no solution, the solver will select zero elements in each group with a sum s=0.
This question already has answers here:
Algorithm for finding the fewest rectangles to cover a set of rectangles without overlapping
(2 answers)
Closed 5 years ago.
Say I have the following binary matrix:
0 0 0 1 1 1 0
0 0 0 1 1 1 0
0 0 0 1 1 1 0
1 1 1 1 1 1 1
1 1 1 1 1 1 1
1 1 1 1 1 1 1
0 0 0 1 1 1 0
0 0 0 1 1 1 0
0 0 0 1 1 1 0
I want to find the set of rectangles parallel to the x and y axis that covers every 1 at least once and covers not a single 0 which has minimal cardinality (the least amount of rectangles). In the example above this would be the rectangles ((0, 3), (6, 5)) and ((3, 0), (5, 8)) (notation is in the form (topleft, bottomright)) - the minimal solution is using two rectangles.
My previous attempt was finding the rectangle with the largest area covering only 1's, adding that rectangle to the set and then marking all those 1's as 0's, until all 1's are gone. While this set would cover every 1 and not a single 0, it won't necessarily have minimal cardinality (this algorithm will fail on the example above).
I think you should replace covered 1's with 2's instead of 0's. This way you can include the 2's when covering 1's and still not cover any 0's.
Here's what I came up with:
#include <stdio.h>
#include <stdlib.h>
struct board {
int **data;
int w,h;
};
int load_board(char *, struct board *);
void print_board(struct board *);
int max_height_with_fixed_w(struct board *board, int i, int j, int w) {
int jj = -1, ii;
if (board->data[j][i] != 0) {
for (jj = j; jj < board->h && board->data[jj][i] != 0; jj++) {
for (ii = i; ii - i < w; ii++) {
if (board->data[jj][ii] == 0)
return jj - j;
}
}
printf("maximum height = %d\n", jj);
}
return jj - j;
}
void find_largest_rect_from(
struct board *board,
int i, int j, int *ei, int *ej) {
int max_w = 0, max_h = 0, max_a = 0;
*ei = *ej = -1;
for (max_w = 0; max_w < board->w - i &&
(board->data[j][i + max_w] != 0);
max_w++) {
int max_aa;
int max_hh = max_height_with_fixed_w(board, i, j, max_w + 1);
if (max_hh > max_h) {
max_h = max_hh;
}
max_aa = max_hh * (max_w + 1);
printf(" area: %d x %d = %d\n", max_hh, max_w + 1, max_aa);
if (max_aa > max_a) {
max_a = max_aa;
*ei = i + max_w;
*ej = j + max_hh - 1;
}
}
printf("max width : %d\n", max_w);
printf("max height: %d\n", max_h);
printf("max area : %d\n", max_a);
}
int main(int arc, char **argv) {
struct board board;
int jj, ii, i = 0, j = 0;
int total_rects = 0;
if(load_board(argv[1], &board)) return 1;
print_board(&board);
for (j = 0; j < board.h; j++) {
for (i = 0; i < board.w; i++) {
if (board.data[j][i] == 1) {
find_largest_rect_from(&board, i, j, &ii, &jj);
printf("largest from %d, %d ends at %d,%d\n", i, j, ii, jj);
int marki, markj;
total_rects++;
for (markj = j; markj <= jj; markj++) {
for (marki = i; marki <= ii; marki++) {
board.data[markj][marki] = 2;
}
}
print_board(&board);
}
}
}
printf("minimum %d rects are required\n", total_rects);
return 0;
}
int load_board(char *fname, struct board *board) {
FILE *file = fopen(fname, "r");
int j,i;
if (!file) return 1;
fscanf(file, "%d %d", &board->w, &board->h);
board->data = (int**)malloc(sizeof(int*)*board->h);
for (j = 0; j < board->h; j++) {
board->data[j] = (int*)malloc(sizeof(int)*board->w);
for (i = 0; i < board->w; i++) {
fscanf(file, "%d", &board->data[j][i]);
}
}
return 0;
}
void print_board(struct board *board) {
int i,j;
printf("board size: %d, %d\n", board->w, board->h);
for (j = 0; j < board->h; j++) {
for (i = 0; i < board->w; i++) {
printf("%d ", board->data[j][i]);
} printf("\n");
}
}
Example input 1:
7 9
0 0 0 1 1 1 0
0 0 0 1 1 1 0
0 0 0 1 1 1 0
1 1 1 1 1 1 1
1 1 1 1 1 1 1
1 1 1 1 1 1 1
0 0 0 1 1 1 0
0 0 0 1 1 1 0
0 0 0 1 1 1 0
Example input 2:
7 7
0 0 0 1 0 0 0
0 0 1 1 1 0 0
0 1 1 1 1 1 0
1 1 1 1 1 1 1
0 1 1 1 1 1 0
0 0 1 1 1 0 0
0 0 0 1 0 0 0
Idea for an algorithm:
As long as there are 1s in the matrix do:
For every 1 that doesn't have 1 above it AND doesn't have 1 to its left, do:
Go greedy: start from this 1 and go in diagonal to the right and down, as long as there are 1s on the way - create a rectangle and change the 1s of the created rectangle into 0s.
I'd go for an algorithm that picks points and expands until it comsumed all possible space, and then picks more, until all points on the grid have been consumed.
For your example, say we're consuming 1s.
I'll pick (0,3), the uppermost of the leftmost 1s. My rectangle would start at a size of 0,0. I'd expand it right and down until it grew to a size of 6,2. At this point, I'd mark those points as occupied.
I'd then pick another point, say (3,0), with a rectangle of size 0,0. I'd grow it down and right until it took up the largest available space, at a size of 2,6.
Consider the following:
0 0 0 1 0 0 0
0 0 1 1 1 0 0
0 1 1 1 1 1 0
1 1 1 1 1 1 1
0 1 1 1 1 1 0
0 0 1 1 1 0 0
0 0 0 1 0 0 0
You can easily determine that for any random starting points, it will always take 4 rectangles.
In order to mark points as "occupied", you should mark them differently than those marked "unconsumable". You can then differentiate between unconsumable (which cannot be expanded into) and "occupied" (which may be expanded into, but do not have to be since they already have been).
I basically have a few variables
0 < na < 250
0 < max <= 16
nb = (na + max - 1) / max
n has the following characterstics
0 <= i < nb - 1 => n = max
i = nb - 1 => n = na - i * max
Is there an easy way to do this without the ternary operator?
for (i = 0; i<nb;i++) {
n = ((i + 1) * max > na ? na - (i * max) : max);
}
Examples
na = 5
max = 2
nb = 3
i = 0 => n = 2
i = 1 => n = 2
i = 2 => n = 1
na = 16
max = 4
nb = 4
i = 0 => n = 4
i = 1 => n = 4
i = 2 => n = 4
i = 3 => n = 4
na = 11
max = 3
nb = 4
i = 0 => n = 3
i = 1 => n = 3
i = 2 => n = 3
i = 3 => n = 2
The question is not very clear. Perhaps you're looking for something like this:
for (i=0;i < nb;++i)
{
n = i < nb - 1 ? max : (na - 1) % max + 1;
}
You don't need to calculate nb. This is one way you could do it (C#):
int na = 11;
int max = 4;
for (int i = 0, x = 0; x < na; i++, x += max)
{
int n = Math.Min(max, na - x);
Console.WriteLine("i = {0}, n = {1}", i, n);
}
Output:
i = 0, n = 4
i = 1, n = 4
i = 2, n = 3
Just to add more confusion to the thread:
If only you print max in the first two cases, then you could do something like: (not in any particular language)
//for 0
printf("i = %d, n = %d\n",i,max)
//for 1
printf("i = %d, n = %d\n",i,max)
//for the rest
for (i = 2; i<nb;i++) {
printf("i = %d, n = %d\n",i,na - (i * max));
}
You can avoid the operator doing two for loops
for (i = 0; (i + 1) * max) > na AND i < nb;i++) {
printf("i = %d, n = %d\n",i,0);
}
for (; i<nb;i++) {
printf("i = %d, n = %d\n",i,na - (i * max));
}