Рассчитайте n% 12

27

Рассчитать nпо модулю 12для 32-разрядного целого числа без знака.

Правила:

  • Должен работать для всех nот 0 до 23. Другие числа необязательны.
  • Необходимо использовать только любой из операторов +-*, ~&^|или <<, >>как это обычно определяется на 32 - битных uints.
  • Может использовать произвольное количество постоянных uints.
  • Не разрешается использовать любые указатели, в том числе массивы или любые ifоператоры, включая вещи, которые компилируются в операторы if, такие как троичные операторы или операторы «больше чем».

Подсчет очков:

  • Операторы + -и побитовые операторы ~ & ^ | << >>(NOT, AND, XOR, OR, битовые сдвиги) дают оценку 1, *дают оценку 2.
  • Наименьшее общее количество очков выигрывает.
nbubis
источник
6
Возможно, вы захотите определить операторы для пользователей языков, отличных от C / Java. Я понимаю, +-*это сложение, вычитание, умножение; ~&^|поразрядно НЕ, И, XOR, ИЛИ; и << >>сдвиги.
Уровень Река Сент
@steveverrill - спасибо. Это действительно намерение.
Нубубис
Могу ли я использовать for i in x:y:z, .dostuff?
Οurous
Могу ли я установить переменную, равную значению, используемому в выражении?
xnor
4
большинство компиляторов оптимизируют n % 12под умножение и сдвиг, как в восторге от хакера, так что это тривиально, просто выведите сборку и посмотрите
phuclv

Ответы:

29

4

(Язык не имеет значения)

n-((48&(11-n))>>2)

Woo! Добрался до 4.

11-n будет гарантировать, что все биты старшего разряда установлены тогда и только тогда, когда n> = 12.

48&(11-n) == если n> 11, то еще 48 0

(48&(11-n))>>2 == если n> 11, то 12, иначе 0

n-((48&(11-n))>>2) это ответ

isaacg
источник
1
Оуууууу, ты побил меня до такого подхода! Я был всего в нескольких шагах от публикации n - (((11 - n) & 0xC0000000) >> 28). Хорошо, я не думаю, что это можно сделать менее чем за четыре.
Runer112
1
@ Runner112 Да, я надеялся, что никто не побьет меня, когда я отправлю это. Хорошо сделано, чтобы найти это для себя, хотя
isaacg
1
Круто :) 4 действительно достижение.
nbubis
11

4

Решение с помощью справочной таблицы (оно выглядит вверх i ^ (i % 12)):

i ^ (0x1d4c000 >> (i & 0xfc) & 30)

4

Вот еще одно решение с 4 операциями:

i - ((0xffff >> (i - 12)) & 12)

Предполагается, что операнд подсчета битовых сдвигов неявно принимается мод 32, то x >> -1есть такой же, как x >> 31.

5

Другой подход, используя таблицу поиска:

i - (16773120 >> i & 1) * 12
копия
источник
7

Баш - 1

echo `seq 0 11` `seq 0 11` | awk '{print $(number+1)}'

например

$ echo `seq 0 11` `seq 0 11` | awk '{print $(0+1)}'
0

$ echo `seq 0 11` `seq 0 11` | awk '{print $(11+1)}'
11

$ echo `seq 0 11` `seq 0 11` | awk '{print $(12+1)}'
0

$ echo `seq 0 11` `seq 0 11` | awk '{print $(23+1)}'
11

источник
1
Это недействительно, потому что он использует указатели.
curiousdannii
@curiousdannii Какие указатели вы имеете в виду? То stdinа stdoutручьи? Конечно, внутри они являются указателями, но тогда мы могли бы также дисквалифицировать Java, потому что он использует Integerкласс для многих целей.
Коул Джонсон
Разве $ () фактически не эквивалентен указателю?
curiousdannii
@curiousdannii - в документации awk говорится, что они являются встроенными переменными.
5

C, little-endian - 2

Это, вероятно, обман, но я думаю, что это соответствует правилам ...

union {
    int i;
    struct {
        int a:4;
        int b:2;
        int c:10;
    } s;
    struct {
        int a:2;
        int b:14;
    } t;
} u;

