Math & Geometry

Mediummath · geometry · number theory · overflow · hashing⏱ 6 min readUpdated

A toolkit of number-theory and coordinate-geometry tricks - digit peeling, gcd, counting prime factors, squared distances, cross products and normalised slopes - that replaces brute force with exact integer math.

PatternMath & Geometry

Instinct Digits, factors, slopes or distances hide a formula - find the invariant, then guard against overflow, negatives and floating-point error.

Memory hack Mod peels, gcd reduces, squares compare - and long saves the day. Peel digits with %10, reduce slopes with gcd, compare squared distances.

At a glance

When to use it

  • The problem works on the digits of a number, its factors, or a formula like pow, gcd or modulo
  • You must stay within 32-bit range or return 0 on overflow
  • Points in the plane must be checked for distances, shapes, slopes or collinearity
  • A brute force would build huge numbers like n! or compare floating-point values

Key idea

Find the invariant (a digit pattern, a count of prime factors, a reduced slope, a shared midpoint) and do exact integer arithmetic on it; this avoids huge intermediates and float errors and usually cuts the work to O(log n) for numbers or O(n^2) for point sets.

Typical complexity

O(log n) time for digit or factor work, O(n^2) for point pairs, O(1) to O(n) space

How to spot it If the problem says "reverse the digits", "trailing zeros", "points on the same line" or "form a square" and asks for an exact count or check, think Math & Geometry first.

The instinct

These problems look like puzzles but are usually one observation plus careful arithmetic. The observation is a property that survives the operations (a digit pattern, a count of prime factors, a slope, a midpoint). The arithmetic is where candidates lose points: 32-bit overflow, Java's negative remainders, and floating-point keys. The winning habit is to stay in integers for as long as possible: compare squared distances, store slopes as reduced fractions, and check overflow before multiplying.

Recognise it

Signal in the problem Why it points here
"Reverse the digits", "is it a palindrome without converting to string" (Reverse Integer, Palindrome Number) Peel digits with % 10 and / 10, check overflow each step
"Assume a 32-bit signed environment", "return 0 on overflow" The test is your overflow guard, not the loop
"Number of trailing zeros in n!" (Factorial Trailing Zeroes) Count factors of 5 instead of computing n!
"Do these 4 points form a square?" (Valid Square) Squared pairwise distances; no square roots
"Maximum number of points on the same line" (Max Points on a Line) Normalised slope as a hash key from each anchor point
"Minimum area rectangle, sides not necessarily axis-parallel" (Minimum Area Rectangle II) Diagonals share a midpoint and length - group pairs by that
"Pow, sqrt, gcd, lcm, prime, modulo 1e9+7" Fast exponentiation, binary search on the answer, Euclid, sieve

Not this pattern if...

  • The "math" is really counting arrangements with overlapping subproblems - that is DP or combinatorics.
  • Points are only used as graph nodes (e.g. Min Cost to Connect All Points) - it is MST / graph.
  • You need the k closest points - squared distance helps, but the pattern is a heap or quickselect.

Memory hack

Tip

Mod peels, gcd reduces, squares compare - and long saves the day. - % 10 peels the last digit, / 10 drops it. - gcd turns a slope dy/dx into a canonical fraction you can hash. - Squared distances avoid sqrt and keep everything exact. - When in doubt, widen to long before the multiply, not after.

Analogy: a carpenter measures twice and cuts once. Do the reasoning on paper (invariant), then do arithmetic only with exact tools (integers) - a floating-point ruler drifts.

Say it out loud in the interview:

  1. "What stays the same / what am I really counting?" (factors of 5, equal slopes, shared midpoints)
  2. "Can every value fit in int? Where could it overflow or go negative?"
  3. "Edge cases: zero, negatives, Integer.MIN_VALUE, duplicate points, vertical lines."

How it works

Decide which tool from the problem's nouns:

flowchart TD
    A["Read the nouns"] --> B{"Digits of a number?"}
    B -->|"yes"| C["Peel with mod 10 and div 10, overflow check before multiply"]
    B -->|"no"| D{"Divisibility, factorial, primes?"}
    D -->|"yes"| E["Count prime factors, gcd or sieve; never build huge numbers"]
    D -->|"no"| F{"Points in the plane?"}
    F -->|"distances or shapes"| G["Squared distances, cross product, midpoints"]
    F -->|"collinear"| H["Slope as reduced dy/dx key per anchor point"]
    F -->|"no"| I["Look for a formula: sums, powers, binary search on answer"]

Two quick traces:

  • Factorial Trailing Zeroes, n = 100: multiples of 5 contribute 20 fives, multiples of 25 contribute 4 more, 125 > 100 stops. Answer 24, without ever touching 100!.
  • Max Points on a Line: from anchor (1,1), the points (2,2), (3,3) and (-1,-1) give dy/dx = 1/1, 2/2, -2/-2, which all reduce (sign normalised) to "1/1", so they land in one bucket.

Java template

java
class MathKit {
    // Reverse digits, returning 0 if the result leaves 32-bit range.
    static int reverse(int x) {
        int r = 0;
        while (x != 0) {
            int digit = x % 10;               // negative for negative x - that's fine here
            x /= 10;
            if (r > Integer.MAX_VALUE / 10 || (r == Integer.MAX_VALUE / 10 && digit > 7)) return 0;
            if (r < Integer.MIN_VALUE / 10 || (r == Integer.MIN_VALUE / 10 && digit < -8)) return 0;
            r = r * 10 + digit;
        }
        return r;
    }

    static int gcd(int a, int b) { return b == 0 ? Math.abs(a) : gcd(b, a % b); }

    // base^exp % mod in O(log exp).
    static long powMod(long base, long exp, long mod) {
        long result = 1 % mod;
        base %= mod;
        if (base < 0) base += mod;            // Java remainders can be negative
        while (exp > 0) {
            if ((exp & 1) == 1) result = result * base % mod;
            base = base * base % mod;
            exp >>= 1;
        }
        return result;
    }

    // Count of prime factor p in n! (p = 5 gives trailing zeros).
    static long factorInFactorial(long n, long p) {
        long count = 0;
        while (n > 0) { n /= p; count += n; }
        return count;
    }
}

class GeoKit {
    static long dist2(int[] a, int[] b) {
        long dx = a[0] - b[0], dy = a[1] - b[1];
        return dx * dx + dy * dy;             // exact, no sqrt
    }

    // > 0: o->a->b turns left, < 0: right, 0: collinear.
    static long cross(int[] o, int[] a, int[] b) {
        return (long) (a[0] - o[0]) * (b[1] - o[1]) - (long) (a[1] - o[1]) * (b[0] - o[0]);
    }

    // Canonical slope key between two distinct points.
    static String slopeKey(int[] a, int[] b) {
        int dx = b[0] - a[0], dy = b[1] - a[1];
        if (dx == 0) return "inf";            // vertical line
        if (dy == 0) return "0";              // horizontal line
        int g = MathKit.gcd(dx, dy);
        dx /= g; dy /= g;
        if (dx < 0) { dx = -dx; dy = -dy; }   // one sign convention
        return dy + "/" + dx;
    }
}

Complexity

Task Time Space
Digit peeling (reverse, palindrome) O(number of digits) = O(log n) O(1)
Factor counting in n! O(log_p n) O(1)
gcd / fast power O(log n) O(1)
Valid Square (6 pair distances) O(1) O(1)
Max Points on a Line (slope map per anchor) O(n²) O(n)
Minimum Area Rectangle II (group pairs by midpoint + length) O(n²) pairs, plus pairs within each group O(n²)

Variations

  • Digit manipulation - peel, rebuild, compare halves; reverse only half of the number to dodge overflow. Palindrome Number, Reverse Integer, Add Digits.
  • Factor and divisor counting - count the limiting prime instead of forming the product. Factorial Trailing Zeroes, Count Primes (sieve).
  • Fast operators - exponentiation by squaring, binary search for roots. Pow(x, n), Sqrt(x).
  • Shape checks with distances - sort the 6 squared distances: 4 equal non-zero sides and 2 equal larger diagonals. Valid Square.
  • Collinearity / slopes - reduced-fraction keys or cross product = 0. Max Points on a Line.
  • Rectangles from diagonals - pairs with the same midpoint and length are diagonals of one rectangle. Minimum Area Rectangle II.
  • Overlap tests - axis-aligned rectangles overlap when they overlap on both axes. Rectangle Overlap, Rectangle Area.

Common mistakes

  • Math.abs(Integer.MIN_VALUE) is still negative; widen to long first or avoid abs on raw input.
  • Java's % keeps the sign of the dividend (-7 % 10 == -7); normalise with ((x % m) + m) % m for modular math.
  • Forgetting degenerate inputs: duplicate points in Valid Square (zero-length side), duplicate points in Max Points on a Line (they match every slope).
  • Multiplying two int coordinates before casting - (long) (a * b) overflows first; write (long) a * b.
  • Computing a huge intermediate (n!, a^b) instead of counting factors or reducing modulo as you go.
Warning

Never use a double slope as a hash key. 0.0 and -0.0 are different keys, 1/3 is not exactly representable, and vertical lines give infinity. Store slopes as a reduced (dy, dx) pair with one sign convention.

All practice problems

6 problems on this site use this pattern, easiest first. Solve them in order and say the instinct out loud before you code.

My notes saved in this browser