Task: Palindromic gapful numbers


C++: #include <iostream>
#include <cstdint>

typedef uint64_t integer;

integer reverse(integer n) {
    integer rev = 0;
    while (n > 0) {
        rev = rev * 10 + (n % 10);
        n /= 10;
    }
    return rev;
}



class palindrome_generator {
public:
    palindrome_generator(int digit) : power_(10), next_(digit * power_ - 1),
        digit_(digit), even_(false) {}
    integer next_palindrome() {
        ++next_;
        if (next_ == power_ * (digit_ + 1)) {
            if (even_)
                power_ *= 10;
            next_ = digit_ * power_;
            even_ = !even_;
        }
        return next_ * (even_ ? 10 * power_ : power_)
            + reverse(even_ ? next_ : next_/10);
    }
private:
    integer power_;
    integer next_;
    int digit_;
    bool even_;
};

bool gapful(integer n) {
    integer m = n;
    while (m >= 10)
        m /= 10;
    return n % (n % 10 + 10 * m) == 0;
}

template<size_t len>
void print(integer (&array)[9][len]) {
    for (int digit = 1; digit < 10; ++digit) {
        std::cout << digit << ":";
        for (int i = 0; i < len; ++i)
            std::cout << ' ' << array[digit - 1][i];
        std::cout << '\n';
    }
}

int main() {
    const int n1 = 20, n2 = 15, n3 = 10;
    const int m1 = 100, m2 = 1000;

    integer pg1[9][n1];
    integer pg2[9][n2];
    integer pg3[9][n3];

    for (int digit = 1; digit < 10; ++digit) {
        palindrome_generator pgen(digit);
        for (int i = 0; i < m2; ) {
            integer n = pgen.next_palindrome();
            if (!gapful(n))
                continue;
            if (i < n1)
                pg1[digit - 1][i] = n;
            else if (i < m1 && i >= m1 - n2)
                pg2[digit - 1][i - (m1 - n2)] = n;
            else if (i >= m2 - n3)
                pg3[digit - 1][i - (m2 - n3)] = n;
            ++i;
        }
    }

    std::cout << "First " << n1 << " palindromic gapful numbers ending in:\n";
    print(pg1);

    std::cout << "\nLast " << n2 << " of first " << m1 << " palindromic gapful numbers ending in:\n";
    print(pg2);

    std::cout << "\nLast " << n3 << " of first " << m2 << " palindromic gapful numbers ending in:\n";
    print(pg3);

    return 0;
}




Java: import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class PalindromicGapfulNumbers {

    public static void main(String[] args) {
        System.out.println("First 20 palindromic gapful numbers ending in:");
        displayMap(getPalindromicGapfulEnding(20, 20));

        System.out.printf("%nLast 15 of first 100 palindromic gapful numbers ending in:%n");
        displayMap(getPalindromicGapfulEnding(15, 100));

        System.out.printf("%nLast 10 of first 1000 palindromic gapful numbers ending in:%n");
        displayMap(getPalindromicGapfulEnding(10, 1000));
    }
    
    private static void displayMap(Map<Integer,List<Long>> map) {
        for ( int key = 1 ; key <= 9 ; key++ ) {
            System.out.println(key + " : " + map.get(key));
        }
    }
    
    public static Map<Integer,List<Long>> getPalindromicGapfulEnding(int countReturned, int firstHowMany) {
        Map<Integer,List<Long>> map = new HashMap<>();
        Map<Integer,Integer> mapCount = new HashMap<>();
        for ( int i = 1 ; i <= 9 ; i++ ) {
            map.put(i, new ArrayList<>());
            mapCount.put(i, 0);
        }
        boolean notPopulated = true;
        for ( long n = 101 ; notPopulated ; n = nextPalindrome(n) ) {
            if ( isGapful(n) ) {
                int index = (int) (n % 10);
                if ( mapCount.get(index) < firstHowMany ) {
                    map.get(index).add(n);
                    mapCount.put(index, mapCount.get(index) + 1);
                    if ( map.get(index).size() > countReturned ) {
                        map.get(index).remove(0);
                    }
                }
                boolean finished = true;
                for ( int i = 1 ; i <= 9 ; i++ ) {
                    if ( mapCount.get(i) < firstHowMany ) {
                        finished = false;
                        break;
                    }
                }
                if ( finished ) {
                    notPopulated = false;
                }
            }
        }
        return map;
    }
    
    public static boolean isGapful(long n) {
        String s = Long.toString(n);
        return n % Long.parseLong("" + s.charAt(0) + s.charAt(s.length()-1)) == 0;
    }
    
    public static int length(long n) {
        int length = 0;
        while ( n > 0 ) {
            length += 1;
            n /= 10;
        }
        return length;
    }
    
    public static long nextPalindrome(long n) {
        int length = length(n);
        if ( length % 2 == 0 ) {
            length /= 2;
            while ( length > 0 ) {
                n /= 10;
                length--;
            }
            n += 1;
            if ( powerTen(n) ) {
                return Long.parseLong(n + reverse(n/10));
            }
            return Long.parseLong(n + reverse(n));
        }
        length = (length - 1) / 2;
        while ( length > 0 ) {
            n /= 10;
            length--;
        }
        n += 1;
        if ( powerTen(n) ) {
            return Long.parseLong(n + reverse(n/100));
        }
        return Long.parseLong(n + reverse(n/10));
    }
    
    private static boolean powerTen(long n) {
        while ( n > 9 && n % 10 == 0 ) {
            n /= 10;
        }
        return n == 1;
    }
        
    private static String reverse(long n) {
        return (new StringBuilder(n + "")).reverse().toString();
    }

}