Pandigital Squares

September 29, 2020

A pandigital number, like 4730825961, is a ten-digit number in which each digit from zero to nine appears exactly once. A square number, like 25² = 625, is a number with an integral square root.

Your task is to write a program that finds all of the pandigital square numbers. When you are finished, you are welcome to read or run a suggested solution, or to post your own solution or discuss the exercise in the comments below.

Advertisement

Pages: 1 2

7 Responses to “Pandigital Squares”

  1. Zack said

    Cute little exercise. Here is my take on it in Julia 1.5: https://pastebin.com/XV0aiT9j

    Please excuse the unnecessary use of semicolons here. I’ve gotten into the habit of using them everywhere, ever since I started learning another language that requires them. Cheers!

  2. Ernie said

    No need to test all integers from 35000 to 100000. Since all pandigitals are divisible by 9, we only need test integers divisible by 3 and exclude those ending in 0

  3. Zack said

    @Ernie. Good point! I’ve amended my code to take into account this information. Thank you for the tip!

  4. Jan Van lent said
    [ i**2 for i in range(int(1023456789**0.5), int(9876543210**0.5)) if len(set(str(i**2))) == 10 ]
    
  5. Daniel said

    Here’s a solution in C.

    #include <stdbool.h>
    #include <stdint.h>
    #include <stdio.h>
    #include <stdlib.h>
    
    #define MIN_PANDIGITAL 1023456789
    #define MAX_PANDIGITAL 9876543210
    
    static bool is_pandigital(int64_t x) {
      if (x < MIN_PANDIGITAL || x > MAX_PANDIGITAL)
        return false;
      int count[10] = {0};
      for (int i = 0; i < 10; ++i) {
        int r = x % 10;
        if (++(count[r]) > 1)
          return false;
        x /= 10;
      }
      return true;
    }
    
    int main(void) {
      int start = 31991;  // int(sqrt(MIN_PANDIGITAL))
      int end = 99380;  // int(sqrt(MAX_PANDIGITAL))
      for (int x = start; x <= end; ++x) {
        int64_t square = (int64_t)x * (int64_t)x;
        if (is_pandigital(square))
          printf("%ld\n", square);
      }
      return EXIT_SUCCESS;
    }
    

    Output:

    1026753849
    1042385796
    1098524736
    1237069584
    ...
    9351276804
    9560732841
    9614783025
    9761835204
    9814072356
    
  6. Daniel said

    Here’s a solution in OCaml.

    let is_pandigital x =
      let min = 1023456789
      and max = 9876543210 in
      if x < min || x > max then false
      else
        let rec is_pandigital' pending observed =
          if pending = 0 then true
          else
            let digit = pending mod 10 in
            let mask = 1 lsl digit in
            if (mask land observed) > 0 then false
            else is_pandigital' (pending / 10) (observed lor mask)
        in is_pandigital' x 0
    ;;
    
    let start = 31991
    and finish = 99380 in
    let rec loop i =
      if i > finish then ()
      else let square = i * i in
        if is_pandigital square then Printf.printf "%d\n" square;
        loop (i + 1) in
    loop start
    

    Output:

    1026753849
    1042385796
    1098524736
    1237069584
    ...
    9351276804
    9560732841
    9614783025
    9761835204
    9814072356
    
  7. Scott McMaster said

    Some Golang, very zippy so I didn’t make any extra optimizations: https://pastebin.com/bJwdAHw9

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: