DevPinoy.org
A Filipino Developers Community

>>> First two to make 3 wins! <<<

Trivia for the weekend: MIN and MAX without conditional statements

rated by 0 users
This post has 23 Replies | 0 Followers

Top 10 Contributor
Posts 498
Points 8,375
cvega Posted: 02-17-2006 2:29 AM

Obtain the MIN and MAX value of two given integers WITHOUT using any C# conditional statements:

int a = 1001;
int b = 2002;

int min = GetMinValue( a, b );
int max = GetMaxValue( a, b );

MessageBox.Show( "MIN = " + min.ToString() +
                
"; MAX = " + max.ToString() );

Replace GetMinValue and GetMaxValue with your calculation. Again, let me remind you that there will be no usage of conditional statements.

You cant do this:
          
int min = ( a > b ? b : a );

Neither this:
       int min; if ( a > b ) min = b; else min = a;

The solution is doable in pure managed code, thus can also be done in VB.NET.
I'll post the answer in Tuesday, if no one got the correct answer. It would be better if you can do this without the help of google Smile [:)]

Comment: Dont use Math.Min and Math.Max too (Thanks Jeff!)

Cheers,

-chris

Chris Vega This posting is provided "AS IS" with no warranties, and confers no rights My Weblog|Visit MSDN Community
  • | Post Points: 50
Top 25 Contributor
Posts 90
Points 1,280
can i use yahoo?
jk... Stick out tongue [:P]
  • | Post Points: 5
Top 50 Contributor
Posts 50
Points 815
May sagot na ako, I'll PM you.
  • | Post Points: 20
Top 10 Contributor
Posts 953
Points 22,750
di ako nakatiis, tumingin ako sa google at may nahanap ako.

my bad.

http://devpinoy.org/blogs/cruizer
Naglalayong buksan at palayain ang kamalayan ng Pinoy .NET developer
  • | Post Points: 20
Top 10 Contributor
Posts 1,969
Points 39,350

I think i have an aswer to this :)

Can I do this?

class Program
{
   static void Main(string[] args)
   {
      int a = 200;
      int b = 100;

      int min = GetMinValue(a, b);
      int max = GetMaxValue(a, b);

      Console.WriteLine("MIN = " + min.ToString() +
         "; MAX = " + max.ToString());
      Console.ReadLine();
   }

   private static int GetMinValue(int a, int b)
   {
      //put them into an array
      int[] answer = {a,b};
      // this would sort the values in ascending order
      Array.Sort(answer);
      // we got the smallest one here!
      return answer[0];
   }

   private static int GetMaxValue(int a, int b)
   {
      //put them into an array
      int[] answer = { a, b };
      // this would sort the values in ascending order
      Array.Sort(answer);
      // this would reverse our array making it descending order.
      Array.Reverse(answer);
      //we now have the bigger value
      return answer[0];
   }
}

devpinoy sig

  • | Post Points: 20
Top 10 Contributor
Posts 953
Points 22,750
hehheh kung ganon rin lang na solution, let's just stick to using conditionals. Stick out tongue [:P]

no offense meant, keithrull. but it sure does solve the problem di ba (though the conditionals probably appear lower in the pipeline -- within the Sort() method)

http://devpinoy.org/blogs/cruizer
Naglalayong buksan at palayain ang kamalayan ng Pinoy .NET developer
  • | Post Points: 35
Top 10 Contributor
Posts 1,969
Points 39,350

cruizer wrote:
hehheh kung ganon rin lang na solution, let's just stick to using conditionals. Stick out tongue [:P]

no offense meant, keithrull. but it sure does solve the problem di ba (though the conditionals probably appear lower in the pipeline -- within the Sort() method)

hehehe! i know :) i posted it because it was the first thing that came up out my head 30 seconds after reading the trivia... plus.. it was not included on the exclusion list so i gave it a try... i think punzie has a good answer which he has explained to me.. ei punzie! post yours! :D

devpinoy sig

  • | Post Points: 20
Top 10 Contributor
Posts 498
Points 8,375
Keith already created a dedicated forum for Trivia, which means we are going to make problem/solution posting on a regular basis Smile [:)]

1 problem solving a week will keep the rust away...Big Smile [:D]

What do you think guys we make this on per difficulty levels? I mean, separate question for beginners and moderate programmers; while advanced problems will take about 2 weeks, since it will normally require longer period of time to solve.

Regards,

-chris
Chris Vega This posting is provided "AS IS" with no warranties, and confers no rights My Weblog|Visit MSDN Community
  • | Post Points: 20
Top 50 Contributor
Posts 50
Points 815
keithrull wrote:

cruizer wrote:
hehheh kung ganon rin lang na solution, let's just stick to using conditionals. Stick out tongue [:P]

no offense meant, keithrull. but it sure does solve the problem di ba (though the conditionals probably appear lower in the pipeline -- within the Sort() method)

