[Challenge] Conditioning

PHP programming forum. Ask questions or help people concerning PHP code. Don't understand a function? Need help implementing a class? Don't understand a class? Here is where to ask. Remember to do your homework!

Moderator: General Moderators

User avatar
McInfo
DevNet Resident
Posts: 1532
Joined: Wed Apr 01, 2009 1:31 pm

Re: [Challenge] Conditioning

Post by McInfo »

VladSun wrote:What's the importance of the N (in this case 50) period? Is it a must for your design or not?
There is no significance to the conditions I chose other than the number of conditions is greater than the number of allowed if statements. I chose the ranges I did because they seemed realistic and to make people think there might be some hidden relationship. Maybe there is, but not by design. The "pattern that I think is somewhat clever" is related to changing a variable based on a where it fits into a group of unequal conditions.

Edit: This post was recovered from search engine cache.
Last edited by McInfo on Mon Jun 14, 2010 5:30 pm, edited 1 time in total.
User avatar
McInfo
DevNet Resident
Posts: 1532
Joined: Wed Apr 01, 2009 1:31 pm

Re: [Challenge] Conditioning

Post by McInfo »

This is my solution.

Code: Select all

<?php
$x = (int) $_GET['x'];
$y = (int) $_GET['y'];
 
function act (&$x, $new, $condition) {
    if ($condition)
        $x = $new;
    return $condition;
}
 
if ( ! act($x,        0, ($y <  1)            )
&&   ! act($x, $x +  $y, ( 0 < $y && $y <  50))
&&   ! act($x, $x +  50, (49 < $y && $y < 100))
&&   ! act($x, $x + 100, (99 < $y)            )
);
 
var_dump($x, $y);
It uses the fact that multiple conditions joined by and will be evaluated in order only until one of them is false.

This challenge was inspired by my solution to the "Colour rotation" challenge.

Edit: This post was recovered from search engine cache.
Last edited by McInfo on Mon Jun 14, 2010 5:31 pm, edited 1 time in total.
User avatar
VladSun
DevNet Master
Posts: 4313
Joined: Wed Jun 27, 2007 9:44 am
Location: Sofia, Bulgaria

Re: [Challenge] Conditioning

Post by VladSun »

:) Nice one. Bravo! :)

I found it's called "short-circuit evaluation". I remember, Turbo Pascal has a special compiler flag used to enable or disable short-circuit evaluation of the expressions in an if statement, though I think it's always enabled in modern languages.

It's also widely used in bash scripting:

Code: Select all

./configure && make && make install
Thats' how every command will be executed only and if only the previous one has return 0 error code ( exit(0) ).
There are 10 types of people in this world, those who understand binary and those who don't
User avatar
McInfo
DevNet Resident
Posts: 1532
Joined: Wed Apr 01, 2009 1:31 pm

Re: [Challenge] Conditioning

Post by McInfo »

Thanks for finding that Wikipedia page. It's interesting to see how different languages handle multiple conditions.

Edit: This post was recovered from search engine cache.
Last edited by McInfo on Mon Jun 14, 2010 5:32 pm, edited 1 time in total.
User avatar
AbraCadaver
DevNet Master
Posts: 2572
Joined: Mon Feb 24, 2003 10:12 am
Location: The Republic of Texas
Contact:

Re: [Challenge] Conditioning

Post by AbraCadaver »

I vote for the prize going to VladSun for either the binary logic or the lookup table. Both sweet!
mysql_function(): WARNING: This extension is deprecated as of PHP 5.5.0, and will be removed in the future. Instead, the MySQLi or PDO_MySQLextension should be used. See also MySQL: choosing an API guide and related FAQ for more information.
User avatar
VladSun
DevNet Master
Posts: 4313
Joined: Wed Jun 27, 2007 9:44 am
Location: Sofia, Bulgaria

Re: [Challenge] Conditioning

Post by VladSun »

Prize?!? What prize?!? There is a prize?!? Yahooooooooooo :rofl:

Gi'me, gi'me, gi'me :mrgreen:

PS: It's the min()/max() solution I like most - it was harder to build ;)
There are 10 types of people in this world, those who understand binary and those who don't
User avatar
McInfo
DevNet Resident
Posts: 1532
Joined: Wed Apr 01, 2009 1:31 pm

Re: [Challenge] Conditioning

Post by McInfo »

I never promised prizes. How about praise to everyone who submitted a solution (especially VladSun for having the most variety)?

If anyone can come up with another solution to this challenge, I would still like to see it.

Edit: This post was recovered from search engine cache.
Last edited by McInfo on Mon Jun 14, 2010 5:33 pm, edited 1 time in total.
josh
DevNet Master
Posts: 4872
Joined: Wed Feb 11, 2004 3:23 pm
Location: Palm beach, Florida

Re: [Challenge] Conditioning

Post by josh »

Maybe I'm stating the obvious but it took me a minute to figure out. When the array is populated whichever expression gets evaluated to true gets type cast from a boolean to an integer (one), which is then accessed in the return

Very intriguing stuff. It seems like it'd be way over my head to ever work on such constructs. I would never intentionally use this technique personally ;-) I'd rather see a couple ugly if statements tucked away with code collapse.

Only interest I'd have is if I had to maintain code that abused the technique lol
User avatar
VladSun
DevNet Master
Posts: 4313
Joined: Wed Jun 27, 2007 9:44 am
Location: Sofia, Bulgaria

Re: [Challenge] Conditioning

Post by VladSun »

Well a "pure" lookup table should be constructed like this:

