a little php challenge

Yesterday, I was helping to tutor a temp worker in PHP. As a challenge, I gave him the task of starting with this string:

$str='0011110001000010101001011000000110100101100110010100001000111100';

… and using that to generate this table:

               
               
               
               
               
               
               
               

I might have chosen a difficult one, though, as he gave up after a while. I’ve thought of several ways of doing it – here’s the one I explained to him:

<?php
$str='0011110001000010101001011000000110100101100110010100001000111100';

$rows=str_split($str,8);
foreach($rows as $k=>$v){
    $cells=str_split($v,1);
    foreach($cells as $k2=>$v2)$cells[$k2]='<td style="background:#'.($v2=='0'?'fff':'000').'">&nbsp;</td>';
    $rows[$k]='<tr>'.join('',$cells).'</tr>';
}
echo '<table>'.join('',$rows).'</table>';
?>

I was thinking about it in off-moments throughout the day – what is the shortest piece of code which will produce the same table?

Here’s another variant I wrote this morning:

<?php
$str='0011110001000010101001011000000110100101100110010100001000111100';

echo '<table><tr>'.join('</tr><tr>',str_split(preg_replace('/([f0])/','<td style="background:#\\1\\1\\1">&nbsp;</td>',strtr($str,'01','f0')),312)).'</tr></table>';
?>

That’s 244 characters in length. Keeping the first three lines intact, can you improve on this?

7 Comments.

  1. hmm.. an interesting challenge.

    $str=’0011110001000010101001011000000110100101100110010100001000111100′;

    /*Attempt 1*/
    echo””;for($i=0;$iĀ “;if(($i+1)%8==0)echo””;}echo””;

    /*Attempt 2*/
    $a=””;for($i=0;$iĀ “.((($i+1)%8==0)?””:”);}echo”$a”;
    /* Attempt 3*/
    echo””;for($i=0;$iĀ “.((($i+1)%8==0)?””:”);}echo””;

    /*Your variant */
    echo ”.join(”,str_split(preg_replace(‘/([f0])/’,’ ‘,strtr($str,’01’,’f0′)),312)).”;

    /*Now.. Same visual presentation.. Attempt 4*/
    echo””;for($i=0;$i”;}echo””;
    /* Attempt 5*/
    for($i=0;$i”;}

    /*
    Can probably use regular expressions and the non-breaking space and Block character to shorten it a bit furthur.. But its not a table like orignally asked for..
    */

  2. Great šŸ™‚ Cant post it here..
    hmm.. an interesting challenge.
    http://dd32.hacked.in/files/challenge.php

    Final 2 variants use unicode instead of a table to achieve the presentation, The first 3 are just differnet variants that may work.

  3. Dang… mine uses 268 characters (when compressed to a oneliner) and outputs lousy HTML šŸ™

    Here’s the “expanded” version for “easy” readability…

    ‘.(($x+1)%8==0?”:”);
    return ++$x;
    }
    echo’.c1{background:#000}’;
    foreach (str_split($str)as$s) {
    $i=f($s,$i);
    }
    ?>

  4. Oh… managed to snip off 10 characters šŸ™‚

    function f($c,$x){
    echo”.($x%8==0?”:”);
    }
    echo’.c1{background:#000}’;
    foreach (str_split($str)as$s) {
    f($s,++$i);
    }

  5. Let’s try that one again…

    function f($c,$x){
    echo'<td class=c’.(($c==’1′)*1).’>’.($x%8==0?'<tr>’:”);
    }
    echo'<style>.c1{background:#000}</style><table><tr>’;
    foreach (str_split($str)as$s) {
    f($s,++$i);
    }

  6. And of course, I could take the first “TR” after the “TABLE” away to save four more bytes šŸ™‚

  7. And my final attempt… at glorious 229 bytes, here it is…

    <?php
    $str=’0011110001000010101001011000000110100101100110010100001000111100′;

    function f($c,$x){echo'<td’.($c==1?’ style=”background:#000″‘:”).’> ‘.($x%8==0?'<tr>’:”);}echo'<table>’;foreach(str_split($str)as$s){f($s,++$i);}?>

%d bloggers like this: