如何生成这种数字模式?

时间:2009-11-30 15:22:55

标签: algorithm language-agnostic

如果输入1-32,我如何生成以下输出?

英寸出

  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 ...
  17. 编辑不是家庭作业..只是缺乏睡眠。

    我在C#工作,但我一直在寻找与语言无关的算法。

    编辑2 为了提供更多背景...我有一个包含32个项目的数组,代表一个二维棋盘。我需要此算法的最后一部分在矢量和图形之间进行转换,其中索引在棋盘上的黑色方块上对齐。

    最终守则:

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

15 个答案:

答案 0 :(得分:16)

假设您可以使用按位运算符,您可以检查具有相同输出的数字的共同点,在这种情况下,我更喜欢使用输入0-31,因为它更简单(您可以只减1到实际值)

你有什么?

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
...

如果你注意到输出应该是0时第三位总是1,而当输出应该是1

时,反之则总是2,这很容易

这样:

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

修改

根据评论的建议,它也可以与

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

因为在某些语言(例如C)中,0将评估为false,其他任何值将评估为true。我不确定它是否也适用于C#,因为我从未用该语言编程。当然,这不是一个与语言无关的答案,但它更加优雅!

答案 1 :(得分:10)

在C:

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

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

或者是关于FogleBird的想法之后:

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

或在Steve Jessop的想法之后:

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

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

C运算符优先级是邪恶的。使用我的代码作为坏例子: - )

答案 2 :(得分:6)

你可以使用整数除法和模2(偶数奇数)的组合:有四个块,第一个,第三个,第五个块等应该产生1,第2,第4,第6等等在2。

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

div应该是整数除法。

编辑:将第一个mod转换为div,当然

答案 3 :(得分:6)

只是为了笑,这是一种将输入1..32映射到两个可能输出的技术,以编译时已知的任意方式:

// 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;
}

通过更改常量,您可以处理所需的任何输出模式。显然在你的情况下有一种模式,这意味着它可以更快地完成(因为不需要转换),但其他人已经做到了。此外,查找表更常见的是数组,但这不是必需的。

答案 4 :(得分:4)

<强>的Python

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

或者:

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

或者:

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

答案 5 :(得分:4)

接受的答案return ((((input-1)&0x04)>>2 == 1)?(2):(1));使用了一个分支,而我刚写完:

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

答案 6 :(得分:3)

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);
}

或者:

sub it {
    return sub {
        my ($n) = @_;
        use integer;
        return 1 + ( (($n - 1) / 4) % 2 );
    }
}

答案 7 :(得分:3)

在Haskell:

vec2graph :: Int -> Char
vec2graph n = (cycle "11112222") !! (n-1)

答案 8 :(得分:1)

这取决于您使用的语言。

在VB.NET中,您可以这样做:

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

听起来可能很复杂,但这只是因为我把它放到了一条线上。

答案 9 :(得分:1)

这很简单:

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)};

等...

HTH

答案 10 :(得分:1)

在Groovy中:

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

然后:

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

答案 11 :(得分:1)

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

答案 12 :(得分:1)

使用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

答案 13 :(得分:1)

<强>的JavaScript

我的第一个想法是

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

但是drhirsch的代码在JavaScript中运行良好:

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

和荒谬(与FogleBird的答案有关):

output = -~((input - 1) % 8 > 3);

答案 14 :(得分:1)

Java,使用模运算('%')给出循环行为(0,1,2 ... 7)然后使用三元if''舍入'到1(?)或2(:)取决于返回值。 ...

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

产地:

  

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