Die Herausforderung
Implementieren Sie eine Funktion, die zwei Ganzzahlen akzeptiert, deren Werte von 0 bis 255 reichen, und die Summe dieser Ganzzahlen (Mod 256) zurückgibt. Sie können nur bitweise Negation (~), bitweise oder (|), Bitverschiebungsoperatoren (>>, <<) verwenden. und Zuweisung (=).
Zu den Dingen, die Sie nicht verwenden können, gehören (ohne darauf beschränkt zu sein)
- Addition, Subtraktion, Multiplikation und Division
- Schleifen
- Bedingte Anweisungen
- Funktionsaufrufe
Die wenigsten Verwendungen von binären oder binären Negations- und Bitverschiebungsoperationen gewinnen . Bei einem Gleichstand gewinnt die beliebteste Lösung. Wie immer gelten Standardlücken .
Hier ist ein Beispiel eines einfachen 2-Bit-Addierers. Es verwendet 77 binäre Negationen, 28 binäre Ors und 2 Bitverschiebungen für eine Gesamtpunktzahl von 107 (dies kann durch Ausführen des C-Präprozessors mit angezeigt werden gcc -E
). Es könnte viel effizienter gemacht werden, indem man die #define
s entfernt und die resultierenden Ausdrücke vereinfacht, aber ich habe sie der Klarheit halber belassen.
#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));
}
}
}
}
Update: Beispiel hinzugefügt und Bewertungskriterien geändert
quelle
Antworten:
Python, 36 Operationen
Eine Methode, die im Parameter "8" logarithmisch ist!
Die Idee ist herauszufinden, welche Indizes Überlauf und Ursache tragen. Anfänglich sind dies nur die Orte, an denen beide und
a
eineb
haben1
. Da übertragene Bits jedoch weitere Überlappungen verursachen können, muss dies iterativ bestimmt werden.Anstatt jeden Index in den nächsten zu überfließen, beschleunigen wir den Prozess, indem wir 1 Index, dann 2 Indizes und dann 4 Indizes verschieben. Dabei müssen wir uns die Stellen merken, an denen ein Überlauf aufgetreten ist (H) und an denen kein Überlauf mehr auftreten kann (K) ).
Eine einfachere iterative Lösung mit 47 Operationen:
Prüfstand für alle, die ihn kopieren wollen.
quelle
C - 0
Es werden zwar Operatoren außerhalb von ~, |, >>, << und = verwendet, es werden jedoch Lösungen mit Casting- und Komma-Operatoren angezeigt, sodass die Regel vermutlich nicht zu streng ist, sofern die verbotenen Operatoren nicht verwendet werden.
quelle
Python, Score =
8380Wickeln Sie die Schleife ab. Es sind 10 Operationen pro Schleife mal 7 Schleifen, 7 für das letzte xor und 3, um das 9. Bit am Ende zu quetschen.
Implementiert die Gleichung
x+y = x^y + 2*(x&y)
durch achtmaliges Wiederholen. Jedes Mal befindet sich ein weiteres Nullbit am Ende vony
.quelle
C, Punktzahl:
7760Golfen nur zum Teufel,
206169131 Bytes:Erweitert:
Im Wesentlichen die gleiche Lösung (mathematisch) wie
@KeithRandall@JuanICarrano, nutzt jedoch die Fähigkeit von C, schnell und locker mit variablen Typen und Zeigern zu spielen, um nach den ersten 8 Bits alles zu löschen, ohne weitere Operatoren zu verwenden.Hängt vom Endian der Maschine und der Größe von (), einem int und einem char ab, sollte aber mit der richtigen Zeigermathematik für die meisten maschinenspezifischen Anwendungen portiert werden können.
BEARBEITEN: Dies ist eine Herausforderung, bei der C (oder andere Sprachen mit niedrigem Sprachniveau) eine ausgeprägte Oberhand haben wird - es sei denn, jemand hat einen Algorithmus gefunden, der nicht mithalten muss.
quelle
unsigned char
. Es ist sauberer und tragbarer.unsigned
es für mich nicht selbstverständlich, etwas zu tippen . Sie haben natürlich Recht - aktualisiert.Python - Score
6664Dies ist die Gleichung für einen Ripple-Addierer. C ist der Carry. Es wird bitweise berechnet: In jeder Iteration wird der Übertrag nach links weitergegeben. Wie von @Orby hervorgehoben, wurde die ursprüngliche Version nicht modular erweitert. Ich habe es behoben und auch einen Zyklus in der Iteration gespeichert, da der erste Übertrag immer Null ist.
quelle
s(255,2)
kehrt257
eher zurück als1
). Sie können dies korrigieren, indem Sie Ihre letzte Zeile ändern, zureturn ~(~xxor(axb,C)|256)
der 3 Punkte hinzugefügt werden.C ++ - Punktzahl: 113
quelle
add(1, 255)
gibt für mich 128 zurück, @Ryan.%
ist nicht auf der Liste der zugelassenen Betreiber, nämlich~
,|
,>>
, und<<
. Vielleicht durch ersetzenands(x8|y8, 255)>>1
?~(~x8 | y8 | 0xFFFFFF00)
würde man den Trick mit nur 4+ schön zu Ihrem Ergebnis machen.byte
anstattint
ihn zu erstellen?