views:

771

answers:

15

Given inputs 1-32 how can I generate the below output?

in. out

  1. 1
  2. 1
  3. 1
  4. 1
  5. 2
  6. 2
  7. 2
  8. 2
  9. 1
  10. 1
  11. 1
  12. 1
  13. 2
  14. 2
  15. 2
  16. 2 ...

Edit Not Homework.. just lack of sleep.

I am working in C#, but I was looking for a language agnostic algorithm.

Edit 2 To provide a bit more background... I have an array of 32 items that represents a two dimensional checkerboard. I needed the last part of this algorithm to convert between the vector and the graph, where the index aligns on the black squares on the checkerboard.

Final Code:

 --Index;
 int row = Index >> 2;
 int col = 2 * Index - (((Index & 0x04) >> 2 == 1) ? 2 : 1);
+3  A: 

In Perl:

#!/usr/bin/perl

use strict; use warnings;

sub it {
    return sub {
        my ($n) = @_;
        return 1 if 4 > ($n - 1) % 8;
        return 2;
    }
}

my $it = it();

for my $x (1 .. 32) {
    printf "%2d:%d\n", $x, $it->($x);
}

Or:

sub it {
    return sub {
        my ($n) = @_;
        use integer;
        return 1 + ( (($n - 1) / 4) % 2 );
    }
}
Sinan Ünür
Thats overkill.
drhirsch
So what? On second thought, it looks like I gave a serious answer to an arithmetic question that should have been closed as "not programming related".
Sinan Ünür
Come on, I didn't downvote you. It's just that in my opinion your solution lacks some elegance, especially compared to mine ;-)
drhirsch
I'de use the second one, since it has less line for the same thing.
David Brunelle
@drhirsch I prefer to give full, runnable code as answers rather than single lines. So, you might think `1 + (4 > ($n - 1) % 8)` is a better answer, but I prefer to give full, runnable code as an answer.
Sinan Ünür
Well, so we just have different preferences. For homework I prefer to not give a full, runnable code. Besides, for this specific question, I think its arguable if enclosing my answer in 'int main(int argc, char argv**) { int input = atoi(argv[1])' and 'printf("%c\n", output); }' would make the point much clearer.
drhirsch
+6  A: 

You could use a combination of integer division and modulo 2 (even-odd): There are blocks of four, and the 1st, 3rd, 5th block and so on should result in 1, the 2nd, 4th, 6th and so on in 2.

s := ((n-1) div 4) mod 2;
return s + 1;

div is supposed to be integer division.

EDIT: Turned first mod into a div, of course

Tom Bartel
+10  A: 

in C:

char output = "11112222"[input-1 & 7];

or

char output = (input-1 >> 2 & 1) + '1';

or after an idea of FogleBird:

char output = input - 1 & 4 ? '2' : '1';

or after an idea of Steve Jessop:

char output = '2' - (0x1e1e1e1e >> input & 1);

or

char output = "12"[input-1>>2&1];

C operator precedence is evil. Do use my code as bad examples :-)

drhirsch
nicely done I was thinking of: out = (5>(in%8))?1:2;
eliocs
Nice reformulation. My "best" ever use of lookup into an integer was to Gray code 2 bits per index into a 32-bit int, in order to select one of 4 values for each integer 1-31, to map them to suffixes "st", "nd", "rd", "th" (potentially looked up again, in a 64bit integer, although normally that doesn't help at all because a constant pool value is no better than a char array). Unfortunately that one-liner didn't survive localisation ;-)
Steve Jessop
I wanted to get rid of the "-1" :-) Sometimes sub byte operations can be very useful.With lookup tables, I found a gem: The pshufb instrucution. Intended for arbitrarily shuffling the contents of a 16 byte SSE register, it can by abused to do a lookup of a table with a very limited size of 16 different values. Doesn't sound so good? Well, it can do 16 of those lookups parallel in one clock cycle. Good for a massive speed up in my chess program, I need now 4 instructions to do a lookup of all 64 squares, and the limited table size isn't a problem, since there are less than 16 different pieces.
drhirsch
You say abused. Seems to me it's designed precisely as a 16-parallel use of a 16-entry lut, and Intel just gave it a funny name :-)
Steve Jessop
+4  A: 

Python

def f(x):
    return int((x - 1) % 8 > 3) + 1

Or:

def f(x):
    return 2 if (x - 1) & 4 else 1

Or:

def f(x):
    return (((x - 1) & 4) >> 2) + 1
FogleBird
+16  A: 

Assuming that you can use bitwise operators you can check what the numbers with same output have in common, in this case I preferred using input 0-31 because it's simpler (you can just subtract 1 to actual values)

What you have?

0x0000 -> 1
0x0001 -> 1
0x0010 -> 1
0x0011 -> 1
0x0100 -> 2
0x0101 -> 2
0x0110 -> 2
0x0111 -> 2
0x1000 -> 1
0x1001 -> 1
0x1010 -> 1
0x1011 -> 1
0x1100 -> 2
...

