Jump to content

Clockwise table rendering


Go to solution Solved by morkofidor,

Recommended Posts

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.

Link to comment
https://forums.phpfreaks.com/topic/285330-clockwise-table-rendering/
Share on other sites

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>";
            ?>

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.

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 :)

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 by Psycho

 

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 :)

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>";

  • Solution

 

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 :happy-04:

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

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 :)

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";
?>

post-3105-0-79238000-1389645044_thumb.png

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');
This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.