Programming Praxis


Home | Pages | Archives


Pandigital Squares

September 29, 2020 9:00 AM

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.

Posted by programmingpraxis

Categories: Exercises

Tags:

7 Responses to “Pandigital Squares”

  1. 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!

    By Zack on September 29, 2020 at 12:19 PM

  2. 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

    By Ernie on October 1, 2020 at 12:11 AM

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

    By Zack on October 1, 2020 at 9:55 AM

  4. [ i**2 for i in range(int(1023456789**0.5), int(9876543210**0.5)) if len(set(str(i**2))) == 10 ]
    

    By Jan Van lent on October 5, 2020 at 6:14 PM

  5. 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
    

    By Daniel on October 6, 2020 at 9:00 PM

  6. 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
    

    By Daniel on October 14, 2020 at 9:27 PM

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

    By Scott McMaster on November 1, 2020 at 6:15 PM

Leave a Reply



Mobile Site | Full Site


Get a free blog at WordPress.com Theme: WordPress Mobile Edition by Alex King.