Bonjour!
je suis confronté à un petit probleme mathématique pour un défi que m'a proposé un copain en informatique, le défi est de faire un reverse_bits (je vais expliquer) en moins de 80 caracteres en C.
Le reverse bits consiste à inverser tout les bits (0 ou 1, c'est du binaire) d'une variable qui en possede 8,
exemple : 10001100 donnera 00110001 apres inversion.
pour réussir ce défi, je dois trouver la logique de cette suite, mais je bloque voici le début de la suite en transformant le binaire en décimal :
1 -> 128
2 -> 64
3 -> 192
4 -> 32
5 -> 160
6 -> 96
etc...
Si quelqu'un a une idée, je suis tout ouïe!
Une solution simple (et qui peut donner un code court) est d'utiliser une seconde variable. On décale celle-ci vers la gauche en copiant le bit de poids faible de x tout en décalant x vers la droite :
#include <stdio.h>
char reverse_bits(char x) {
char y;
for(int i=0; i<8; i++){
y=(y<<1)|(x&1);
x>>=1;
}
return y;
}
int main(void) {
int x;
scanf("%d", &x);
x = reverse_bits(x);
printf("%d", x);
return 0;
}
char reverse_bits(char x) {
x=((170&x)>>1)|((85&x)<<1);
x=((204&x)>>2)|((51&x)<<2);
x=((240&x)>>4)|((15&x)<<4);
return x;
}
Merci pour cette réponse, malheureusement j'ai omis de dire plusieurs chose, je connaissais déjà ces solutions effectivement, elles sont assez efficace, mais je suis dans une école où on a une norme à respecter, par exemple des espaces entre les >> et les =, on a meme pas le droit d'utiliser for enfin bref, en fait mon post avait plutot un but mathématique, pas vraiment algorithmique.
Du coup ma vrai question était de savoir s'il existe un U tel que Un donne le reverse_bits n.
salut
bonjour,
j'ai eu la mm réflexion que vous !
mais ensuite j'ai fini par comprendre : on voit comme dans un miroir, à l'envers.
le 1er chiffre en dernier, le second en avant-dernier, etc.
comme je l'ai dis quelque poste plus haut, ce n'est pas de l'informatique, c'est des suites, le but est pas de trouver un algorithme mais de trouver la logique de la suite créer par le renversement binaire d'un nombre
Non verdurin, cela inverse chaque bit mais les laisse au même endroit.
Malheureusement, l'exemple sur le site que tu pointes est plus que malheureux, car il ne permet pas de distinguer les 2 sortes de transformations.
Principe possible (que je n'écris pas en C mais en utilisant les propriétés du C ):
Déclarer B comme byte
Déclarer A comme byte signé
B = 0
Entrer A (nombre à "inverser")
faire 8 boucles (par un for...)
{
B devient (B + B)
si A < 0
{
B devient B+1
}
A devient (A + A)
}
-----
Rappel :
En C, un nombre signé est considéré négatif si son bit de poids fort est 1
et en binaire, multiplier un nombre par 2, décale tous ses bits d'un rang vers la gauche.
Sauf distraction.
Bonjour,
@ J-P : Je ne comprends pas dans l'algorithme ci-avant car dans une des 8 itérations le bit 7 de A est introduit sur le bit 0 de B par le test "si A<0"
mais lors de l'itération suivante, ce bit est décalé vers la gauche par B+B
ainsi, après 8 itérations le B=0 devient le A initial.
Est-ce que j'ai mal interprété ?
Les exemples de Littlefox 27-01-17 à 12:31 avec & (ET), | (OU), >>, << fonctionnent bien
(alors que des ^ (XOR) seraient mal venus) grâce aux décalages dans les deux sens.
Dans mon algo, il y a un *2 au lieu d'un divisé par 2
En voici un autre écrit sur algobox.
VARIABLES
A EST_DU_TYPE NOMBRE
B EST_DU_TYPE NOMBRE
C EST_DU_TYPE NOMBRE
D EST_DU_TYPE NOMBRE
i EST_DU_TYPE NOMBRE
DEBUT_ALGORITHME
LIRE A
B PREND_LA_VALEUR 0
C PREND_LA_VALEUR 128
D PREND_LA_VALEUR 1
POUR i ALLANT_DE 1 A 8
DEBUT_POUR
SI (A >= C) ALORS
DEBUT_SI
B PREND_LA_VALEUR (B + D)
A PREND_LA_VALEUR (A-C)
FIN_SI
D PREND_LA_VALEUR 2*D
C PREND_LA_VALEUR C/2
FIN_POUR
AFFICHER B
FIN_ALGORITHME
Il est un peu différent de l'esprit du précédent, car je ne sais pas sous algobox limiter le nombre à un byte ...
Je n'ai plus d'émulateur en C .
Dans l'algo de mon message précédent, il faut bien entendu entrer un nambre A compris dans [0 ; 255] et en sortie B contient le nombre palyndrome (si on le retranscrit en binaire)
Bonsoir,
L'opération reverse-bits demandée ne demande pas un "palindrome"
exemple : 10001100 donnera 00110001 apres inversion
Pour la logique de la suite, on peut regarder ça récursivement.
Si on prend deux bits, il suffit de les échanger.
00
12
21
33
pour quatre bits on écrit les nombres en base 4, on échange les deux chiffres et on les transforme avec la table ci-dessus.
Par exemple (les bases sont en indices)
116=01410
204=8
D16=31413
234=B16
On obtient ainsi une table de correspondance pour les chiffres hexadécimaux.
Pour un octet on écrit le nombre en hexadécimal, on échange les deux chiffres et on utilise la table précédente pour les transformer.
Par exemple
100011002=8C16C8
3116=001100012
Bonjour,
le problème est que iwan00 semble rechercher l'impossible
une sorte de quête du Graal consistant à trouver une définition plus courte de l'opération "reverse-bits" que :
"échanger les bits de rangs i avec ceux de rangs 7-i"
HS : par ailleurs le palyndrome serait un néologisme concernant la course des grains de pollen ??
char reverse_bits(char x) {
x=((170&x)>>1)|((85&x)<<1);
x=((204&x)>>2)|((51&x)<<2);
x=((240&x)>>4)|((15&x)<<4);
return x;
}
def U(k,n) :
if k == 0 :
return n
b = 2**(2**(k-1))
return b*U(k-1,n%b) + U(k-1,n//b)
def U(m,n):
return U(m>>1,n&((1<<m)-1))<<m|U(m>>1,n>>m)if m else n
Bonjour.
Si la chaîne de caractères est vide, son inverse est une chaîne vide.
Sinon c'est l'inverse de la chaîne amputée de son premier élément, auquel on ajoute le premier élément.
Function reverse(n as str)
if n = "" then
reverse = "
else
reverse = reverse(mid(n, 2,len(n)-1) & left(n,1)
EndFunction
En Lisp :
(De reverse (n)
(If (Not null (n)) (Cons (reverse(Cdr n)) (First n))) )
Vous devez être membre accéder à ce service...
Pas encore inscrit ?
1 compte par personne, multi-compte interdit !
Ou identifiez-vous :