morkofidor Posted January 13, 2014 Share Posted January 13, 2014 Hello, everyone. Can anybody help me, i'm trying to populate an HTML table with numbers in clockwise order, starting from last cell in the table then spiralling to the center. User inputs number of rows and columns, table is generated, but i'm lost at populating cells with numbers in clockwise order. Here's the code so far: <html> <head> <style> table{ border-collapse: collapse; } table, td{ border: 1px solid black; } td{ width: 50px; } tr{ height:50px; } </style> </head> <body> <div id="input"> <form action="table.php" method="post"> Input number of rows :<br> <input type="text" name="row"><br> Input number of columns:<br> <input type="text" name="column"><br> <input type="submit" name="submit" value="Ok"> </form> </div> <div id="output"> <?php $i = 0; $j = 0; echo "<table>"; for ($col = 0; $col < $_POST['column']; $col++) { echo "<tr>"; for ($row = 0; $row < $_POST['row']; $row++) { echo "<td>"; $i++; $array[$j] = $i; echo $array[$j]; $j++; echo "</td>"; } echo "</tr>"; } echo "</table>"; ?> </div> </body> </html> Array is there because i thought i could populate the table in desired order from array. Any suggestions, directions or links will be appreciated. Please help. Quote Link to comment Share on other sites More sharing options...
morkofidor Posted January 13, 2014 Author Share Posted January 13, 2014 Hello, everyone. Can anybody help me, i'm trying to populate an HTML table with numbers in clockwise order, starting from last cell in the table then spiralling to the center. User inputs number of rows and columns, table is generated, but i'm lost at populating cells with numbers in clockwise order. Here's the code so far: <html> <head> <style> table{ border-collapse: collapse; } table, td{ border: 1px solid black; } td{ width: 50px; } tr{ height:50px; } </style> </head> <body> <div id="input"> <form action="table.php" method="post"> Input number of rows :<br> <input type="text" name="row"><br> Input number of columns:<br> <input type="text" name="column"><br> <input type="submit" name="submit" value="Ok"> </form> </div> <div id="output"> <?php $i = 0; $j = 0; echo "<table>"; for ($col = 0; $col < $_POST['column']; $col++) { echo "<tr>"; for ($row = 0; $row < $_POST['row']; $row++) { echo "<td>"; $i++; $array[$j] = $i; echo $array[$j]; $j++; echo "</td>"; } echo "</tr>"; } echo "</table>"; ?> </div> </body> </html> Array is there because i thought i could populate the table in desired order from array. Any suggestions, directions or links will be appreciated. Please help. I messed up table generating part: First i should generate row, then columns, naturaly. <?php $i = 0; $j = 0; echo "<table>"; for ($row = 0; $row < $_POST['row']; $row++) { echo "<tr>"; for ($col = 0; $col < $_POST['column']; $col++) { echo "<td>"; $i++; $array[$j] = $i; echo $array[$j]; $j++; echo "</td>"; } echo "</tr>"; } echo "</table>"; ?> Quote Link to comment Share on other sites More sharing options...
Psycho Posted January 13, 2014 Share Posted January 13, 2014 Interesting problem. I have to believe there is a mathematical formula that could be used, but looking at some scenarios I'm not able to see one. So, I would create a process to iterate through the table cells in a clockwise process. I'll see if I can write something up. Quote Link to comment Share on other sites More sharing options...
morkofidor Posted January 13, 2014 Author Share Posted January 13, 2014 Interesting problem. I have to believe there is a mathematical formula that could be used, but looking at some scenarios I'm not able to see one. So, I would create a process to iterate through the table cells in a clockwise process. I'll see if I can write something up. Looking forward to it Quote Link to comment Share on other sites More sharing options...
Psycho Posted January 13, 2014 Share Posted January 13, 2014 (edited) Well, I am sure this can be improved upon, but it works (at least in the tests I've run): <?php $rowTotal = max(intval($_POST['row']), 1); $colTotal = max(intval($_POST['column']), 1); //Set start position $row = 1; $col = 1; //Set inital directions (Left-to-right) $rowDirection = 0; $colDirection = 1; //Set initial 'edge' values $rowMin = 1; $rowMax = $rowTotal; $colMin = 1; $colMax = $colTotal; //Set initial number & stop number $count = 1; $stopCount = $rowTotal * $colTotal; //Create array to hold results $outputAry = array(); //Run process to calculate results while($count <= $stopCount) { //Set count in current position & increment count $outputAry[$row][$col] = $count; $count++; //Move positon based upon current directions $row = $row + $rowDirection; $col = $col + $colDirection; //Check if we've hit a Min/Max value for row or column //and change the direction and adjust Min/Max value //----------------------------------------------------- //Moving left-to-right - Check if we've reach far right if($colDirection == 1 && $col == $colMax) { $rowDirection = 1; //Change movement to go $colDirection = 0; //Top-to-bottom $rowMin++; //Move top edge down 1 unit } //Moving top-to-bottom - Check if we've reached bottom if($rowDirection == 1 && $row == $rowMax) { $rowDirection = 0; //Change movement to go $colDirection = -1; //Right-to-left $colMax--; //Move right edge in 1 unit } //Moving right-to-left - Check if we've reached far left if($colDirection == -1 && $col == $colMin) { $rowDirection = -1; //Change movement to go $colDirection = 0; //Botton-to-top $rowMax--; //Move bottom edge up 1 unit } //Moving bottom-to-top - Check if we've reached top if($rowDirection == -1 && $row == $rowMin) { $rowDirection = 0; //Change movement to go $colDirection = 1; //Left-to-right $colMin++; //Move left edge out 1 unit } } //Sort the results by row/column array_walk($outputAry, 'ksort'); //Create the output $table = "<table border='1'>\n"; foreach($outputAry as $row) { $table .= "<tr>\n"; foreach($row as $value) { $table .= "<td>{$value}</td>\n"; } $table .= "</tr>\n"; } $table .= "</table>\n"; echo $table; ?> Edited January 13, 2014 by Psycho Quote Link to comment Share on other sites More sharing options...
morkofidor Posted January 13, 2014 Author Share Posted January 13, 2014 Well, I am sure this can be improved upon, but it works (at least in the tests I've run): <?php $rowTotal = max(intval($_POST['row']), 1); $colTotal = max(intval($_POST['column']), 1); //Set start position $row = 1; $col = 1; //Set inital directions (Left-to-right) $rowDirection = 0; $colDirection = 1; //Set initial 'edge' values $rowMin = 1; $rowMax = $rowTotal; $colMin = 1; $colMax = $colTotal; //Set initial number & stop number $count = 1; $stopCount = $rowTotal * $colTotal; //Create array to hold results $outputAry = array(); //Run process to calculate results while($count <= $stopCount) { //Set count in current position & increment count $outputAry[$row][$col] = $count; $count++; //Move positon based upon current directions $row = $row + $rowDirection; $col = $col + $colDirection; //Check if we've hit a Min/Max value for row or column //and change the direction and adjust Min/Max value //----------------------------------------------------- //Moving left-to-right - Check if we've reach far right if($colDirection == 1 && $col == $colMax) { $rowDirection = 1; //Change movement to go $colDirection = 0; //Top-to-bottom $rowMin++; //Move top edge down 1 unit } //Moving top-to-bottom - Check if we've reached bottom if($rowDirection == 1 && $row == $rowMax) { $rowDirection = 0; //Change movement to go $colDirection = -1; //Right-to-left $colMax--; //Move right edge in 1 unit } //Moving right-to-left - Check if we've reached far left if($colDirection == -1 && $col == $colMin) { $rowDirection = -1; //Change movement to go $colDirection = 0; //Botton-to-top $rowMax--; //Move bottom edge up 1 unit } //Moving bottom-to-top - Check if we've reached top if($rowDirection == -1 && $row == $rowMin) { $rowDirection = 0; //Change movement to go $colDirection = 1; //Left-to-right $colMin++; //Move left edge out 1 unit } } //Sort the results by row/column array_walk($outputAry, 'ksort'); //Create the output $table = "<table border='1'>\n"; foreach($outputAry as $row) { $table .= "<tr>\n"; foreach($row as $value) { $table .= "<td>{$value}</td>\n"; } $table .= "</tr>\n"; } $table .= "</table>\n"; echo $table; ?> Thank you, i'm going to try it out right away Quote Link to comment Share on other sites More sharing options...
ginerjm Posted January 13, 2014 Share Posted January 13, 2014 (edited) Is this what you are looking for? Showing table for rows=4 cols=4 10 9 8 7 11 2 1 6 12 3 4 5 13 14 15 16 Edited January 13, 2014 by ginerjm Quote Link to comment Share on other sites More sharing options...
ginerjm Posted January 13, 2014 Share Posted January 13, 2014 Here's my code - similar to psycho's, but different. <? /* spiral.php */ // $num_rows = 5; // user provided values $num_cols = 4; //******************************** $elem_val = $num_rows * $num_cols; // number to begin with // $edges = array('b','l','t','r'); $min_row = 0; $max_row = $num_rows -1; $min_col = 0; $max_col = $num_cols -1; // $e = 0; $ar = array(); $building = true; while ($building) { $edge = $edges[$e]; switch ($edge) { case 'b': { // do a bottom of the grid row $r = $max_row; for ($c = $max_col;$c >= $min_col; $c--) { $key = "R".$r."C".$c; $ar[$key] = $elem_val; $elem_val--; } $max_row--; break; } case 'l': { // do a left side of the grid $c = $min_col; for ($r = $max_row;$r >= $min_row; $r--) { $key = "R".$r."C".$c; $ar[$key] = $elem_val; $elem_val--; } $min_col++; break; } case 't': { // do a top row of the grid $r = $min_row; for ($c = $min_col;$c <= $max_col; $c++) { $key = "R".$r."C".$c; $ar[$key] = $elem_val; $elem_val--; } $min_row++; break; } case 'r': { // do the right side of the grid $c = $max_col; for ($r = $min_row;$r <= $max_row; $r++) { $key = "R".$r."C".$c; $ar[$key] = $elem_val; $elem_val--; } $max_col--; break; } } if ($elem_val <=0) $building = false; $e++; if ($e > 3) $e = 0; } echo "Showing results table for rows=$num_rows cols=$num_cols<br><br>"; $num_rows--; $num_cols--; echo "<table border=1 style='border-collapse:collapse;'>"; echo "<col width=40px><col width=40px><col width=40px><col width=40px>"; for ($r = 0;$r<=$num_rows;$r++) { echo "<tr>"; for ($c=0;$c<=$num_cols;$c++) { $key = "R".$r."C".$c; echo "<td>$ar[$key]</td>"; } echo "</tr>"; } echo "</table>"; Quote Link to comment Share on other sites More sharing options...
Solution morkofidor Posted January 13, 2014 Author Solution Share Posted January 13, 2014 Is this what you are looking for? Showing table for rows=4 cols=4 10 9 8 7 11 2 1 6 12 3 4 5 13 14 15 16 Not quite, but it's helpful, thank you I'm trying to get first number on last index, spiraling to the middle. 5 6 7 4 9 8 3 2 1 I need to study the code you provided, i'll get there. Thanks again Quote Link to comment Share on other sites More sharing options...
ginerjm Posted January 13, 2014 Share Posted January 13, 2014 minor change in my code then. Simply change the starting value of $elem_val and instead of decrementing it, increment instead. Oh - and change the value test at the end of my while to detect if it exceeds your value instead of checking for less than 0 Quote Link to comment Share on other sites More sharing options...
morkofidor Posted January 13, 2014 Author Share Posted January 13, 2014 minor change in my code then. Simply change the starting value of $elem_val and instead of decrementing it, increment instead. Oh - and change the value test at the end of my while to detect if it exceeds your value instead of checking for less than 0 Thanks, i got it, it's quite clear after you take a look at it. At first i thought you were beggining in the center, then i saw you were starting from max value then decrementing it. I made your code work the way i want it to. Now i'll try Psycho's code. Thanks guys Quote Link to comment Share on other sites More sharing options...
Barand Posted January 13, 2014 Share Posted January 13, 2014 here's my 0.02 worth <?php $rows = 5; $cols = 5; $bounds = array(0, 0, $cols-1, $rows-1); $dx = -1; $dy = 0; $dir = 0; $results = array_fill_keys(range(0,$rows*$cols-1),''); $x = $bounds[2]; $y = $bounds[3]; for ($i=1; $i<=$rows*$cols; $i++) { if ($i>1) { switch ($dir%4) { case 0: if ($x==$bounds[0]) { $dx = 0; $dy = -1; $bounds[3]--; $dir++; } break; case 1: if ($y==$bounds[1]) { $dx = 1; $dy = 0; $bounds[0]++; $dir++; } break; case 2: if ($x==$bounds[2]) { $dx = 0; $dy = 1; $bounds[1]++; $dir++; } break; case 3: if ($y==$bounds[3]) { $dx = -1; $dy = 0; $bounds[2]--; $dir++; } break; } $x += $dx; $y += $dy; } $pos = $y*$cols+$x; $results[$pos] = $i; } $output = array_chunk($results, $cols); echo "<table border='1'>\n"; foreach ($output as $row) { echo "<tr><td>" . join('</td><td>', $row) . "</td></tr>\n"; } echo "</table>\n"; ?> Quote Link to comment Share on other sites More sharing options...
Psycho Posted January 13, 2014 Share Posted January 13, 2014 FYI: The only modifications that should be needed to my code would be 1) the default start position and direction and 2) the parent array will need to have ksort() run on it: //Set start position $row = $rowTotal; $col = $colTotal; //Set inital directions $rowDirection = 0; $colDirection = -1; //Sort the results by row/column ksort($outputAry); array_walk($outputAry, 'ksort'); Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.