Paix et prospérité avec les doigts-qui-se-collent-sauf-au-milieu, mes amis.
Aujourd’hui, un article de super-geek qui vous servira à rien. Je vais vous faire découvrir les différentes façons rigolotes pour
Échanger
les valeurs
de deux
variables.
De base:
Vous avez deux variables numériques (A et B). Vous voulez que A prenne la valeur de B et versa-vice. Comme vous êtes pas trop con mais un peu quand même, vous déduisez qu’il faut utiliser une variable intermédiaire « C », et faire un truc comme ça:
C <- A
A <- B
B <- C
Ça s’appelle une permutation circulaire, ou une connerie de ce genre.
Pour les atrophiés de l’hypothalamus, la flèche « <- » signifie « prend la valeur de ». Par exemple, pour la 1ère ligne ça donne: « C prend la valeur de A ». C = A quoi. (C & A, des soldes à petits prix). Mais le signe égale est dans le sens affectation, pas égalité. C’est pas le « == » des conditions en langage C (& A). Ahh, au secours, tuez mon cerveau. Tuez mon cerveau. Bon, le mieux c’est que vous laissiez tomber cet article et que vous alliez aux putes.
La permutation circulaire c’est rigolo, mais cette variable intermédiaire, elle sert pas à grand chose, et elle prend de la mémoire. On n’a pas que ça à foutre quand on est un microprocesseur over-booké par le téléchargement de tera-octets de p0rn via Bite-Torrent. Il faut donc avoir recours à une astuce rigolote:
Échange à l’aide d’additions et de soustractions:
Voici comment échanger A et B, sans utiliser de troisième variable:
A <- A – B
B <- A + B
A <- B – A
Au lieu de simples affectations, on a des additions et des soustractions. Mais pour un ordinateur, c’est aussi rapide, ça prend juste un cycle d’horloge. Enfin on suppose que oui.
Bon, là comme ça on pige que dalle. Je vous le réécris avec des indices.
A2 <- A1 – B1
B2 <- A2 + B1
A3 <- B2 – A2
Si on remplace le B2 dans la dernière ligne, ça donne:
A3 <- (A2 + B1) – A2
A3 <- B1
A3 prend la valeur initiale de B
Et si on remplace le A2 dans la deuxième ligne, ça donne:
B2 <- (A1 – B1) + B1
B2 <- A1
B2 prend la valeur initiale de A
Youpi ça marche.
Bon, le seul problème, c’est que si A et B sont des pointeurs sur la même zone mémoire, ça foire complètement. (A et B se modifient en même temps, et boum). Mais dans ce cas, faudrait être con pour vouloir échanger A et B, vu que ça servirait à rien.
Ah et ça peut merder avec des histoires d’overflow aussi. Bref, c’est fun, mais pas tant que ça. il y a mieux.
Échange à l’aide de XOR
Le XOR (« ou » exclusif) est une opération logique entre deux valeurs binaires. Le résultat vaut 1 si l’un des deux opérandes vaut 1. Voyez-vous cela:
0 XOR 0 = 0
0 XOR 1 = 1
1 XOR 0 = 1
1 XOR 1 = 0
Fun fact : x XOR y = (x AND NOT(y)) OR (NOT(x) AND y)
Hahaha.
Autre fun fact : x XOR y = (x est différent de y). Si x et y sont différents, on obtient 1. S’ils sont égaux, on obtient 0.
Et donc, pour échanger A et B, on claque ceci:
A <- A XOR B
B <- A XOR B
A <- A XOR B
Petite précision: le XOR entre deux valeurs numériques, c’est comme le XOR binaire. On applique l’opération « bit à bit ». Mais vous l’aviez compris par vous-même, bien entendu.
Vous pouvez vérifier en mettant des petits 0 et des petits 1 à la place des A et B, et tester tous les cas possibles, ça marche. Si je puis me permettre, je vais faire une démonstration un peu plus élégante.
On remet des indices pour pas se paumer.
A2 <- A1 XOR B1
B2 <- A2 XOR B1
A3 <- A2 XOR B2
En remplaçant le B2 dans la dernière ligne, ça donne:
A3 <- A2 XOR (A2 XOR B1)
le XOR est une opération associative, ça veut dire qu’on peut faire toutes les conneries qu’on veut avec les parenthèses, à condition de pas changer l’ordre des variables. Sauf qu’en fait on pourrait aussi changer l’ordre parce que le XOR est également commutatif, figurez-vous. Mais on s’en branle.
Bref:
A3 <- (A2 XOR A2) XOR B1
Quand on XORifie un truc avec lui-même, ça donne systématiquement 0. (Rappelez-vous ce que j’ai dit au début, bande de moules rachitiques).
Donc:
A3 <- 0 XOR B1.
Et quand on XORifie un truc avec 0, ça redonne le truc lui-même. Ainsi soit-il.
Paf, on retombe sur le même genre de situation rigolote qu’avec les additions et soustractions:
A3 <- B1. (A3 prend la valeur initiale de B)
Pour le B, ça fait pareil.
Je reprends ma deuxième ligne, et je remplace le A2:
B2 <- (A1 XOR B1) XOR B1
plop plop associativité
B2 <- A1 XOR (B1 XOR B1)
plop plop: un XOR avec deux fois le même truc ça donne 0
B2 <- A1 XOR 0
plop plop XORifier du 0 ça fait rien du tout.
B2 <- A1
B2 est égal à la valeur initiale de A. Yii haaaaa.
Voili voilà. Et l’avantage, c’est que là, pas d’overflow à la con. Un XOR c’est un XOR, ça chie pas partout comme un chien incontinent qu’aurait fait une overdose de jus de pruneau.
Par contre, y’a toujours le problème que si A et B sont des pointeurs sur la même zone mémoire, ça vous pète à la gueule. Mais, comme dit précédemment, faut vraiment être con pour vouloir échanger les valeurs d’une zone mémoire avec elle-même. Oui oui, ça sert à rien.
Le langage python
Le Python c’est super rigolo. On peut faire plein de trucs super pratiques et super pas prise de tête que y’a pas dans les autres langages, tel qu’utiliser des variables sans les déclarer, parce que bordel de merde ça suffit de nous prendre pour des gamins, on est capable de programmer sans avoir à être surveillé par l’ordinateur. On n’est pas des taffioles, foutrefoutre.
En python, pour échanger les valeurs de A et B, vous devez écrire:
A, B = B, A
Une remarque pertinente? Quelqu’un? Non? Bon.
Concrètement
J’peux te l’dire, matelot, depuis plus de 15 ans, je bourlingue mes yeux globuleux de geek sur des dizaines de machines, de langages, de projets professionnels, et de réalisations personnelles. Et partout, depuis les space invaders codés en Pascal jusqu’aux contrôleurs de générateurs automatiques de planche de code pour tondeuses à gazon, codés en C panaché de macros bien crades, en passant par les piloteurs d’étalonneurs d’étalons de compteur électrique, codés en Visual Basic par des troupeaux de chimpanzés immortels, j’ai jamais JAMAIS eu besoin d’échanger les valeurs de deux variables! C’est un truc trop bizarre pour que t’en aies besoin dans le monde réel. La seule fois où ça m’est arrivé, c’était un exo d’informatique durant mes études, et j’étais même pas bourré. Ouais matelot, nos profs aimaient bien nous apprendre des trucs qui servent à rien. Un peu comme cet article d’ailleurs.
Vous pouvez donc oublier tout ce que j’ai écrit ici. Et plutôt que de vous faire chier à échanger des variables, concentrez-vous plutôt sur la mignonne Keisha Evans, qui essaie de mettre son nichon droit à la place de son nichon gauche. (Mais elle a un peu de mal).
Et ça c’est gratuit:
Selon vous, de quelle personne s’agit-il? (Réponse dans les commentaires)
Vous en voulez encore bande de petits pervers?
Je savais bien que les astuces à la con d’optimisation de code finiraient par vous exciter. En voici plein d’autres (http:// graphics.stanford.edu/~seander/bithacks.html).
Vous pourrez y découvrir comment choper la valeur absolue d’un nombre sans faire de branchement conditionnel, ou comment inverser des bits. Allez, sautez dedans bande de petits canaillous! Moi je vais me coucher.