hehehe! i know :) i posted it because it was the first thing that came up out my head 30 seconds after reading the trivia... plus.. it was not included on the exclusion list so i gave it a try... i think punzie has a good answer which he has explained to me.. ei punzie! post yours! :D



I'll post the code once the trivia period is over. (So keep on guessing! Big Smile [:D]) I already PM'ed cvega the code, though I'll make some minor revisions to it because of an overflow scenario.

Clue: no API calls, just primitives.
  • | Post Points: 5
Top 50 Contributor
Posts 50
Points 815
cvega wrote:
Keith already created a dedicated forum for Trivia, which means we are going to make problem/solution posting on a regular basis Smile [:)]

1 problem solving a week will keep the rust away...Big Smile [:D]

What do you think guys we make this on per difficulty levels? I mean, separate question for beginners and moderate programmers; while advanced problems will take about 2 weeks, since it will normally require longer period of time to solve.

Regards,

-chris


Are these all going to be programming puzzles like this one? "Trivia" might not be the best word to describe these.

Difficulty levels sounds like a good idea, however the difficulty judgement is really subjective. I'd rather let the contributor state the problem and what he/she thinks the difficulty is as a matter of opinion, and let everyone answer it.
  • | Post Points: 20
Top 10 Contributor
Posts 498
Points 8,375
Yes, we should limit first to programming puzzles (since this is a developers community) and I agree, "Trivia" is no longer a relevant name for this; do any of you have any suggestion on how we should call this? How about "Programming Challenges"?

By the way, is code completion (something like fill in the blank) considered as programming challenge? I've seen this type of questions to last time I joined a challenge in a russian newsgroup, and I find many of which are difficult enough without looking in MSDN.

Here's what I'm thinking for difficulty level:
* The one who posted the question should post with his own judged initial difficulty level, i.e., 5 stars (assuming we use stars as indication for difficulty level, where 10 stars signifies "advanced level"), then after which the post was made, users can post a comment regarding the accuracy of the difficulty level, hence can ask the poster to modify it.

I propose this format:


Difficulty: 9 stars
Time Limit: 6 Days
Question:
   Display 5 MessageBox simultaneouly on a single button click, all in different screen location.
Limitation:
   No multi-threading, and without looping.


Then when the time limit has lapsed, then the answer together with detailed explanation will be posted, and all those who got the correct answers will be mentioned together with their submissions, and the thread will be locked (or probably better not to lock it?).

How about recognition system regarding challenge winners, any ideas?

Regards,

-chris
Chris Vega This posting is provided "AS IS" with no warranties, and confers no rights My Weblog|Visit MSDN Community
  • | Post Points: 5
Top 25 Contributor
Posts 90
Points 1,280
cvega wrote:

Obtain the MIN and MAX value of two given integers WITHOUT using any C# conditional statements:

int a = 1001;
int b = 2002;

int min = GetMinValue( a, b );
int max = GetMaxValue( a, b );

MessageBox.Show( "MIN = " + min.ToString() +
                
"; MAX = " + max.ToString() );

Replace GetMinValue and GetMaxValue with your calculation. Again, let me remind you that there will be no usage of conditional statements.

You cant do this:
          
int min = ( a > b ? b : a );

Neither this:
       int min; if ( a > b ) min = b; else min = a;

The solution is doable in pure managed code, thus can also be done in VB.NET.
I'll post the answer in Tuesday, if no one got the correct answer. It would be better if you can do this without the help of google Smile [:)]

Comment: Dont use Math.Min and Math.Max too (Thanks Jeff!)

Cheers,

-chris


i think i got this!  i'll PM you my solution... i used Query Analyzer for my testing, have to convert it to C#... Stick out tongue [:P]
  • | Post Points: 20
Top 25 Contributor
Posts 90
Points 1,280
Chris,

i PMed you a (minor) code modification

c",)
  • | Post Points: 5
Top 10 Contributor
Posts 498
Points 8,375

Here's the answer for the current problem

Formula:


The general formula in getting the max (highest amongst) and min (lowest amongst) between two integers (a and b) are these:


  min = ( ( a + b ) - abs( a - b ) ) / 2
  max = ( ( a + b ) + abs( a - b ) ) / 2


Or in much lower level approach of using sign-bit, are these:

  min = a + ( ( signbit( b - a ) ) and ( b - a ) )
  max = b - ( ( signbit( b - a ) ) and ( b - a ) )


Using the formula above, we can complete the solution to the problem as following:

First approach, using the first formula

int a = 1001;
int b = 2002;

// Bit shifting 1 step to the right is equivalent to
// "divide by 2", and abs is available in Math class

int min = ( ( a + b ) - Math.Abs( a - b ) ) >> 1;
int max = ( ( a + b ) + Math.Abs( a - b ) ) >> 1;


