Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Making a basic algorithm - the more interesting version

Tags:

java

algorithm

See the edit history of "Making a basic algorithm". There was a palpable sense of disappointment amongst the respondents when OP changed the question, invalidating some interesting answers. So, I figure, why not ask the original question again, to allow those answers to stand.

So basically I want to find a easier way to do this:

if(size == 2)  unit /= 2;
if(size == 2 || size == 6) unit /= 2;
if(size == 2 || size == 6 || size == 10) unit /= 2;

So basically it checking if size is equal to 2 and then every new line it add 4 to the last size check.

I need to go up to 256.

I want to know if there a easy way of doing this.

like image 951
Andy Turner Avatar asked Apr 13 '16 18:04

Andy Turner


People also ask

What makes one algorithm better than another?

Created by Pamela Fox. A good algorithm is correct, but a great algorithm is both correct and efficient. The most efficient algorithm is one that takes the least amount of execution time and memory usage possible while still yielding a correct answer.


1 Answers

The fundamental criterion on the numbers checked for equality here is that the remained of size / 4 is 2. This can be detected using the modulo operator, %:

size % 4 == 2

Then there is the question of how many times to divide unit by 2. For the examples above:

  • For size == 2, unit /= 8 (matches all 3 conditions);
  • For size == 6, unit /= 4 (matches second 2 conditions);
  • For size == 10, unit /= 2 (matches last condition).

So the smaller the number, the more times it is divided by 8. If the maximum size checked is 10, unit is divided by 2 ^ (1 + (10 - size) / 4). This can be expressed concisely using the right-shift operator:

unit >>= 1 + (10 - size) / 4

or, more generally:

unit >>= 1 + (max_number - size) / 4

where max_number % 4 == 2.

Setting max_number = 254 (256 is specified in the question, but wouldn't feature in the expression; the last number checked would be 254), and noting that we only apply this if 2 <= size <= 254, we can express the final answer as:

if (size % 4 == 2 && size >= 2 && size <= 254) {
  unit >>= 1 + (254 - size) / 4;
}

Actually, the condition can be expressed more concisely (but undoubtedly less readably) as:

if ((size & 0xffffff03) == 2)

As noted by @PaulBoddington, care needs to be taken with the size of the right shift: if unit is an int and the number of bits shifted is greater than 31, then unit should simply be set to zero.

like image 148
Andy Turner Avatar answered Sep 21 '22 05:09

Andy Turner