Le défi
Implémentez une fonction qui accepte deux entiers dont les valeurs vont de 0 à 255 et renvoie la somme de ces entiers mod 256. Vous ne pouvez utiliser que la négation au niveau du bit (~), au niveau du bit ou (|), des opérateurs de décalage de bit (>>, <<) et affectation (=).
Les choses que vous ne pouvez pas utiliser incluent (mais ne sont pas limitées à)
- Addition, soustraction, multiplication et division
- Boucles
- Expressions conditionnelles
- Appels de fonction
Les utilisations les moins nombreuses des opérations binaires ou de négation binaire et de décalage de bits l'emportent . En cas d'égalité, la solution la plus populaire l'emporte. Comme toujours, les failles standard s'appliquent.
Voici un exemple d'un simple additionneur 2 bits. Il utilise 77 négations binaires, 28 or binaires et 2 décalages binaires pour un score total de 107 (cela peut être vu en exécutant le préprocesseur C avec gcc -E
). Il pourrait être rendu beaucoup plus efficace en supprimant les #define
s et en simplifiant les expressions résultantes, mais je les ai laissées pour plus de clarté.
#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));
}
}
}
}
Mise à jour: ajout d'un exemple et modification des critères de notation
Réponses:
Python, 36 opérations
Une méthode logarithmique dans le paramètre "8"!
L'idée est de savoir quels indices débordent et quelle cause porte. Au départ, ce sont juste les endroits où les deux
a
anddb
ont un1
. Mais étant donné que les bits transportés peuvent provoquer des chevauchements supplémentaires, cela doit être déterminé de manière itérative.Plutôt que de déborder chaque index dans le suivant, nous accélérons le processus en déplaçant 1 index, puis 2 indices, puis 4 indices, en étant sûr de se souvenir des endroits où un débordement s'est produit (H) et où un débordement ne peut plus se produire (K ).
Une solution itérative plus simple avec 47 opérations:
Banc d'essai, pour quiconque souhaite le copier.
la source
C - 0
Il utilise des opérateurs en dehors de ~, |, >>, << et =, mais je vois des solutions utilisant des opérateurs de transtypage et de virgule, donc je suppose que la règle n'est pas trop stricte à condition qu'elle n'utilise pas les opérateurs interdits.
la source
python, score =
8380Déroulez la boucle. C'est 10 opérations par boucle fois 7 boucles, 7 pour le dernier xor et 3 pour écraser le 9e bit à la fin.
Implémente l'équation
x+y = x^y + 2*(x&y)
en la répétant 8 fois. Chaque fois, il y a un bit zéro de plus en bas dey
.la source
C, score:
7760Golfé juste pour l'enfer,
206169131 octets:Étendu:
Essentiellement la même solution (mathématiquement) que
@KeithRandall@JuanICarrano aproposée, mais tire parti de la capacité de C à jouer rapidement et librement avec des types variables et des pointeurs pour tout effacer après les 8 premiers bits sans utiliser plus d'opérateurs.Dépend de l'endian-ness de la machine et de la taille de () un int et un char, mais devrait pouvoir être porté sur la plupart des applications spécifiques à la machine avec le calcul de pointeur approprié.
EDIT: C'est un défi que C (ou d'autres langages de bas niveau) aura un avantage distinct - à moins que quelqu'un ne propose un algorithme qui n'a pas à porter.
la source
unsigned char
. C'est plus propre et plus portable.unsigned
ne me vient pas naturellement dans le golf de code. Vous avez bien sûr raison - mis à jour.Python - Score
6664C'est l'équation pour un additionneur ondulé. C est le portage. Il est calculé un bit à la fois: à chaque itération le report se propage à gauche. Comme l'a souligné @Orby, la version originale n'a pas fait d'ajout modulaire. Je l'ai corrigé et j'ai également enregistré un cycle dans l'itération, car le premier report est toujours nul.
la source
s(255,2)
retourne257
plutôt que1
). Vous pouvez corriger cela en modifiant votre dernière ligne,return ~(~xxor(axb,C)|256)
ce qui ajoute 3 points.C ++ - score: 113
la source
add(1, 255)
retourne 128 pour moi, @Ryan.%
ne figure pas sur la liste des opérateurs autorisés, à savoir~
,|
,>>
, et<<
. Peut-être le remplacer parands(x8|y8, 255)>>1
?~(~x8 | y8 | 0xFFFFFF00)
ferait bien l'affaire avec seulement 4+ pour votre score.byte
au lieu de leint
ferait-il déborder automatiquement?