Как я могу создать этот шаблон чисел? - PullRequest
5 голосов
/ 30 ноября 2009

С учетом входов 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 ...

Редактировать Не домашнее задание .. просто недостаток сна.

Я работаю в C #, но я искал алгоритм, независимый от языка.

Редактировать 2 Чтобы обеспечить немного больше фона ... У меня есть массив из 32 элементов, который представляет двухмерную шахматную доску. Мне нужна была последняя часть этого алгоритма для преобразования между вектором и графиком, где индекс выравнивается по черным квадратам на шахматной доске.

Итоговый код:

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

Ответы [ 15 ]

16 голосов
/ 30 ноября 2009

Предполагая, что вы можете использовать побитовые операторы, вы можете проверить, что общего имеют числа с одинаковым выходом, в этом случае я предпочел бы использовать ввод 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));
}

EDIT

Как следует из комментария, он должен работать также с

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

потому что в некоторых языках (например, C) 0 будет иметь значение false, а любое другое значение - true. Я не уверен, что это работает и в C #, потому что я никогда не программировал на этом языке. Конечно, это не зависит от языка, но это более элегантно!

10 голосов
/ 30 ноября 2009

в С:

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

или

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

или после идеи FogleBird:

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

или после идеи Стива Джессопа:

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

или

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

Приоритет оператора C - зло. Используйте мой код как плохие примеры: -)

6 голосов
/ 30 ноября 2009

Просто для смеха, вот техника, которая отображает входные данные 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;
}

Изменяя константу, вы можете работать с любым шаблоном выходных данных. Очевидно, что в вашем случае есть шаблон, который означает, что, вероятно, это можно сделать быстрее (поскольку сдвиг не требуется), но все остальные уже сделали это. Кроме того, справочная таблица является массивом, но здесь это не обязательно.

6 голосов
/ 30 ноября 2009

Вы можете использовать комбинацию целочисленного деления и по модулю 2 (четно-нечетное): Есть блоки из четырех, и 1-й, 3-й, 5-й блок и т. Д. Должны привести к 1, 2-му, 4-му, 6-му и т. в 2.

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

div предполагается целочисленным делением.

РЕДАКТИРОВАТЬ: Превратил первый мод в div, конечно же

4 голосов
/ 30 ноября 2009

Принятый ответ return ((((input-1)&0x04)>>2 == 1)?(2):(1)); использует ветку, а я бы просто написал:

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

4 голосов
/ 30 ноября 2009

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
3 голосов
/ 30 ноября 2009

В Хаскеле:

vec2graph :: Int -> Char
vec2graph n = (cycle "11112222") !! (n-1)
3 голосов
/ 30 ноября 2009

В 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 );
    }
}
1 голос
/ 10 декабря 2009

Java, используя операцию по модулю ('%'), чтобы задать циклическое поведение (0,1,2 ... 7), а затем троичный, если «округлить» до 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 = 110 = 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

1 голос
/ 30 ноября 2009

JavaScript

Моя первая мысль была

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

но код Дрирша отлично работает в JavaScript:

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

и смешно (связано с ответом FogleBird):

output = -~((input - 1) % 8 > 3);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...