merge adjacent html table cells based on class or value - php

I have a html table with a variable number of cells.
For the sake of this example i will say 20x20 (although it's quite bigger).
This is generated via php and the dataset to populate the table has been pulled from mysql.
Each one of these cells has a numeric value, and it needs to specifically be placed where is is. So if cell A(10,15) has a value of 100, that 100 needs to specifically be on 10,15-
And while the table is being generated i have no way to analyze the positioning.
Now, many of these cells, have other adjacent cells with the same value. Either horizontally or vertically.
What i need to do is merge adjacent cells of a this table that have the same value.
This could be horizontal, vertical, or both, but still keeping it a rectangle- Nothing too funky.
For example if i have
0 1 1 1 0
2 2 5 0 4
5 5 5 1 4
i need to modify the colspan and/or rowspan based on value-
To be noted is that upon generation i can actually define classes or ids for each one
of these cells. Also during generation i can identify wether there will be more than one in a series in a row, but i have no way of knowing wether there will be one on the row below.
ps: i did do a bit a research and found this thread.
Complex table merging javascript & jquery algorithm
modified the jsfiddle example to affect both colspan and rowspan of the cell but it seems to flip out when it needs to merge more that two cells-
What could be a suggested approach on the matter?
Thank you in advance

Do it in two passes (O(n2)), first traverse your array in the width and detect the number of adjacent cells (and set zero for a cell after the same one) :
0(1) 1(3) 1(0) 1(0) 0(1)
2(2) 2(0) 5(1) 0(1) 4(1)
5(3) 5(0) 5(0) 1(1) 4(1)
Then, traverse it vertically, and find cells where both numbers are the same (and the count > 0), you'll get :
0(1,1) 1(3,1) 1(0,0) 1(0,0) 0(1,1)
2(2,1) 2(0,0) 5(1,0) 0(1,1) 4(1,2)
5(3,1) 5(0,0) 5(0,0) 1(1,1) 4(1,0)
Now, the first number of the pair is the colspan, the second is the rowspan. If one of the number is 0, don't output it.
0 1---- 0
2-- 5 0 4
5---- 1 |

Related

Excel - Getting the 2nd or nth matched string from your corresponding data

With my previous posts
1. PHPSpreadsheet generates an error "Wrong number of arguments for INDEX() function: 5 given, between 1 and 4 expected"
2. Excel - Getting the Top 5 data of a column and their matching title but produces duplicates
I have found out that the PHPSpreadsheet library for PHP is yet to allow the usage of the AGGREGATE() and complicated formulas/functions but I'm in dire need of their functionalities
Going back, I have 2 columns in my Excel (produced by my web applications made from CodeIgniter and Laravel)
The problem is, the Article Count column (on the right) contains 2 values of 54 which is supposed to belong to 2 different Publications (on the left) but with the use of the formula =INDEX(E$4:E$38,MATCH(M4,J$4:J$38,0)) it just fetches the 1st matched Publication.
The output should look like this:
The original Table:
My question is, what would be the right function or code in Excel so I could retrieve the SECOND Publication of my matched data?
I'm aiming to target those Publications that has the Article Count of 54, but I want to aim the SECOND ONE which is the letter D WITHOUT using the Aggregate() function of Excel
Here are my used codes
1) =LARGE(J4:J38,1) - J4:J38 is my range of raw data, I am using this to get the 5 highest numbers in descending order
2) =INDEX(E4:E38,MATCH(M4,J4:J38,0)) - I'm using this to retrieve the Publication Names that matched the Article Count
After communicating in chat, we got this correct formula:
=INDEX(E$2:E$38,IF(M4=M3,MATCH(L3,E$2:E$38,0),0)+MATCH(M4,OFFSET(J$2,IF(M4=M3,MATCH(L3,E$2:E$38,0),0),0,COUNT(J$2:J$38)-IF(M4=M3,MATCH(L3,E$2:E$38,0),0),1),0))
How this works:
This IF(M4=M3,MATCH(L3,E$2:E$38,0),0) returns the position of the previous row's publication title in the titles array (E), in case the current publication count is the same with the previous one. Let's call this number X. Instead of using J2:J38 for the results, we use J(2+X):J38. This trick is done by using offset to cut off the previous section, already used by the previous row. This way, on repeating publication counts the already mentioned titles get ignored.
You need to use AGGREGATE's SMALL sub-function to return the smallest matching row number and adjust the k argument to accommodate duplicate rankings.
'in M4
=LARGE(J$4:J$38, ROW(1:1))
'in L4
=INDEX(I:I, AGGREGATE(15, 7, ROW($4:$38)/(J$4:J$38=M4), COUNTIF(M$4:M4, M4)))
enter image description here

Break table if height is greater than value

I'm working on a script that generates a PHP table containing some values from a MySQL database. The script will be displayed on a TV, so I need to break it if its height is greater than 1280 (I've got this value by completing it with values 'till it fits perfect, then I've used jQuery alert to display its height) and I will use jquery.cycle.all plugin to create a slideshow from the tables.
My solution was to use a PHP variable and increment it on each generated then if I have let's say 13 rows, it echoes </table><table>, but the cells must have an exact width so it may add a new line of text (if I have a longer text) on a cell and the table will have more than 1280px height.
Does anybody have any idea about how I can solve this?
Possible solutions:
Use the css overflow: hidden to prevent content going to the next line and just hide it
Use javascript to iterate over each row, calculate the height of the row and remove rows if the total height exceeds 1280px.
Use PHP to calculate the length of the text in actual px and how many rows would be used, but that is quite complex.

Searching for matrix way finding algorithm

i am developing a board game in php and now i have problems in writing an algorithm...
the game board is a multidimensional array ($board[10][10]) to define rows and columns of the board matrix or vector...
now i have to loop through the complete board but with a dynamic start point. for example the user selects cell [5,6] this is the start point for the loop. goal is to find all available board cells around the selected cell to find the target cells for a move method. i think i need a performant and efficient way to do this. does anyone know an algorithm to loop through a matrix/vector, only ones every field to find the available and used cells?
extra rule...
in the picture appended is a blue field selected (is a little bigger than the other). the available fields are only on the right side. the left side are available but not reachable from the current selected position... i think this is a extra information which makes the algorithm a little bit complicated....
big thx so far!
kind regards
not completely sure that I got the requirements right, so let me restate them:
You want an efficient algorithm to loop through all elements of an nxn matrix with n approximately 10, which starts at a given element (i,j) and is ordered by distance from (i,j)!?
I'd loop through a distance variable d from 0 to n/2
then for each value of d loop for l through -(2*d) to +(2*d)-1
pick the the cells (i+d, j+l), if i>=0 also pick (i+l,j-d),(i+l, j+d)
for each cell you have to apply a modulo n, to map negativ indexes back to the matrix.
This considers the matrix basically a torus, glueing upper and lower edge as well as left and right edge together.
If you don't like that you can let run d up to n and instead of a modulo operation just ignore values outside the matrix.
These aproaches give you the fields directly in the correct order. For small fields I do doubt any kind of optimization on this level has much of an effect in most situations, Nicholas approach might be just as good.
Update
I slightly modified the cells to pick in order to honor the rule 'only consider fields that are right from the current column or on the same column'
If your map is only 10x10, I'd loop through from [0][0], collecting all the possible spaces for the player to move, then grade the spaces by distance to current player position. N is small, so the fact that the algorithm has O(N^2) shouldn't affect your performance much.
Maybe someone with more background in algorithms has something up their sleeve.

Lottery number analysis

