When you see a problem counting numbers in a range with digit-based constraints, think digit DP. The pattern:
Convert the limit to a string (base ) or binary.
State: where extra depends on the constraint.
Transition: try each valid digit, update state, recurse.
Base case: return when you've placed all digits (and satisfied constraints). Common extra states: bitmask (distinct digits), running sum (digit sum), remainder (divisibility), previous digit (adjacency constraints).