MessageBox.Show( "MIN = " + min.ToString() +
                
"; MAX = " + max.ToString() );

Second approach, using the second formula

int a = 1001;
int b = 2002;

// Bit shifting 31 step to the right means we are
// extracting the most significant bit of a 32-bit
// integer, which is treated as a sign-bit in a
// two's complement method.
int min = a + ( ( ( b - a ) >> 31 ) & ( b - a ) );
int max = b - ( ( ( b - a ) >> 31 ) & ( b - a ) );


MessageBox.Show( "MIN = " + min.ToString() +
                
"; MAX = " + max.ToString() );



And the winners

From the 6 submissions I received, CryptoKnight got the most accurate solution using the first approach, here is his submission:

Here's my SQL code
    declare @n1 int, @n2 int
    SET @n1 = 0
    SET @n2 = 123
    SELECT 'MAX', (abs(@n1 + @n2) + abs(@n1 - @n2)) / 2
    SELECT 'MIN', (abs(@n1 + @n2) - abs(@n1 - @n2)) / 2

Here's the C# conversion...
    private int GetMinValue(int a, int b)
    {
        return ((a + b) - Math.Abs(a - b)) / 2;
    }

    private int GetMaxValue(int a, int b)
    {
        return ((a + b) + Math.Abs(a - b)) / 2;
    }


And punzie got the solution riding on the same line as second approach, by using the sign-bit to index an array of two elements (he sent this solution few minutes after I posted the question):

public int MyMin(int x, int y)
{
    int[] holder = new int[2];
    holder[0] = x;
    holder[1] = y;
    int signBit = ((y - x) >> 31) & 1;
    return holder[signBit];
}

public int MyMax(int x, int y)
{
    int[] holder = new int[2];
    holder[0] = x;
    holder[1] = y;
    int signBit = ((x - y) >> 31) & 1;
    return holder[signBit];
}


The other 4 solutions I received also solved the problem, and all 4 solutions are in the same line of Array sorting, and reversing; same the what posted by Keith above.


Practical usage

One of the 6 who respond asked a question "what is the practical use of this"? Well, I could say that this is designed mainly for programming challenges and there's no actual practical usage; however I did used this on one of my project few years ago, when I was adding line numbers and collapsing feature in a RichTextBox control, where I used the second approach to calculate which line has the most and least number of characters in the entire RTB contents, and this is the exact functions I used that time (it accepts number of characters per line in an array, or an array of integers in general):

  private int GetMinInArray(int [] array)
  {
   int min = int.MaxValue/2;
   int ubound = array.Length;

   for(int i=0; i<ubound; i++) 
   {
    min = min + ( ( ( array[ i ] - min ) >> 31 ) &
                    ( array[ i ] - min ) );
   }
   return min;
  }

  private int GetMaxInArray(int [] array)
  {
   int max = int.MinValue/2;
   int ubound = array.Length;

   for(int i=0; i<ubound; i++)
   {
    max = max - ( ( ( max - array[ i ] ) >> 31 ) &
                    ( max - array[ i ] ) );
   }
   return max;
  }

And this is the code for I created just now for testing the above functions:

   int [] ary = new int[30]
       {
        2100, 2002, 5005, 501, 3003,
        2001, 999, 5602, 120, 1203,
        892, 8391, 119, 3102, 4001,
        192, 5112, 3621, 6721, 0122,
        6310, 8921, 4325, 1011, 0912,
        7683, 3999, 1102, 9123, 0184
       };

   int min = GetMinInArray(ary);
   int max = GetMaxInArray(ary);

   MessageBox.Show( "MIN = " + min.ToString() +
    "; MAX = " + max.ToString() );


Closing

Again, thanks for participating in this problem solving; and complements to all who got the right solution. Hope to see you again on our next problem solving.

Best regards to all,

-chris

Chris Vega This posting is provided "AS IS" with no warranties, and confers no rights My Weblog|Visit MSDN Community
  • | Post Points: 20
Top 50 Contributor
Posts 50
Points 815
I didn't use Math.Abs since I think it uses conditionals, just like Array.Sort. Anyone ILDASM'ed this?

UPDATE: Here's the relevant decompiled code, from .NET Reflector:

public static int Abs(int value)
{
      if (value >= 0)
      {
            return value;
      }
      return Math.AbsHelper(value);
}

private static int AbsHelper(int value)
{
      if (value >= 0)
      {
            return value;
      }
      if (value == -2147483648)
      {
            throw new OverflowException(Environment.GetResourceString("Overflow_NegateTwosCompNum"));
      }
      return -value;
}


Mapapaaway ba ako dito? Just in the interest of correctness. Stick out tongue [:P]

  • | Post Points: 50
Page 1 of 2 (24 items) 1 2 Next > | RSS

Copyright DevPinoy 2005-2008