I'm trying to perform some basic analysis on Lotto results :)
I have a database that looks something like:
id|no|day|dd|mmm|yyyy|n1|n2|n3|n4|n5|n6|bb|jackpot|wins|machine|set
--------------------------------------------------------------------
1 |22|mon|22|aug|1999|01|05|11|29|38|39|04|2003202| 1 | Topaz | 3
2 |23|tue|24|aug|1999|01|06|16|21|25|39|03|2003202| 2 | Pearl | 1
That's just an example. So, n1 to n6 are standard balls in the lottery and bb stands for the bonus ball.
I want to write a PHP/SQL code that will display just one random sequence of numbers that have yet to come out. However, If the numbers 01, 04, 05, 11, 29, 38 and 39 have come out, I don't want the code to print out them numbers but just in a different order, as in theory them set of numbers are already winning numbers.
I just can't get my head around the logic of this. I'd appreciate any help.
Thanks in advance
Assuming that the balls are stored in ascending order in your database like the examples you've given, you could just generate a random sequence of 6 numbers, sort them and then generate 1 random bonus number. Once you've done that it would just be a matter of doing a simple SQL query into your database and seeing if it comes back with a result:
$nums=...//generate your 6 numbers plus bonus number here
sort($nums);
$mysqli=new mysqli('...','...','...','...');
$stmt=$mysqli->prepare("SELECT * FROM table
WHERE n1=? AND n2=? AND n3=? AND n4=? AND n5=? AND n6=? AND bb=?");
$stmt->bind_param('iiiiiii', $nums[0], $nums[1], $nums[2], $nums[3], $nums[4], $nums[5], $nums[6]);
$stmt->execute();
$stmt->store_result();
if($stmt->num_rows==0)
//your numbers have not been drawn before - return them
else
//otherwise loop round and try again
As long as both list of numbers (but not the bonus ball) are sorted you won't have any problems with a different ordering of an already drawn set of numbers.
This will become less efficient as your database of previous draws gets fuller, but I don't think you'll have to worry about that for a few decades. :-)
What about sorting each already drawn result (each row) in some order, ascending maybe, then sort the set of already drawn results (all rows)? Then you will have a easy to look up in list in which you can see what is left to be drawn.
Say for example you want a never drawn set before? You would just have to loop through the list until you spot a "hole", which would be a never before drawn set. If you would like to optimise further you could store at what index you last found a "hole" as well. Then you would never need to loop through the same part of the list twice, and you could even abandon "completed" parts of the list to save disk space, or if you would like the new number you come up with to seam random you could start at a random offset in the list.
To do this effectively you should make an extra column to store the pre-sorted set. For example if you have (5, 3, 6, 4, 1, 2) that column could contain 010203040506. Add in enough zeros so that the numbers occur on a fixed offset basis.

Space a series of values so they don't overlap

There have been a couple of questions very close to this topic, but none really helped me.
Ive been programming a graphing library, and I need an algorithm to vertically place labels without overlapping. I've been stuck on this for a couple of days now, and managed to distil it to the most basic function:
If given a series of label positions along the Y axis, say, 1 1 2 3 5 6 9, and an upper and a lower limits 10 and 0 respectively, I need a way to space out the values to output 1 2 3 4 5 6 9
333467 should be 234567 weighted to be close to the original coordinates.
This should also work backwards, if values are bunched up at the upper end of the scale, they should be spread as much as possible (before overflowing)
I'm not looking for a definitive answer, but I'd like some help on how to approach this problem. Im completely stuck.
Last train of thought was to scan all labels for possible collisions and position them as one big block, aligning to the centre of all the Y coordinates. But this will not work if there are multiple sets of collisions.
EDIT: To put this algorithm in a bigger context, have a look at these two google chart API pie charts:
1) Top stacked labels
2) Bottom Stacked Labels
The labels are almost springy, they avoid collisions by joining together and moving their entire mass to the center of their mass.
Make the set of labels unique by inserting into an ordered set. Divide the difference between the y-axis upper and lower bound by the number of elements in the set. This is your spacing increment. Iterate over the set in order and position one label every spacing increment.
You didn't say anything about needing to preserve a scale...
Well, After some thought and advice from other sources i came up with a solution:
Pseudocode:
foreach labels as label
if label->collidesWith(labels->lowerLimit)
label->moveAwayFrom(labels->lowerLimit)
if label->collidesWith(labels->upperLimit)
label->moveAwayFrom(labels->upperLimit)
if label->collidesWith(label->previous)
label->moveAwayFrom(label->previous)
label->previous->moveAwayFrom(label)
if label->collidesWith(label->next)
label->moveAwayFrom(label->next)
label->next->moveAwayFrom(label)
endforeach
MoveAwayFrom moves 1 pixel at a time. When this function is run multiple times it rejiggles the labels until none of them collide. (in reality im calling this loop 100 times, havent figured out a way to do it more inteligently)

Categories