Соревнование
Реализуйте функцию, которая принимает два целых числа, значения которых находятся в диапазоне от 0 до 255, и возвращает сумму этих целых чисел mod 256. Вы можете использовать только побитовое отрицание (~), побитовое или (|), операторы сдвига битов (>>, <<) и назначение (=).
Вещи, которые вы не можете использовать, включают (но не ограничиваются ими)
- Сложение, вычитание, умножение и деление
- Loops
- Условные заявления
- Вызовы функций
Наименьшее использование двоичных операций, двоичного отрицания и операций сдвига битов выигрывает . В случае ничьей побеждает самое популярное решение. Как всегда, применяются стандартные лазейки .
Вот пример простого 2-битного сумматора. Он использует 77 бинарных отрицаний, 28 бинарных ордеров и 2 сдвига битов для общей оценки 107 (это можно увидеть, запустив препроцессор C с gcc -E
). Это можно сделать намного эффективнее, удалив #define
s и упростив полученные выражения, но я оставил их для ясности.
#include <stdio.h>
#define and(a, b) (~((~a)|(~b)))
#define xor(a, b) (and(~a,b) | and(a,~b))
int adder(int a, int b)
{
int x, carry;
x = xor(and(a, 1), and(b, 1));
carry = and(and(a, 1), and(b, 1));
carry = xor(xor(and(a, 2), and(b, 2)), (carry << 1));
x = x | carry;
return x;
}
int main(int argc, char **argv)
{
int i, j;
for (i = 0; i < 4; i++) {
for (j = 0; j < 4; j++) {
if (adder(i, j) != (i + j) % 4) {
printf("Failed on %d + %d = %d\n", i, j, adder(i, j));
}
}
}
}
Обновление: добавлен пример и изменен критерий оценки.
Ответы:
Python, 36 операций
Методы, логарифмические по параметру "8"!
Идея состоит в том, чтобы выяснить, какие индексы переполняют и вызывают переносы. Первоначально, это просто места, где оба
a
anddb
имеют1
. Но поскольку переносимые биты могут вызывать дальнейшие переполнения, это необходимо определять итеративно.Вместо того, чтобы переполнять каждый индекс в следующий, мы ускоряем процесс, перемещая 1 индекс, затем 2 индекса, затем 4 индекса, обязательно запомнив места, где произошло переполнение (H) и где переполнение больше не может произойти (K ).
Более простое итеративное решение с 47 операциями:
Испытательный стенд для тех, кто хочет его скопировать.
источник
С - 0
Он использует операторы вне ~, |, >>, << и =, но я вижу решения, использующие операторы приведения и запятые, поэтому я предполагаю, что правило не слишком строгое, если оно не использует запрещенные операторы.
источник
питон, оценка =
8380Разверните цикл. Это 10 операций за цикл, 7 циклов, 7 для последнего xor и 3, чтобы раздавить 9-й бит в конце.
Реализует уравнение
x+y = x^y + 2*(x&y)
, повторяя его 8 раз. Каждый раз, когда есть еще один нулевой бит в нижней частиy
.источник
C, оценка:
7760Гольф только для черта,
206169131 байт:Expanded:
По сути, это то же решение (математически), которое было разработано
@KeithRandall@JuanICarrano, но оно использует способность C быстро и свободно играть с переменными типами и указателями, чтобы стереть все после первых 8 бит без использования дополнительных операторов.Зависит от порядкового номера машины и sizeof (), int и char, но может быть перенесен на большинство машинно-зависимых приложений с соответствующей математикой указателя.
РЕДАКТИРОВАТЬ: Это проблема, которую C (или другие языки низкого уровня) будут иметь явное преимущество - если кто-то не придумает алгоритм, который не должен нести.
источник
unsigned char
. Это чище и портативнее.unsigned
мне не естественно. Вы правы конечно - обновлено.Питон - Оценка
6664Это уравнение для сумматора пульсации. C это перенос. Он вычисляется по одному биту за раз: в каждой итерации перенос переносится влево. Как отмечает @Orby, оригинальная версия не сделала модульное дополнение. Я исправил это и также сохранил цикл в итерации, так как первый перенос всегда равен нулю.
источник
s(255,2)
возвращается,257
а не1
). Вы можете исправить это, изменив свою последнюю строку,return ~(~xxor(axb,C)|256)
которая добавляет 3 балла.С ++ - оценка: 113
источник
add(1, 255)
возвращается 128 для меня, @Ryan.%
нет в списке разрешенных операторов, а именно~
,|
,>>
, и<<
. Может заменить егоands(x8|y8, 255)>>1
?~(~x8 | y8 | 0xFFFFFF00)
было бы неплохо, только с 4+ на ваш счет.byte
вместо того,int
чтобы сделать его переполнением автоматически?