Scramble Number Pair Calculator

Let a pair of distinct positive integers, (i, j), be considered "scrambled" if you can obtain j by reordering the digits of i. For example, (12345, 25341) is a scrambled pair, but (12345, 67890) is not.

Given integers A and B with the same number of digits and no leading zeroes, how many distinct scrambled pairs (i, j) are there that satisfy: A <= i < j <= B?

Example

For instance, if we let A = 10 and B = 99, the answer is 36:

(12,21), (13,31), (14,41), (15,51), (16,61), (17,71), (18,81), (19,91), (23,32), (24,42), (25,52), (26,62), (27,72), (28,82), (29,92), (34,43), (35,53), (36,63), (37,73), (38,83), (39,93), (45,54), (46,64), (47,74), (48,84), (49,94), (56,65), (57,75), (58,85), (59,95), (67,76), (68,86), (69,96), (78,87), (79,97), (89,98)

Think and Solution

public class Test {

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        System.out.println("Input min range: ");
        int min = scanner.nextInt();
        System.out.println("Input max range: ");
        int max = scanner.nextInt();
        System.out.print(scrambleNumberCalculator(min, max));
        Map<Object,Object>  map = new HashMap();

    }

    /**
     * Main function to do the scramble number pair calculation
     * @param minRange  : minimum of range 
     * @param maxRange : maximum of range
     * @return
     */
    public  static long scrambleNumberCalculator(int min, int max) {
        // the total scramble number set to avoid duplicate calculate
        Set<Integer> pairs = new HashSet<>();

        // the result of pairs count;
        long cnt = 0;    
        int[] range = new int[]{min, max};
        for (int i = range[0]; i <= range[1]; i++) {
            if (pairs.contains(i))
                continue;
            Set<Integer> res = new HashSet<>();
            List<Integer> list = convertDigitsList(i);
            permutation(res, list, range, 0, list.size());            
            cnt += combinationPair(res.size());
            // res size equal to one means there is no pair for this number
            // for saving pairs space I don't add the number with no scramble pair.
            if(res.size() > 1)
                pairs.addAll(res);
        }
        // System.out.println(pairs);
        return cnt;
    }

    /**
     * The function to check current number has how many scramble number and store it in a set,
     * recursion without return value but values are recorded in permutation set
     * 
     * @param res: the permutation result storage as a set
     * @param digits: the current number digits for permutation 
     * @param range: the range of output val
     * @param cur: current permutation value
     * @param idx: current permutation index for digits list
     */
    private static void permutation(Set<Integer> res, List<Integer> digits, int[] range,
            int cur, int idx) {
        if (idx == 0) {
            if (cur >= range[0] && cur <= range[1])
                res.add(cur);
            return;
        }
        for (int i = 0; i < digits.size(); i++) {
            // avoid the zero leading number
            if (cur == 0 && digits.get(i) == 0)
                continue;
            cur = cur * 10 + digits.get(i);
            digits.remove(i);
            permutation(res, digits, range, cur, idx - 1);
            digits.add(i, cur % 10);
            cur /= 10;
        }
    }

    /**
     * The function to count the pair amount in permutation set by just using the size of current scramble number set
     * @param num: consider the large input I use long type here
     * @return the amount of pair in current permutation set
     */
    private static long combinationPair(long num) {
        long pairCnt = 0;
        for (int i = 0; i < num - 1; i++)
            for (int j = i + 1; j < num; j++)
                pairCnt++;
        return pairCnt;
    }

    /**
     * The function to convert a number into a list with digits make the permutation more convenient
     * @param num
     * @return
     */
    private static List<Integer> convertDigitsList(int num) {
        List<Integer> res = new LinkedList<>();
        while (num > 0) {
            res.add(0, num % 10);
            num /= 10;
        }
        return res;
    }
}

results matching ""

    No results matching ""