It's quite easy if you notice that third bit is always 0 when output should be 1 and viceversa it's always 1 when output should be 2

so:

char codify(char input)
{
     return ((((input-1)&0x04)>>2 == 1)?(2):(1));
}

EDIT

As suggested by comment it should work also with

char codify(char input)
{
     return ((input-1 & 0x04)?(2):(1));
}

because in some languages (like C) 0 will evaluate to false and any other value to true. I'm not sure if it works in C# too because I've never programmed in that language. Of course this is not a language-agnostic answer but it's more C-elegant!

Jack
Excellent, thanks!
Nescio
Why not: return (input - 1)
FogleBird
Because I'm used to approach *mask, shift and check*.. it's just personal taste, isnt't?
Jack
drhirsch
I like drhirsch's answer even better, but some languages require a bool value when truth testing.
FogleBird
+1  A: 

It depends of the language you are using.

In VB.NET, you could do something like this :

for i as integer = 1 to 32
   dim intAnswer as integer = 1 + (Math.Floor((i-1) / 4) mod 2)
   ' Do whatever you need to do with it
next

It might sound complicated, but it's only because I put it into a sigle line.

David Brunelle
+1  A: 

Thats pretty straightforward:

if (input == "1") {Console.WriteLine(1)};
if (input == "2") {Console.WriteLine(1)};
if (input == "3") {Console.WriteLine(1)};
if (input == "4") {Console.WriteLine(1)};
if (input == "5") {Console.WriteLine(2)};
if (input == "6") {Console.WriteLine(2)};
if (input == "7") {Console.WriteLine(2)};
if (input == "8") {Console.WriteLine(2)};

etc...

HTH

Jimberly
who would've thought about this?
Amarghosh
Exactly, the other responses are over-engineered and needlessly complex.
Jimberly
This is nice, but I need the values as part of a larger calculation.
Nescio
So just wrap it in a method? Is this what you mean?
Jimberly
That is awful, -1.
FogleBird
Please elaborate...
Jimberly
Do you hand code every input/output pair for every function you write?
FogleBird
http://www.urbandictionary.com/define.php?term=sarchasm This is the second time today that I am linking to this page. What is happening to the world?
Amarghosh
+6  A: 

Just for laughs, here's a technique that maps inputs 1..32 to two possible outputs, in any arbitrary way known at compile time:

// binary 1111 0000 1111 0000 1111 0000 1111 0000
const uint32_t lu_table = 0xF0F0F0F0;

// select 1 bit out of the table
if (((1 << (input-1)) & lu_table) == 0) {
    return 1;
} else {
    return 2;
}

By changing the constant, you can handle whatever pattern of outputs you want. Obviously in your case there's a pattern which means it can probably be done faster (since no shift is needed), but everyone else already did that. Also, it's more common for a lookup table to be an array, but that's not necessary here.

Steve Jessop
+1 For the idea. I will reformulate this ;-)
drhirsch
+1  A: 

In Groovy:

def codify = { i  ->
    return  (((((i-1)/4).intValue()) %2 ) + 1)
}

Then:

def list = 1..16
list.each {
    println "${it}: ${codify(it)}"
}
mbrevoort
+3  A: 

In Haskell:

vec2graph :: Int -> Char
vec2graph n = (cycle "11112222") !! (n-1)
Greg Bacon
+4  A: 

The accepted answer return ((((input-1)&0x04)>>2 == 1)?(2):(1)); uses a branch while I would have just written:

return 1 + ((input-1) & 0x04 ) >> 2;

Gregory Pakosz
+1 for the idea.
FogleBird
Note that after optimization and constant folding the branch will most likely be gone. And I think its got accepted because its one the the few answers which does explain something.
drhirsch
+1  A: 
char codify(char input)
{
     return  (((input-1) & 0x04)>>2) + 1;
}
plinth
+1  A: 

Using Python:

output = 1
for i in range(1, 32+1):
  print "%d. %d" % (i, output)
  if i % 4 == 0:
    output = output == 1 and 2 or 1
gmoh
+1  A: 

JavaScript

My first thought was

output = ((input - 1 & 4) >> 2) + 1;

but drhirsch's code works fine in JavaScript:

output = input - 1 & 4 ? 2 : 1;

and the ridiculous (related to FogleBird's answer):

output = -~((input - 1) % 8 > 3);
Nosredna
+1  A: 

Java, using modulo operation ('%') to give the cyclic behaviour (0,1,2...7) and then a ternary if to 'round' to 1(?) or 2(:) depending on returned value. ...

 public static void main(String[] args) {
        for (int i=1;i<=32;i++) {
             System.out.println(i+"="+ (i%8<4?1:2) );
    }

Produces:

1=1 2=1 3=1 4=2 5=2 6=2 7=2 8=1 9=1 10=1 11=1 12=2 13=2 14=2 15=2 16=1 17=1 18=1 19=1 20=2 21=2 22=2 23=2 24=1 25=1 26=1 27=1 28=2 29=2 30=2 31=2 32=1

monojohnny