Coding questions
Check if a numeric string is divisible by 8
Determine whether a very large non-negative integer given as a decimal string is divisible by 8 without converting the whole string to an integer. The key insight is that only the last three digits matter (since 1000 is a multiple of 8), giving an O(1) check; a streaming modular-remainder approach is the O(n) alternative.
Question
You are given a very large non-negative integer represented as a decimal string s (it may be too large to fit in standard 64-bit integer types).
Write a function that returns True if the number represented by s is divisible by 8, otherwise return False.
Constraints / Requirements
- Do not convert the entire string to an integer type (e.g., no
int(s)). 1 <= len(s) <= 10^6.sconsists only of digits'0'–'9'.- Leading zeros may exist (e.g.,
"00016").
Examples
s = "16"→Trues = "123"→Falses = "1000"→True
Numeric String Divisible by 8
Return whether a very large non-negative decimal string is divisible by 8 without converting the whole string.
Hints
- A decimal integer is divisible by 8 iff its last three digits are divisible by 8.
Solution
Because 1000 is a multiple of 8, only the last three digits of the number affect divisibility by 8. The clean O(1) approach is to parse just the final three characters and test % 8 == 0; this respects the no-full-conversion constraint. A streaming Horner's-method remainder (running r = (r*10 + digit) % 8) is the O(n)/O(1)-space alternative that avoids large integers entirely and generalizes to any divisor. Both correctly handle leading zeros and strings shorter than three digits.
Key idea (divisibility rule for 8)
A number is divisible by 8 if and only if the number formed by its last three digits is divisible by 8. This works because 1000 = 8 × 125, so every digit at position 1000 or higher contributes a multiple of 1000 (hence a multiple of 8) and can be ignored. We never need to read more than the final three characters of the string.
The usual cases:
- If
len(s) <= 3: parse the whole (short) string as an integer and check% 8 == 0. This is safe — it's at most a 3-digit number. - Otherwise: take the last 3 characters, parse just those (a tiny integer in
0..999), and check divisibility by 8. Leading zeros in that 3-char slice are harmless becauseint("016") == 16.
We deliberately parse only up to 3 characters, so we never violate the "don't convert the full string" constraint, and the work is O(1) regardless of the input length (up to 10^6 digits).
Python
def divisible_by_8(s: str) -> bool:
# Only the last (up to) 3 digits matter, because 1000 is divisible by 8.
last3 = s[-3:]
return int(last3) % 8 == 0
s[-3:] already handles strings shorter than 3 characters (it just returns the whole string), and int("016") correctly yields 16, so leading zeros need no special handling.
Alternative: streaming modular arithmetic (no slicing, no large int)
If the interviewer wants you to avoid even constructing a 3-character integer, process the string left to right keeping a running remainder mod 8. Horner's method keeps the accumulator small:
def divisible_by_8(s: str) -> bool:
r = 0
for ch in s:
r = (r * 10 + (ord(ch) - ord('0'))) % 8
return r == 0
This is O(n) time, O(1) space, and never forms a big integer. The last-three-digits version is preferred when allowed because it is O(1), but the streaming version generalizes to any divisor and is good to mention.
Worked examples
"16"→16 % 8 == 0→True"123"→123 % 8 == 3→False"1000"→ last 3 ="000"→0 % 8 == 0→True"00016"→ last 3 ="016"→16 % 8 == 0→True