It made already some months, I try to resolve the codingame "Let's Go To The Cinema" of the CodinGame platform, a problem of mid-level difficulty, but I can't still figure out the solution around.
The codingame lays on three concepts of recursion, simulation and stack and consist to fill a cinema where several groups want to sit.
The statement of the problem is as it follows :
There is a cinema with maxRow * maxColumn seats (all rows having same number of seats).
n groups of people are arriving in order and trying to sit down. For each group, you get as input the numPersons number of peoples it consists of, and the row and seat their ticket is issued for. (Meaning they purchased the seats from ( row , seat ) to ( row , seat + numPersons - 1), these seats included.) The same seat might have been sold several times!
You have to simulate and output how many groups and how many persons could sit on their original appointed seat.
If a group cannot sit to its place because it is already occupied, they try to find another place using a seat finding method:
The group sits ONLY if ALL of them can sit next to each other.
They try to shift together: left by 1, right by 1, left by 2, right by 2, etc.
If unsuccessful in the row, then try 1 row towards the front, then by 1 row to back, 2 rows to front, etc.
In each row use the same seat-finding procedure (starting at the same seat position).
If they tried every possible places but still without success:
They adapt to the situation and split into two subgroups of same size (the first subgroup shall be bigger, if the size of the group was odd.).
Now the first subgroup tries to sit on the original row seat position using the same seat-finding procedure as above.
As the group size is now smaller, they might succeed this time.
If they don't succeed, they keep splitting the subgroupsize by another half, and continue trying, BEFORE the original another half subgroup gets the chance to try.
Note: Latest when the subgroup size reaches 1 person, it will always succeed to find a place.
After the whole original group got seated, the next group arrives, and so on.
You have to output two numbers:
groupSuccess is the number of groups, who could sit instantly in their original places. (If a split subgroup can sit later on the original place, that does not count towards this counter.)
personSuccess is the number of individuals, who could find a place on their original group ticket. A person shall be counted as successful, no matter after how many iterations (s)he found the place, if and only if the seat is any of the places appointed to the original group: ( row , seat ) to ( row , seat + numPersons - 1).
In first place, I created a "checkPlaces" function which checks if places at row parameter and comprised between column and column + numPersons - 1 are occupied :
public static boolean checkPlaces(int numPersons, int row, int column) {
for(int i = column; i < column + numPersons - 1; i++) {
if(cinema[row][i] == 1) {
return false;
}
}
return true;
}
I create another function "analyzeRow" where I check in calling "checkPlaces" function several times if original reserved places are available and if not I check consecutively
in shifting from 1, 2, ..., n column to the left and to right if the group can sit elsewhere on the row.
public static boolean analyzeRow(int numPersons, int row, int column, int maxRow, int maxColumn) {
if(checkPlaces(numPersons, row, column)) {
for(int i = column; i < column + numPersons - 1; i++) {
cinema[row][i] = 1;
}
return true;
}
else {
for(int j = 1; j < maxColumn; j++) {
if(j < column) {
int col1 = shiftLeftColumn(column, j);
if(checkPlaces(numPersons, row, col1)) {
for(int i = column; i < column + numPersons - 1; i++) {
cinema[row][i] = 1;
}
return true;
}
}
if(j < maxColumn - column) {
int col2 = shiftRightColumn(column, j);
if(checkPlaces(numPersons, row, col2)) {
for(int i = column; i < column + numPersons - 1; i++) {
cinema[row][i] = 1;
}
return true;
}
}
}
}
return false;
}
A third function "checkGrid" has for purpose to check the entire cinema in changing row
when analyzeRow sends false on a particular row in shifting from 1, 2, ..., n to front and to back until borders of the cinema are reached out.
public static boolean checkGrid(int numPersons, int row, int column, int maxRow, int maxColumn) {
if(!analyzeRow(numPersons, row, column, maxRow, maxColumn)) {
for(int l = 1; l < maxRow; l++) {
if(l < maxRow - row) {
int row1 = moveFrontRow(row, l);
analyzeRow(numPersons, row1, column, maxRow, maxColumn);
}
if(l < row) {
int row2 = moveBackRow(row, l);
analyzeRow(numPersons, row2, column, maxRow, maxColumn);
}
}
}
return true;
}
I also created several functions to shift column or row to left, right, front, back :
public static int shiftLeftColumn(int column, int j) {
int columnReturn = column - j;
return columnReturn;
}
public static int shiftRightColumn(int column, int j) {
int columnReturn = column + j;
return columnReturn;
}
public static int moveFrontRow(int row, int i) {
int rowReturn = row + i;
return rowReturn;
}
public static int moveBackRow(int row, int i) {
int rowReturn = row - i;
return rowReturn;
}
However, I have the feeling to have understood the idea, however I have difficulties to bring my code until the end and I'm not totally sure how I must do to take account the "split groups" part of the exercize, as the statement advice to use the "stack" concept, but I would rather use a binary tree that I create at the beginning of my main function with a static function :
TreeNode root = TreeNode.buildTree(numPersons);
Given that the exercize ask to split the group of people in two parts and then examine a first group and divide again to examine the two split groups issued of this first group,
before to examine the second.
It seems like leafs of a tree.
public class TreeNode {
int value;
TreeNode left;
TreeNode right;
public TreeNode(int value) {
this.value = value;
}
public TreeNode(int value, TreeNode left, TreeNode right) {
this.value = value;
this.left = left;
this.right = right;
}
public static TreeNode buildTree(int numPersons) {
while(numPersons > 1) {
if(numPersons % 2 == 0) {
TreeNode A = new TreeNode(numPersons, buildTree(numPersons/2), buildTree(numPersons/2));
return A;
}
else {
TreeNode B = new TreeNode(numPersons, buildTree((numPersons / 2) + 1), buildTree(numPersons / 2));
return B;
}
}
return new TreeNode(numPersons, null, null);
}
}
It made a long time I think on this, but I can't find how to finish and I would like to know if the way of thinking is the good or if I'm totally aside of the plate concerning the resolution of this exercize and I failed to see some algorithmic subtlety.
Thanks in advance to who could guide me.
I have the following code:
for (int i = 1; i <= columnArr.Length; i++)
{
sheet.Column(i).AutoFit();
totalWidth += sheet.Column(i).Width;
}
if (image != null)
{
int percent = (int)(totalWidth* 100 / image.Image.Width);
sheet.Row(1).Height = percent * image.Image.Height / 100;
image.SetSize(percent);
}
I want this code should make image (of type ExcelPicture) be as wide as the columns in the relevant part of the sheet (in my case, 3 columns); however, the image is much smaller. However, the row does end up the correct height for the image as shown in the file. How can I fix the width of the image?
You could use the other SetSize method.
SetSize(width, height)
Getting the details right was tricky but this worked for me:
report.Sheet.Column(columnIndex).Width = 10;
report.Sheet.Row(rowIndex).Height = 50;
picture.To.Column = picture.From.Column = columnIndex - 1;
picture.To.Row = picture.From.Row = rowIndex - 1;
picture.SetSize(70, 66);
Note that the column and row index is off by one.
Need to animate a sorting algorithm, with source code line by line visualization.
INTRO:
For the begining, there is a FORM (see it in the picture attached). On top of that form is displayed a dinamicaly created array of Edit components, containing the array to sort.
A little below, on the right is placed a Memo component, containing the algorithm. At the left of each line of that algorithm, dinamicaly is placed a Label, that indicates the line number in algorithm.
The idea is to highlight line by colouring that label, where is the execution at the moment. Sorting starts when "Start" button is clicked. The action for it is following:
int n = 10;
bool swapped = true; hl(1);
int j = 0; hl(2);
int tmp; hl(3);
while (swapped) { hl(4);
swapped = false; hl(5);
j++; hl(6);
for (int i = 0; i < n - j; i++) { hl(7);
if (arr[i] > arr[i + 1]) { hl(8);
tmp = arr[i]; hl(9);
arr[i] = arr[i + 1]; hl(10);
arr[i + 1] = tmp; hl(11);
swapped = true; hl(12);
} hl(13);
} hl(14);
} hl(15);
The hl function must colour labels and pause execution by using Sleep() function
void TForm2::hl(int l)
{
for (int i = 0; i < 24; i++) {
Form2->lines[i]->Font->Color = clGray;
}
Form2->lines[l-1]->Font->Color = clRed;
Sleep(300);
}
PROBLEM:
Code execution is pausing (sleep function works properly), but the labels are still gray, with no visible changes, except the last one, when event finishes. The 15th line is red.
QUESTION:
Can anybody tell me, where I'm wrong, and how to do it right?
http://i.stack.imgur.com/crGyC.jpg
You need to allow the paint message to be processed in order to visually update the display. You can do that with either the Refresh or Update procedures:
Form2->Lines[l-1]->Font->Color = clGray;
Form2->Update(); // or Form2->Refresh();
So I have to do some operations on part of an image. The operation is not relevant (i dont change this code at all), but the way i create the pointer changes the results i get. I dont understand why that happens.
Why does this code gets the result I want:
for(int row = 0; row < 70; ++row) {
for(int col = 48; col < 208; ++col) {
uchar* p = c.ptr(row+col);
*p = (1-circuloBinario.at<unsigned char>(row,col-48))*(*p) + circuloBinario.at<unsigned char>(row,col-48)*limite;
}
}
And this one doesnt?
for(int row = 0; row < 70; ++row) {
uchar* p = c.ptr(row+48);
for(int col = 48; col < 208; ++col) {
*p = (1-circuloBinario.at<unsigned char>(row,col-48))*(*p) + circuloBinario.at<unsigned char>(row,col-48)*limite;
p++;
}
}
By the way, I dont get any errors with the second code, the problem is that the result I get is not what I expect (it starts modifying the image from a row bigger than 0 and starts from column 0 instead of 48).
Thanks.
Mat::ptr returns a pointer to the specified matrix row.
See the documentation here: http://docs.opencv.org/modules/core/doc/basic_structures.html#mat-ptr
So neither c.ptr(row+col) nor c.ptr(row+48) make sense because you should only be passing a row index to the ptr function.
The way you use Mat::pt is apparently incorrect, as mentioned by M456.
If you want to modify the value of some elements of the matrix, why don't you use the following syntax?
c.at<element_type>(row, col) = new_value;
I have multiple rows in my excel, where contents are small except the top row.
Just in order to insert a big title in the top row, i would not like the width of subsequent rows' to be impacted.
Is there a way i can span the content in the top row over multiple columns and without affecting the width of subsequent rows.
Yes, by using the WritableSheet.mergeCells method.
For example:
WritableWorkbook w = Workbook.createWorkbook(outputStream);
WritableSheet s = w.createSheet("MySheet", 0);
int row = 0;
WritableCell titleCell = new Label(0, row, "Hello World");
s.addCell(titleCell);
s.mergeCells(0, row, 13, row);
This has the effect of making the first row be 13 cells wide, and will not effect the cell widths of the subsequent rows. Note, this will allow you to merge rows but this will not work. The correct way to change the row height is by:
/* Row heights are in 20ths of a point */
int fontPointSize = 16;
int rowHeight = (int) ((1.5d * fontPointSize) * 20);
s.setRowView(row, rowHeight, false);
This is possible, play around with this. Hope it will help you.
int col1 = 0;
int col2 = 2;
int row1 = 0;
int row2 = 0;
WritableWorkbook workbook = Workbook.createWorkbook(outputStream);
WritableSheet sheet = workbook.createSheet("MySheet", 0);
sheet.mergeCells(col1,row1,col2,row2);
//This makes the cell at row1 and col1 span the next two cells
//Write content at the marge cell
sheet.addCell(new Label(col1,row1,"Content here"));
References:
first reference and socond reference