Code: Select all

 
$a1 = $y < 1;
$a2 = $y < 50;
$a3 = $y < 100;
 
$lt[ $a1][ $a2][ $a3]  = 0;
$lt[!$a1][ $a2][ $a3]  = $y + $x;
$lt[!$a1][!$a2][ $a3]  = 50 + $x;
$lt[!$a1][!$a2][!$a3] = 100 + $x;
 
/*$lt = array
(
    $y < 1                  => 0,
    $y >= 1 && $y < 50      => $y + $x,
    $y >= 50 && $y < 100    => 50 + $x,
    $y >= 100               => 100 + $x,
);*/
But it's obvious that $a1, $a2, $a3 are extremely correlated:

Code: Select all

$a1 == true    => $a2 == false, $a3 == false
...
$a2 == false   => $a1 == false
$a3 == false   => $a1 == false, $a2 == false
...
etc.

So it can be written in a shorter form ;)


There are obvious disadvantages when using such "look up" tables - every "address" and it's corresponding "value" MUST be evaluated before the lookup action takes place.
Last edited by VladSun on Sun Mar 07, 2010 4:32 pm, edited 2 times in total.
There are 10 types of people in this world, those who understand binary and those who don't
User avatar
Eran
DevNet Master
Posts: 3549
Joined: Fri Jan 18, 2008 12:36 am
Location: Israel, ME

Re: [Challenge] Conditioning

Post by Eran »

I've begun to use this technique to replace tedious switch statements. I'm really liking it so far :)
User avatar
VladSun
DevNet Master
Posts: 4313
Joined: Wed Jun 27, 2007 9:44 am
Location: Sofia, Bulgaria

Re: [Challenge] Conditioning

Post by VladSun »

Nice to know somebody finds my stuff useful :) :)
There are 10 types of people in this world, those who understand binary and those who don't
josh
DevNet Master
Posts: 4872
Joined: Wed Feb 11, 2004 3:23 pm
Location: Palm beach, Florida

Re: [Challenge] Conditioning

Post by josh »

pytrin wrote:I've begun to use this technique to replace tedious switch statements. I'm really liking it so far :)
I think learning the stuff is fun & important because we'll all have to debug code like this.

But I'm just wondering what potential advantages you see in it that would make you actually rewrite a switch statement to this technique? Do you have a boss that reprimands you for using more than one curly brace for a conditional? Do you find the stuff "readable"? (FYI I do not). It is more "mental juggling" in my opinion
User avatar
Eran
DevNet Master
Posts: 3549
Joined: Fri Jan 18, 2008 12:36 am
Location: Israel, ME

Re: [Challenge] Conditioning

Post by Eran »

I find it much more readable, to be honest. When you have a set of predetermined values that depend on ranges of a variable, it is much easier to see all the values in an array format than in otherwise a much longer switch statement. For example, compare the following pieces of code which both return a screen-size range for laptops depending on a given value -
The original:

Code: Select all

switch ($screen) {
    case $screen < 12 : 
        $filters['screen'] = '8-12';
        break;
    case $screen >= 12 && $screen < 14 :
        $filters['screen'] = '12-14';
        break;
    case $screen >= 14 && $screen < 15 : 
        $filters['screen'] = '14-15';
        break;
    case $screen >= 15 && $screen < 16 : 
        $filters['screen'] = '15-16';
        break;
    case $screen >= 16 && $screen < 17 :
        $filters['screen'] = '16-17';
        break;
    case $screen >= 17 : 
        $filters['screen'] = '17-20';
        break;
}
 
Revised:

Code: Select all

$screenRange = array (
    $screen < 12                    => '8-12',
    $screen >= 12 && $screen < 14   => '12-14',
    $screen >= 14 && $screen < 15   => '14-15',
    $screen >= 15 && $screen < 16   => '15-16',
    $screen >= 16 && $screen < 17   => '16-17',
    $screen >= 17                   => '17-20'
);
$filters['screen'] = $screenRange[1];
It's not "mental juggling" once you're familiar with the concept. Then it's no different than any other language structure.
User avatar
VladSun
DevNet Master
Posts: 4313
Joined: Wed Jun 27, 2007 9:44 am
Location: Sofia, Bulgaria

Re: [Challenge] Conditioning

Post by VladSun »

Another way to write this is:

Code: Select all

$screenRange = array 
(
    1               => '17-20'                                         
    $screen < 17    => '16-17'
    $screen < 16    => '15-16',
    $screen < 15    => '14-15',
    $screen < 14    => '12-14',
    $screen < 12    => '8-12',
);
$filters['screen'] = $screenRange[1];
it's the analog of:

Code: Select all

if ($screen < 12)
   return '8-12';
elseif ($screen < 14)
   return '12-14';
...
else
   return '17-20';
Last edited by VladSun on Mon Mar 08, 2010 4:10 am, edited 1 time in total.
There are 10 types of people in this world, those who understand binary and those who don't
josh
DevNet Master
Posts: 4872
Joined: Wed Feb 11, 2004 3:23 pm
Location: Palm beach, Florida

Re: [Challenge] Conditioning

Post by josh »

Yes that does look cleaner (if you are familiar with the concept). Thanks for clarifying.

Also I would advise if using in a real system, would advise a comment right before the return statement (something that at least provides a term someone can type into google to learn about this pattern). Or maybe not a comment but using the word "lookup" in the function name so people know what the heck it does ;-)
and instead of hard coding the integer "one", making a constant like self::ScreenSize, and self::DefaultSize then I think I would be hard pressed to come up with any more gripes
Post Reply