Convert Integer to Non-Adjacent Form
Company: Salesforce
Role: Software Engineer
Category: Coding & Algorithms
Difficulty: Medium
Interview Round: Take-home Project
Quick Answer: Convert Integer to Non-Adjacent Form evaluates algorithm design, data structures, correctness, complexity, edge cases, and implementation details in a realistic interview setting. A strong answer states assumptions, handles edge cases, explains trade-offs, and shows how to validate the result clearly.
Convert Integer to Non-Adjacent Form (toNAF)
Constraints
- n may be any integer, positive, negative, or zero.
- Digits returned are exactly from the set {-1, 0, 1}.
- No two adjacent returned digits are both nonzero.
- Output is least-significant-digit first.
- By convention toNAF(0) returns [0].
Examples
Input: (0,)
Expected Output: [0]
Explanation: Zero is the base case; NAF(0) is defined as [0].
Input: (1,)
Expected Output: [1]
Explanation: 1 is odd, 1 mod 4 = 1 so z=+1; after subtracting, value is 0. Single digit 1.
Input: (7,)
Expected Output: [-1, 0, 0, 1]
Explanation: 7 = 8 - 1 = 2^3 - 2^0, so the NAF is (-1)·1 + 0·2 + 0·4 + 1·8 = 7 with only two nonzero digits instead of three ones in 0b111.
Input: (3,)
Expected Output: [-1, 0, 1]
Explanation: 3 = 4 - 1: digits give -1 + 0·2 + 1·4 = 3, replacing binary 11 (weight 2) with the same weight but non-adjacent form.
Input: (-7,)
Expected Output: [1, 0, 0, -1]
Explanation: -7 = -8 + 1 = 1·1 + 0·2 + 0·4 + (-1)·8. Negative inputs are handled directly by floor division.
Input: (2,)
Expected Output: [0, 1]
Explanation: 2 is even: emit 0, halve to 1, which emits 1. Result 0·1 + 1·2 = 2.
Input: (15,)
Expected Output: [-1, 0, 0, 0, 1]
Explanation: 15 = 16 - 1 = 2^4 - 2^0: four binary ones collapse to two nonzero NAF digits.
Input: (1073741823,)
Expected Output: [-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]
Explanation: 2^30 - 1 (thirty binary ones) compresses to exactly two nonzero NAF digits: -2^0 + 2^30, demonstrating the large-magnitude minimal-weight property.
Hints
- Process the number bit by bit from the least-significant end, like ordinary binary conversion but allowing the digit -1.
- When the current value is odd, you must emit -1 or +1. Pick whichever makes the value divisible by 4 after subtracting it — that forces the very next digit to be 0.
- The clean formula for the odd case is z = 2 - (n mod 4): it gives +1 when n ≡ 1 (mod 4) and -1 when n ≡ 3 (mod 4). Subtract z, then integer-divide by 2.
- Floor division (Python //, which rounds toward -infinity) makes the negative case work without special handling.
Convert Non-Adjacent Form Back to Integer (fromNAF)
Constraints
- Each digit is from {-1, 0, 1}.
- Input is least-significant-digit first (matching toNAF's output order).
- An empty list represents the integer 0.
- Must be the exact inverse of toNAF: fromNAF(toNAF(n)) == n for all n.
Examples
Input: ([0],)
Expected Output: 0
Explanation: A single zero digit decodes to 0, matching toNAF(0).
Input: ([1],)
Expected Output: 1
Explanation: One digit of value 1 at position 0 gives 1·2^0 = 1.
Input: ([-1, 0, 0, 1],)
Expected Output: 7
Explanation: (-1)·1 + 0·2 + 0·4 + 1·8 = -1 + 8 = 7, the inverse of toNAF(7).
Input: ([-1, 0, 1],)
Expected Output: 3
Explanation: (-1)·1 + 0·2 + 1·4 = -1 + 4 = 3.
Input: ([1, 0, 0, -1],)
Expected Output: -7
Explanation: 1·1 + 0·2 + 0·4 + (-1)·8 = 1 - 8 = -7, showing negative reconstruction.
Input: ([0, 1],)
Expected Output: 2
Explanation: 0·1 + 1·2 = 2.
Input: ([],)
Expected Output: 0
Explanation: Empty digit list is the convention for 0; the loop never executes.
Input: ([-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],)
Expected Output: 1073741823
Explanation: -2^0 + 2^30 = 1073741824 - 1 = 1073741823, the exact round-trip of toNAF(2^30 - 1).
Hints
- The value is just sum(digits[i] * 2**i); the non-adjacency property is not needed to decode.
- Use Horner's rule from the most-significant digit (the last element) down: value = value*2 + digit. This avoids computing powers of two explicitly.
- Walking the list in reverse keeps the accumulator exact even when some digits are -1.
- Handle the empty list as 0 — the loop body simply never runs.