3.7.20 · D4Algorithm Paradigms

Exercises — Bit manipulation — XOR tricks, LSB, counting set bits

2,822 words13 min readBack to topic

Level 1 — Recognition

These just ask you to read binary and evaluate one operator. No cleverness yet.

Recall Solution L1·Q1

Each contributes its place value. Reading right to left the switches are at places : The LSB is the rightmost bit, here a , worth . Answer: , LSB .

Recall Solution L1·Q2

Line them up (, ):

  1100   (12)
  1010   (10)
  • AND keeps a only where both are : column (), column (), (), () → .
  • OR keeps a where either is .
  • XOR keeps a only where they differ: same , differ , differ , same . Answers: (a) , (b) , (c) .
Recall Solution L1·Q3

Left shift by multiplies by ; right shift divides (floor): Answers: and .


Level 2 — Application

Now run the standard tricks from the parent note.

Recall Solution L2·Q1

XOR the whole list; pairs cancel (self-inverse law ): Running left to right if you prefer: , , , . Answer: 5.

Recall Solution L2·Q2

. Its lowest set bit sits at place . The identity from the parent note is where is the lowest set position, so the answer is . Check via two's complement (-bit picture, = flip , add ):

  10100   ( 20)
  01100   (-20)
& -----
  00100   =  4

Answer: 4.

Recall Solution L2·Q3

. Each step kills one :

  • → count
  • → count
  • → count
  • → count , loop ends. Answer: 4 set bits (indeed has four s).

Level 3 — Analysis

Explain why, and find where it breaks.

Recall Solution L3·Q1

A power of two has exactly one switch on: .

  • () If then , i.e. the single became and everything below became . ANDing (only bit set) with (bit clear) gives .
  • () If has two or more set bits, let the lowest be at place and some higher bit at place . Subtracting flips bit and the zeros below it, but leaves the high bit untouched. So still has bit set → not . Hence the AND is exactly for one-bit numbers, i.e. powers of two. (See Logarithms and Powers of Two.) Note: the condition matters — for , too, yet is not a power of two, which is why the full test is x != 0 && (x & (x-1)) == 0.
Recall Solution L3·Q2

Write splitting off its lowest set bit at place : Two's complement . Flipping , then . The "" ripples through the trailing s of and stops at place , planting a there while re-clearing everything below and inverting every high bit. AND the two:

  1100   ( x)
  0100   (-x)
& ----
  0100   = 4 = 2^2

High bits cancel (a bit AND its inverse ), the lowest bit aligns (), trailing stay . The construction forces the match at the lowest set position — never the highest.

Recall Solution L3·Q3

XOR only cancels in pairs (even counts → ). Here appears an odd number (three) times, so it does not vanish: The result is neither the lone value nor — the trick is invalid when repeats aren't even. Fix for "all appear thrice except one": count each bit position modulo (see L4·Q2). Answer: no — plain XOR gives , not .


Level 4 — Synthesis

Combine tricks into a new algorithm.

Recall Solution L4·Q1

Let the two loners be and . Step 1 — collapse to their XOR. XOR everything; the pairs die, leaving Here . So . Step 2 — find a bit where they differ. Since , has at least one bit. Isolate the lowest one with : This bit is in exactly one of and in the other — a perfect splitter. Step 3 — split the array by that bit and XOR each group. Elements whose bit is set: [2, 3, 2]. Elements whose bit is clear: [1, 1, 5]. Within each group the paired numbers still cancel, so each group's XOR is one loner. Answer: , (either order). Check: ✓.

Recall Solution L4·Q2

XOR fails (L3·Q3), so count bits modulo 3. For each bit position , add up how many of the numbers have that bit set; if the total is not a multiple of , the lone number has that bit. , .

  • place : set in the three s → total , → loner's bit .
  • place : set in the three s → total → loner's bit .
  • place : set only in → total , → loner's bit 1. Rebuild: only is on → . Answer: 8. (This generalises the parity idea from "mod 2" to "mod 3.")
Recall Solution L4·Q3

XOR all indices/values of the full range with all array elements; every present number cancels with its twin in the range, leaving the absent one: Range part: . Array part: . Answer: 2 (indeed is missing from ).


Level 5 — Mastery

Edge cases, negatives, and zero — the scenarios that silently break naive code.

Recall Solution L5·Q1

in two's complement is still (flip all bits of → all s ; add ). So . There is no set bit to isolate, and the trick correctly returns . Practical rule: always guard "lowest set bit" logic with a check for , since is the one input with no lowest set bit. Answer: 0.

Recall Solution L5·Q2

In 8-bit, , so (flip → , add ). Then . AND:

  11110100   (-12)
  00001100   ( 12)
& --------
  00000100   = 4 = 2^2

The identity holds for negatives too: it still returns the lowest set bit's place value, here . Answer: 4 — the sign doesn't matter, only the trailing-zero count does.

Recall Solution L5·Q3

in two's complement is all ones: . So it has 32 set bits. Brian Kernighan's loop x &= x-1; count++ clears one per iteration, so it runs exactly times before hitting . (This is why popcount of equals the word width — a classic sanity check for signed inputs.) Answer: 32.

Recall Solution L5·Q4

. An arithmetic right shift copies the sign bit in from the left: . Here too, so they agree. But the general warning stands: arithmetic shift rounds toward . E.g. , , whereas language division (rounds toward ). They differ. Answer: , which happens to equal ; the mismatch shows up for odd negatives.


Recall Feynman check — say it to a friend

XOR keeps only what shows up an odd number of times (flip a switch twice and it's untouched). When two things are odd, first XOR everything to get their difference, then use x & -x to find one bit where they disagree and sort the room into two piles — each pile now has a single odd one out. For "appears three times," switch from counting parity (mod 2) to counting mod 3. And whenever a minus sign or a zero shows up, stop and picture the fixed-width switch row.

Connections

  • Parent: XOR / LSB / popcount
  • Two's Complement Representation — every negative-number exercise (L2·Q2, L5·Q2–Q4).
  • Hash Sets vs O(1)-space tricks — the memory-vs-cleverness tradeoff behind L3/L4.
  • Logarithms and Powers of Two — the power-of-two test (L3·Q1).
  • Bitmask Dynamic Programming — where these subset/bit tools reappear.
  • Greedy and Divide-and-Conquer — splitting the array in L4·Q1 is a divide step.