u.i = 11-n;
u.s.a = 0;
u.s.c = 0;
result = n-u.t.b;
Р..
источник
Как это работает?
nbubis
1
Сорт обманывает, так как вы используете = 0 вместо & 0x0, который должен засчитываться как дополнительные 2 операции. Но +1 за креативность :)
нбубис
4

PHP - оценка 0

Интересно, как это возможно, что никто не пришел с этим до меня !!!

$n = 18;
$s = str_repeat("a", $n);
$s2 = preg_replace('/aaaaaaaaaaaa/', '', $s);
echo strlen($s2);
Tomas
источник
2
Ницца. Я думаю, что здесь может быть проблема, так как массивы запрещены. Хотя на самом деле приятно.
AJMansfield
@AJMansfield Можно утверждать, что это не массивы, а строки (да, строки низкого уровня - это байтовые массивы). :)
seequ
1
@seequ Можно также утверждать, что это недопустимо из-за использования ОЗУ (да, на низком уровне ram является технически индексированным массивом) ¯_ (ツ) _ / ¯
Stan Strum
2

С, оценка 5

Работает до 23, не гарантируется выше.

( ((n+4)>>2)&4 ) + n & 15

((n+4)>>2)&4возвращает 4 при n> = 12. Добавьте его к n, и вы получите правильный ответ в младших 4 битах, а затем обрежете остальные биты.

Уровень реки St
источник
Отлично сработано!! Теперь давайте посмотрим, сможет ли кто-нибудь добраться до 4 ..
нбубис
2

на любом языке: 5

не собираюсь побеждать, но участвую потому, что весело, а может, потому что это легче понять, чем другим:

n - ((n+20)>>5)*12

это эквивалентно

n - (n>11)*12

это эквивалентно, потому что, когда вы добавляете 20 к 12, вы получаете 32, таким образом, 5-й бит становится 1. Это только когда n> 1, поскольку 32 - наименьшее число, где 5-й бит становится 1.

также обратите внимание, что легко расширяется для более высокого диапазона, как вы можете сделать

n - ((n+20)>>5)*12 - ((n+41)>>5)*12

достичь диапазона до 35

Pinna_be
источник
1

Python 2.x - 4

j=input();m=lambda a,b:a*b;a=(m(j,357913942)>>32);print j-m(12,a)

Является =ли оператор?

В этом случае счет 6.

j-12*(j*357913942>>32)

Кстати, решение @steveverrill можно напрямую использовать и в Python.

Работает для диапазона 0 .. 23

Итак, что происходит ? Умножьте на 357913942 и разделите на 2 ^ 32 (или сдвиг вправо 32)

Willem
источник
Мне нравится, как вы использовали функцию для умножения только один раз. но imho вы просто переименовали умножение в функцию m (,), что для меня означает, что вы использовали его дважды.
Pinna_be
зависит от того, как правила интерпретируются, но у вас есть действительный пункт
Виллем
1

С - 6

(n - (((n * 0xAAAB) >> 19)) * 12 )
nbubis
источник
Это должно быть либо частью вопроса, либо просто другим ответом. Я предлагаю последнее.
Jwosty
@Jwosty - изменился.
nbubis
0

Кобра - 2 (или 3)

def modulo12(n as uint32) as uint32
        for i in 11:n to int64:12,n-=12
        return n

Это может быть изгиб , тем правила немного, но я попросил и ему было разрешено использовать это.

Это также работает для любого числа.

Οurous
источник
0

Кона - 5

Может быть недействительным, потому что я не уверен, разрешен ли оператор пола, но у меня есть два *с минусом:

mod:{x-(_0.08333*x)*12}

Который должен работать для любого целого числа.

Kyle Kanos
источник
Я не уверен в операции пола, но я определенно уверен, что первое умножение работает на чем-то отличном от 32-разрядных целых чисел.
Runer112
@ Runer112: OP говорит, что ввод должен быть 32-битным, а операторы такие, как определено, обычно с 32-битными значениями; это ничего не говорит о нецелых значениях в коде.
Кайл Канос
Если не понимать что-то неправильно, 0.08333 * x не выглядит как умножение, как определено для 32-битных uint, потому что 0.08333 не является 32-битной uint.
Runer112
1
«Может использовать произвольное количество постоянных uints». т.е. не может использовать произвольные числа с плавающей точкой.
Нубубис
1
@nbubis: эта строка не накладывает ограничений на число с плавающей точкой.
Кайл Канос