Jump to content

Magic numbers

From Rosetta Code
Task
Magic numbers
You are encouraged to solve this task according to the task description, using any language you may know.

Magic numbers are polydivisible numbers in base 10. A polydivisible number is an m digit number where the first n digits are evenly divisible by n for all n from 1 to m.


E.G. The number 1868587 is a magic number (is polydivisible in base 10.)

      1 ÷ 1 = 1
     18 ÷ 2 = 9
    186 ÷ 3 = 62
   1868 ÷ 4 = 467
  18685 ÷ 5 = 3737
 186858 ÷ 6 = 31143
1868587 ÷ 7 = 266941

There is a finite number of magic numbers.


Task
  • Write a routine (subroutine, function, procedure, generator, whatever it may be called in your language) to find magic numbers.
  • Use that routine to find and display how many magic numbers exist.
  • Use that routine to find and display the largest possible magic number.
  • Count and display how many magic numbers have 1 digit, 2 digits, 3 digits, ... for all magic numbers.
  • Find and display all of the magic numbers that are minimally pandigital in 1 through 9. (Contains each digit but only once.)
  • Find and display all of the magic numbers that are minimally pandigital in 0 through 9.


Zero (0) may or may not be included as a magic number. For this task, include zero.


See also


ALGOL 68

Works with: ALGOL 68G version Any - tested with release 2.8.3.win32

Uses Algol 68G's LONG LONG INT, which has programmer definable precision, the default is sufficient for this task.

BEGIN # count magic numbers: numbers divisible by the count of digits and    #
      # each left substring is also divisible by the count of its digits     #
    # returns the magic numbers of length m length that can be formed by      #
    # adding a digit to the elements of prev m                               #
    PROC next magic = ( []LONG LONG INT prev m, INT m length )[]LONG LONG INT:
         BEGIN
            FLEX[ 1 : 2 000 ]LONG LONG INT m;
            INT m pos := 0;
            FOR i FROM LWB prev m TO UPB prev m DO
                LONG LONG INT n := prev m[ i ] * 10;
                FOR d FROM 0 BY IF ODD m length THEN 1 ELSE 2 FI TO 9 DO
                    IF ( n + d ) MOD m length = 0 THEN
                        IF m pos >= UPB m THEN
                            # need a bigger magic number buffer              #
                            [ 1 : UPB m + 1000 ]LONG LONG INT new m;
                            new m[ 1 : UPB m ] := m;
                            m                  := new m
                        FI;
                        m[ m pos +:= 1 ] := n + d
                    FI
                OD
            OD;
            m[ 1 : m pos ]
         END # next magic # ;
    # returns TRUE if n is pandigital (1-9), FALSE otherwise                 #
    PROC is pandigital1 = ( LONG LONG INT n )BOOL:
         BEGIN
            INT v := SHORTEN SHORTEN n;
            [ 0 : 9 ]INT digit count := []INT( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 )[ AT 0 ];
            WHILE digit count[ v MOD 10 ] +:= 1;
                  ( v OVERAB 10 ) > 0
            DO SKIP OD;
            BOOL result := digit count[ 0 ] = 0;
            FOR i FROM 1 TO 9 WHILE result := digit count[ i ] = 1 DO SKIP OD;
            result
         END # is pandigital1 # ;
    # find the magic numbers                                                 #
    print( ( "Magic number counts by number of digits:", newline ) );
    INT m count := 0;                        # total number of magic numbers #
    INT d count := 1;                                     # number of digits #
    FLEX[ 1 : 10 ]LONG LONG INT magic := ( 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 );
    FLEX[ 1 :  0 ]LONG LONG INT magic9;
    LONG LONG INT max magic := -1;
    WHILE UPB magic >= LWB magic DO
        print( ( whole( d count, -5 ), ": ", whole( UPB magic, -9 ), newline ) );
        m count  +:= UPB magic;
        max magic := magic[ UPB magic ];
        IF   d count = 1 THEN
            # exclude 0 from the 1 digit magic numbers to find the 2 digit   #
            magic := ( 1, 2, 3, 4, 5, 6, 7, 8, 9 )
        ELIF d count = 9 THEN
            # save the 9 digit magic numbers so we can find the pandigitals  #
            magic9 := magic
        FI;
        magic := next magic( magic, d count +:= 1 )
    OD;
    print( ( "Total:", whole( m count, -10 ), " magic numbers", newline ) );
    print( ( "Largest is ", whole( max magic, 0 ), newline ) );
    # find the minimally pandigital magic numbers                            #
    [ 1 : UPB magic9 ]LONG LONG INT pd magic;
    INT pd pos := 0;
    FOR i FROM LWB pd magic TO UPB pd magic DO
        IF is pandigital1( magic9[ i ] ) THEN
            pd magic[ pd pos +:= 1 ] := magic9[ i ]
        FI
    OD;
    print( ( "Minimally pandigital 1-9 magic numbers: " ) );
    FOR i TO pd pos DO
        print( ( whole( pd magic[ i ], 0 ) ) )
    OD;
    print( ( newline ) );
    print( ( "Minimally pandigital 0-9 magic numbers: " ) );
    FOR i TO pd pos DO
        print( ( whole( pd magic[ i ] * 10, 0 ) ) )
    OD;
    print( ( newline ) )
END
Output:
Magic number counts by number of digits:
    1:        10
    2:        45
    3:       150
    4:       375
    5:       750
    6:      1200
    7:      1713
    8:      2227
    9:      2492
   10:      2492
   11:      2225
   12:      2041
   13:      1575
   14:      1132
   15:       770
   16:       571
   17:       335
   18:       180
   19:        90
   20:        44
   21:        18
   22:        12
   23:         6
   24:         3
   25:         1
Total:     20457 magic numbers
Largest is 3608528850368400786036725
Minimally pandigital 1-9 magic numbers: 381654729
Minimally pandigital 0-9 magic numbers: 3816547290

AWK

function lmod(n, d,	i, l, r) {
	l = 15 - length(d - 1)
	for (i = 1; i <= d; i += l) r = (r substr(n, i, l)) % d
	return r
}

function is_pandigital(d, n) {
	while (d < 10) if (!index(n, d++)) return 0
	return 1
}

BEGIN {
	do {
		l = length(n = res[++i]) + 1
		for (d = (l - lmod(n "0", l)) % l; d < 10; d += l)
			res[++o] = n d
	} while (i != o)

	print "found " o " magic numbers"
	print "the largest one is " res[o]

	print "count by number of digits:"
	l = 0
	for (i = 1; i <= o; ++i) {
		if ((d = length(m = res[i])) == l) {
			++n
		} else {
			if (l) printf "%u:%u ", l, n
			n = 1
			l = d
		}
		if (l == 9 && is_pandigital(1, m))
			pd1 = pd1 " " m
		if (l == 10 && is_pandigital(0, m))
			pd0 = pd0 " " m
	}
	printf "%u:%u\n", l, n
	print "minimally pandigital in 1..9:" pd1
	print "minimally pandigital in 0..9:" pd0
}
Output:
found 20457 magic numbers
the largest one is 3608528850368400786036725
count by number of digits:
1:10 2:45 3:150 4:375 5:750 6:1200 7:1713 8:2227 9:2492 10:2492 11:2225 12:2041 13:1575 14:1132 15:770 16:571 17:335 18:180 19:90 20:44 21:18 22:12 23:6 24:3 25:1
minimally pandigital in 1..9: 381654729
minimally pandigital in 0..9: 3816547290

BASIC

FreeBASIC

Translation of: AWK
Function lmod(n As String, d As Integer) As Ulongint
    Dim As Ulongint r = 0
    For i As Integer = 1 To Len(n)
        r = (r * 10 + Val(Mid(n, i, 1))) Mod d
    Next i
    Return r
End Function

Function isPandigital(d As Integer, n As String) As Boolean
    While d < 10
        If Instr(n, Trim(Str(d))) = 0 Then Return False
        d += 1
    Wend
    Return True
End Function

Dim Shared As String res(1 To 1000000)
Dim As Integer i, o, l, d, nn
Dim As String pd1, pd0, n, m

i = 0 : o = 0
Do
    n = res(i + 1)
    l = Len(n) + 1
    For d = 0 To 9
        If (lmod(n & Trim(Str(d)), l) = 0) Then
            o += 1
            res(o) = n & Trim(Str(d))
        End If
    Next d
    i += 1
Loop Until i = o

Print "Found "; o; " magic numbers"
Print !"\nThe largest one is "; res(o)

Print !"\ncount by number of digits:"
l = 0
For i = 1 To o
    m = res(i)
    d = Len(m)
    If d = l Then
        nn += 1
    Else
        If l Then Print Using "## : &"; l; nn
        nn = 1
        l = d
    End If
    If l =  9 And isPandigital(1, m) Then pd1 &= " " & m
    If l = 10 And isPandigital(0, m) Then pd0 &= " " & m
Next i
Print Using "## : &"; l; nn

Print !"\nminimally pandigital in 1..9:" & pd1
Print "minimally pandigital in 0..9:" & pd0

Sleep
Output:
Found  20457 magic numbers

The largest one is 3608528850368400786036725

count by number of digits:
 1 : 10
 2 : 45
 3 : 150
 4 : 375
 5 : 750
 6 : 1200
 7 : 1713
 8 : 2227
 9 : 2492
10 : 2492
11 : 2225
12 : 2041
13 : 1575
14 : 1132
15 : 770
16 : 571
17 : 335
18 : 180
19 : 90
20 : 44
21 : 18
22 : 12
23 : 6
24 : 3
25 : 1

minimally pandigital in 1..9: 381654729
minimally pandigital in 0..9: 3816547290

QB64

Dim Shared res(1 To 1000000) As String
Dim As Long i, o, l, d, nn
Dim As String pd1, pd0, n, m

i = 0: o = 0
Do
    n = res(i + 1)
    l = Len(n) + 1
    For d = 0 To 9
        If (lmod(n + LTrim$(RTrim$(Str$(d))), l) = 0) Then
            o = o + 1
            res(o) = n + LTrim$(RTrim$(Str$(d)))
        End If
    Next d
    i = i + 1
Loop Until i = o

Print "Found "; o; " magic numbers"
Print Chr$(10) + "The largest one is "; res(o)

Print Chr$(10) + "count by number of digits:"
l = 0
For i = 1 To o
    m = res(i)
    d = Len(m)
    If d = l Then
        nn = nn + 1
    Else
        If l Then Print Using "## : "; l;: Print nn
        nn = 1
        l = d
    End If
    If l = 9 And isPandigital(1, m) Then pd1 = pd1 + " " + m
    If l = 10 And isPandigital(0, m) Then pd0 = pd0 + " " + m
Next i
Print Using "## : "; l;: Print nn

Print Chr$(10) + "minimally pandigital in 1..9:" + pd1
Print "minimally pandigital in 0..9:" + pd0

Function lmod& (n As String, d As Integer)
    r& = 0
    For i& = 1 To Len(n)
        r = (r * 10 + Val(Mid$(n, i&, 1))) Mod d
    Next i&
    lmod = r
End Function

Function isPandigital% (d As Integer, n As String)
    Dim i As Integer
    For i = d To 9
        If InStr(n, LTrim$(RTrim$(Str$(i)))) = 0 Then isPandigital% = 0: Exit Function
    Next i
    isPandigital% = -1
End Function
Output:
Same as FreeBASIC entry.

C++

Library: Boost
#include <array>
#include <iostream>
#include <numeric>
#include <vector>

#include <boost/multiprecision/cpp_int.hpp>

using boost::multiprecision::uint128_t;

class magic_number_generator {
public:
    magic_number_generator() : magic_(10) {
        std::iota(magic_.begin(), magic_.end(), 0);
    }
    bool next(uint128_t& n);

public:
    std::vector<uint128_t> magic_;
    size_t index_ = 0;
    int digits_ = 2;
};

bool magic_number_generator::next(uint128_t& n) {
    if (index_ == magic_.size()) {
        std::vector<uint128_t> magic;
        for (uint128_t m : magic_) {
            if (m == 0)
                continue;
            uint128_t n = 10 * m;
            for (int d = 0; d < 10; ++d, ++n) {
                if (n % digits_ == 0)
                    magic.push_back(n);
            }
        }
        index_ = 0;
        ++digits_;
        magic_ = std::move(magic);
    }
    if (magic_.empty())
        return false;
    n = magic_[index_++];
    return true;
}

std::array<int, 10> get_digits(uint128_t n) {
    std::array<int, 10> result = {};
    for (; n > 0; n /= 10)
        ++result[static_cast<int>(n % 10)];
    return result;
}

int main() {
    int count = 0, dcount = 0;
    uint128_t magic = 0, p = 10;
    std::vector<int> digit_count;

    std::array<int, 10> digits0 = {1,1,1,1,1,1,1,1,1,1};
    std::array<int, 10> digits1 = {0,1,1,1,1,1,1,1,1,1};
    std::vector<uint128_t> pandigital0, pandigital1;

    for (magic_number_generator gen; gen.next(magic);) {
        if (magic >= p) {
            p *= 10;
            digit_count.push_back(dcount);
            dcount = 0;
        }
        auto digits = get_digits(magic);
        if (digits == digits0)
            pandigital0.push_back(magic);
        else if (digits == digits1)
            pandigital1.push_back(magic);
        ++count;
        ++dcount;
    }
    digit_count.push_back(dcount);

    std::cout << "There are " << count << " magic numbers.\n\n";
    std::cout << "The largest magic number is " << magic << ".\n\n";

    std::cout << "Magic number count by digits:\n";
    for (int i = 0; i < digit_count.size(); ++i)
        std::cout << i + 1 << '\t' << digit_count[i] << '\n';

    std::cout << "\nMagic numbers that are minimally pandigital in 1-9:\n";
    for (auto m : pandigital1)
        std::cout << m << '\n';

    std::cout << "\nMagic numbers that are minimally pandigital in 0-9:\n";
    for (auto m : pandigital0)
        std::cout << m << '\n';
}
Output:
There are 20457 magic numbers.

The largest magic number is 3608528850368400786036725.

Magic number count by digits:
1	10
2	45
3	150
4	375
5	750
6	1200
7	1713
8	2227
9	2492
10	2492
11	2225
12	2041
13	1575
14	1132
15	770
16	571
17	335
18	180
19	90
20	44
21	18
22	12
23	6
24	3
25	1

Magic numbers that are minimally pandigital in 1-9:
381654729

Magic numbers that are minimally pandigital in 0-9:
3816547290

EasyLang

func[] bnmul a[] b .
   for d in a[]
      h = c + d * b
      r[] &= h mod 10000000
      c = h div 10000000
   .
   if c > 0
      r[] &= c
   .
   return r[]
.
func bnmod a[] b .
   for ia = len a[] downto 1
      m = (m * 10000000 + a[ia]) mod b
   .
   return m
.
func$ str bn[] .
   s$ = bn[$]
   for i = len bn[] - 1 downto 1
      h$ = bn[i]
      s$ &= substr "0000000" 1 (7 - len h$) & h$
   .
   return s$
.
func bnlen bn[] .
   if bn[] = [ 0 ]
      return 1
   .
   return (len bn[] - 1) * 7 + floor log10 bn[$] + 1
.
global mn[][] .
proc getmagnums . .
   i = 1
   n[] = [ 0 ]
   repeat
      l = bnlen n[]
      for dig = (l - bnmod n[] l) mod l step l to 9
         mn[][] &= n[]
         mn[$][1] += dig
      .
      i += 1
      until i = len mn[][]
      n[] = bnmul mn[i][] 10
   .
.
getmagnums
# 
proc show . .
   print len mn[][] & " magic numbers"
   print str mn[$][] & " is the largest"
   len ndigs[] 25
   min = 1 / 0
   for mi to len mn[][]
      n[] = mn[mi][]
      ndig = bnlen n[]
      ndigs[ndig] += 1
      if ndig = 9
         s$ = str n[]
         for i = 1 to 9
            if strpos s$ i = 0
               s$ = "999999999"
            .
         .
         min = lower min number s$
      .
   .
   print "count by number of digits:"
   for i to len ndigs[]
      write i & ":" & ndigs[i] & " "
   .
   print ""
   print min & " is minimal pandigital in 1..9"
   print min & 0 & " is minimal pandigital in 0..9"
.
show
Output:
20457 magic numbers
3608528850368400786036725 is the largest
count by number of digits:
1:10 2:45 3:150 4:375 5:750 6:1200 7:1713 8:2227 9:2492 10:2492 11:2225 12:2041 13:1575 14:1132 15:770 16:571 17:335 18:180 19:90 20:44 21:18 22:12 23:6 24:3 25:1 
381654729 is minimal pandigital in 1..9
3816547290 is minimal pandigital in 0..9

F#

// Magic numbers. Nigel Galloway: February 10th., 2023
let digs=[|0..10|]|>Array.map(System.UInt128.CreateChecked)
let fN n g=n|>List.collect(fun n->let n=n*digs[10] in [for g in digs[0..9]->n+g]|>List.filter(fun n->n%g=digs[0]))
let fG (n:int []) g=let rec fN g=if g<digs[10] then n[int g]<-n[int g]-1 else n[int(g%digs[10])]<-n[int(g%digs[10])]-1; fN (g/digs[10])
                    fN g; Array.forall ((=)0) n
let magic=Array.append [|[digs[0]..digs[9]]|] (Array.unfold(fun(n,g)->match n with []->None |n->let n=fN n g in Some(n,(n,g+digs[1])))([digs[1]..digs[9]],digs[2]))
printfn $"There are %d{magic|>Array.sumBy(List.length)} Magic numbers"
magic|>Array.iteri(fun n g->printfn "There are %d magic numbers of length %d" (List.length g) (n+1))
printfn $"Largest magic number is %A{magic.[magic.Length-2]|>List.max}"
printf "Minimally pan-digital(1..9) magic numbers are: "; magic[8]|>List.filter(fun n->fG [|0;1;1;1;1;1;1;1;1;1|] n)|>List.iter(printf "%A ");printfn ""
printf "Minimally pan-digital(1..9) magic numbers are: "; magic[9]|>List.filter(fun n->fG [|1;1;1;1;1;1;1;1;1;1|] n)|>List.iter(printf "%A ");printfn ""9
Output:
There are 20457 Magic numbers
There are 10 magic numbers of length 1
There are 45 magic numbers of length 2
There are 150 magic numbers of length 3
There are 375 magic numbers of length 4
There are 750 magic numbers of length 5
There are 1200 magic numbers of length 6
There are 1713 magic numbers of length 7
There are 2227 magic numbers of length 8
There are 2492 magic numbers of length 9
There are 2492 magic numbers of length 10
There are 2225 magic numbers of length 11
There are 2041 magic numbers of length 12
There are 1575 magic numbers of length 13
There are 1132 magic numbers of length 14
There are 770 magic numbers of length 15
There are 571 magic numbers of length 16
There are 335 magic numbers of length 17
There are 180 magic numbers of length 18
There are 90 magic numbers of length 19
There are 44 magic numbers of length 20
There are 18 magic numbers of length 21
There are 12 magic numbers of length 22
There are 6 magic numbers of length 23
There are 3 magic numbers of length 24
There are 1 magic numbers of length 25
There are 0 magic numbers of length 26
Largest magic number is 3608528850368400786036725
Minimally pan-digital(1..9) magic numbers are: 381654729
Minimally pan-digital(0..9) magic numbers are: 3816547290

J

Implementation:

ispdiv=: {{0= +/(# | 10 #. ])\ 10&#.inv y}}

{{
 if. 0>nc<'pdivs' do.
  pdivs=: {{
   r=. 0,d=. 1 2 3 4 5 6 7 8 9x
   while. #d do. 
     r=. r,d=. (#~ ispdiv"0), (10*d)+/i.10
   end.
  }}0
 end.
}}0

Task:

   #pdivs                     NB. quantity of these "magic' numbers"
20457
   >./pdivs                   NB. largest of these "magic numbers"
3608528850368400786036725
   (~.,. #/.~) #@":@> pdivs   NB. tallies by digit count
 1   10
 2   45
 3  150
 4  375
 5  750
 6 1200
 7 1713
 8 2227
 9 2492
10 2492
11 2225
12 2041
13 1575
14 1132
15  770
16  571
17  335
18  180
19   90
20   44
21   18
22   12
23    6
24    3
25    1
    (#~ '123456789'&-:@(/:~)@":@>)pdivs
381654729
    (#~ '0123456789'&-:@(/:~)@":@>)pdivs
3816547290

Java

import java.math.BigInteger;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

public final class MagicNumbers {

	public static void main(String[] args) {
		List<BigInteger> magicNumbers = polydivisible(10);
		System.out.println("There are " + magicNumbers.size() + " magic numbers.");
		System.out.println("The largest magic number is " + magicNumbers.getLast());
		System.out.println();
		
		List<List<String>> magicLists = magicLists(magicNumbers);
		System.out.println("Count of magic numbers by the number of digits:");
		IntStream.range(0, magicLists.size()).forEach( i ->
		    System.out.println(String.format("%2d%s%5d", i + 1, ":", magicLists.get(i).size())) );
		System.out.println();
		
		System.out.print("Minimally pandigital 1-9 magic numbers: ");
		magicLists.get(8).stream().filter( s -> isMinimallyPandigital(s, "1") ).forEach(System.out::print);
		System.out.println();

		System.out.print("Minimally pandigital 0-9 magic numbers: ");		
		magicLists.get(9).stream().filter( s -> isMinimallyPandigital(s, "0") ).forEach(System.out::print);
	}
	
	private static List<BigInteger> polydivisible(int base) {
		List<BigInteger> magicNumbers = new ArrayList<BigInteger>();
	    List<BigInteger> previousNumbers = IntStream.range(1, base).mapToObj( i -> BigInteger.valueOf(i) )
	    									        .collect(Collectors.toList());
	    List<BigInteger> newNumbers = new ArrayList<BigInteger>();
	    BigInteger digitCount = BigInteger.TWO;
	    while ( ! previousNumbers.isEmpty() ) {
	        magicNumbers.addAll(previousNumbers);
	        for ( BigInteger prev : previousNumbers ) {
	            for ( int j = 0; j < base; j++ ) {
	                BigInteger number = prev.multiply(BigInteger.valueOf(base)).add(BigInteger.valueOf(j));
	                if ( number.mod(digitCount).signum() == 0 ) {
	                    newNumbers.addLast(number);
	                }
	            }
	        }
	        previousNumbers = new ArrayList<BigInteger>(newNumbers);
	        newNumbers = new ArrayList<BigInteger>();
	        digitCount = digitCount.add(BigInteger.ONE);
	    }
	    magicNumbers.addFirst(BigInteger.ZERO);
	    return magicNumbers;
	}
	
	private static List<List<String>> magicLists(List<BigInteger> magicNumbers) {
		List<List<String>> result = new ArrayList<List<String>>();
		magicNumbers.stream().map( i -> i.toString() ).forEach( s -> {
			if ( s.length() > result.size() ) {
				result.addLast( new ArrayList<String>() );
			}
			result.get(s.length() - 1).addLast(s);
		} );
		return result;
	}
	
	private static boolean isMinimallyPandigital(String number, String startDigit) {
		List<String> digits = number.chars().mapToObj( i -> String.valueOf(i - '0') )
								    .distinct().sorted().toList();
		return digits.size() == 10 - Integer.valueOf(startDigit) && digits.getFirst().equals(startDigit);
	}
}
Output:
There are 20457 magic numbers.
The largest magic number is 3608528850368400786036725

Count of magic numbers by the number of digits:
 1:   10
 2:   45
 3:  150
 4:  375
 5:  750
 6: 1200
 7: 1713
 8: 2227
 9: 2492
10: 2492
11: 2225
12: 2041
13: 1575
14: 1132
15:  770
16:  571
17:  335
18:  180
19:   90
20:   44
21:   18
22:   12
23:    6
24:    3
25:    1

Minimally pandigital 1-9 magic numbers: 381654729
Minimally pandigital 0-9 magic numbers: 3816547290

jq

Adapted from Wren

Works with gojq, the Go implementation of jq, and with fq

The solution presented here depends on the unbounded-precision integer arithmetic of the Go implementations of jq, and the results shown can be generated by an invocation of the form:

gojq -nr -f magic-numbers.jq
def sum(s): reduce s as $x (0; .+$x);

# Emit all the polydivisibles in the form of an array of arrays
# such that the numbers in .[i] are the polydivisibles of length i+1
def polydivisible:
   def extend($n):
     ((. * 10) + range(0;10)) | select(. % $n == 0);
   # input: an array of arrays, such that the numbers in .[i] are the polydivisibles of length i+1
   def extend:
     . as $in
     | length as $n
     | [$in[-1][] | extend($n+1)] as $x
     | if $x|length == 0 then $in
       else $in + [$x] | extend
       end;
   [[range(1;10)]] | extend;

def pandigital:
  tostring | gsub("0";"") | explode | unique | length == 9;

# Select the pandigitals from .[$k] 
# Input: an array as produced by polydivisible
# Output: an array
def pd($k):
  .[$k] | map(select(pandigital));
  
def tasks:
  polydivisible
  | .[0] += [0]
  | "There are \(sum(.[] | length)) magic numbers in total.", 
    "\nThe largest is \(.[-1][-1])",
    "\nThere are:",
      (range(0; length) as $i
       | "\(.[$i]|length) with \($i + 1) digit\(if ($i == 0) then "" else "s" end)"),
    ( "\nAll magic numbers that are pan-digital in 1 through 9 with no repeats: ",  pd(8)[] ),
    ( "\nAll magic numbers that are pan-digital in 0 through 9 with no repeats: ", pd(9)[] ) ;

tasks
Output:
There are 20457 magic numbers in total.

The largest is 3608528850368400786036725

There are:
10 with 1 digit
45 with 2 digits
150 with 3 digits
375 with 4 digits
750 with 5 digits
1200 with 6 digits
1713 with 7 digits
2227 with 8 digits
2492 with 9 digits
2492 with 10 digits
2225 with 11 digits
2041 with 12 digits
1575 with 13 digits
1132 with 14 digits
770 with 15 digits
571 with 16 digits
335 with 17 digits
180 with 18 digits
90 with 19 digits
44 with 20 digits
18 with 21 digits
12 with 22 digits
6 with 23 digits
3 with 24 digits
1 with 25 digits

All magic numbers that are pan-digital in 1 through 9 with no repeats: 
381654729

All magic numbers that are pan-digital in 0 through 9 with no repeats: 
3816547290

Julia

function findmagics(maxdig = 26)
    magics = [Int128[] for _ in 1:maxdig-1]
    pushfirst!(magics, collect(one(Int128):9))
    for n in 2:maxdig, i in magics[n - 1], j in 0:9
        k = 10i + j
        k % n == 0 && push!(magics[n], k)
    end
    pushfirst!(first(magics), 0) # zero is a one-digit magic number?
    return magics
end

const magics = findmagics()

for (n, arr) in enumerate(magics)
    println("There are $(length(arr)) magic numbers with $n digits",
       isempty(arr) ? "." : " with the largest $(last(arr)).")
end
println("\nIn all, there are $(sum(map(length, magics))) magic numbers.\n")

println("Magic number(s) pan-digital in 1 through 9 with no repeats: ",
    join(filter(n -> (d = digits(n); all(i -> count(==(i), d) == 1, 1:9)), magics[9])))
println("Magic number(s) pan-digital in 0 through 9 with no repeats: ",
    join(filter(n -> (d = digits(n); all(i -> count(==(i), d) == 1, 0:9)), magics[10])))
Output:
There are 10 magic numbers with 1 digits with the largest 9.
There are 45 magic numbers with 2 digits with the largest 98.
There are 150 magic numbers with 3 digits with the largest 987.       
There are 375 magic numbers with 4 digits with the largest 9876.      
There are 750 magic numbers with 5 digits with the largest 98765.     
There are 1200 magic numbers with 6 digits with the largest 987654.   
There are 1713 magic numbers with 7 digits with the largest 9876545.  
There are 2227 magic numbers with 8 digits with the largest 98765456. 
There are 2492 magic numbers with 9 digits with the largest 987654564.
There are 2492 magic numbers with 10 digits with the largest 9876545640.
There are 2225 magic numbers with 11 digits with the largest 98765456405.
There are 2041 magic numbers with 12 digits with the largest 987606963096.
There are 1575 magic numbers with 13 digits with the largest 9876069630960.
There are 1132 magic numbers with 14 digits with the largest 98760696309604.
There are 770 magic numbers with 15 digits with the largest 987606963096045.
There are 571 magic numbers with 16 digits with the largest 9876062430364208.
There are 335 magic numbers with 17 digits with the largest 98485872309636009.
There are 180 magic numbers with 18 digits with the largest 984450645096105672.
There are 90 magic numbers with 19 digits with the largest 9812523240364656789.
There are 44 magic numbers with 20 digits with the largest 96685896604836004260.
There are 18 magic numbers with 21 digits with the largest 966858966048360042609.
There are 12 magic numbers with 22 digits with the largest 9668589660483600426096.
There are 6 magic numbers with 23 digits with the largest 72645656402410567240820.
There are 3 magic numbers with 24 digits with the largest 402852168072900828009216.
There are 1 magic numbers with 25 digits with the largest 3608528850368400786036725.
There are 0 magic numbers with 26 digits.

In all, there are 20457 magic numbers.

Magic number(s) pan-digital in 1 through 9 with no repeats: 381654729
Magic number(s) pan-digital in 0 through 9 with no repeats: 3816547290

Nim

Library: Nim-Integers
import std/[algorithm, sequtils, strformat, strutils]
import integers

iterator magicNumbers(): tuple[length: int; value: Integer] =
  ## Yield the lengths and values of magic numbers.
  var magics = toSeq(newInteger(1)..newInteger(9))  # Ignore 0 for now.
  yield (1, newInteger(0))
  var length = 1
  while magics.len != 0:
    for n in magics: yield (length, n)
    var newMagics: seq[Integer]
    inc length
    for m in magics:
      for d in 0..9:
        let n = 10 * m + d
        if n mod length == 0:
          newMagics.add n
    magics = move(newMagics)

func isMinimallyPandigital(n: Integer; start: char): bool =
  ## Return true if "n" is minimally pandigital in "start" through 9.
  sorted($n) == toSeq(start..'9')


# Build list of magic numbers distributed by length.
var magicList: seq[seq[Integer]] = @[@[]]
var total = 0
for (length, n) in magicNumbers():
  if length > magicList.high:
    magicList.add @[]
  magicList[^1].add n
  inc total

echo &"Number of magic numbers: {insertSep($total)}"
echo &"Largest magic number: {insertSep($magicList[^1][^1])}"

echo "\nMagic number counts by number of digits:"
for length in 1..magicList.high:
  echo &"{length:2}: {magicList[length].len}"
echo()

stdout.write "Minimally pandigital 1-9 magic numbers: "
for n in magicList[9]:
  if n.isMinimallyPandigital('1'):
    stdout.write insertSep($n), ' '
echo()

stdout.write "Minimally pandigital 0-9 magic numbers: "
for n in magicList[10]:
  if n.isMinimallyPandigital('0'):
    stdout.write insertSep($n), ' '
echo()
Output:
Number of magic numbers: 20_457
Largest magic number: 3_608_528_850_368_400_786_036_725

Magic number counts by number of digits:
 1: 10
 2: 45
 3: 150
 4: 375
 5: 750
 6: 1200
 7: 1713
 8: 2227
 9: 2492
10: 2492
11: 2225
12: 2041
13: 1575
14: 1132
15: 770
16: 571
17: 335
18: 180
19: 90
20: 44
21: 18
22: 12
23: 6
24: 3
25: 1

Minimally pandigital 1-9 magic numbers: 381_654_729 
Minimally pandigital 0-9 magic numbers: 3_816_547_290 

Pascal

Free Pascal

Only Using UInt64. Therefore 18 digits are the limit.

program MagicNUmbers;
{$IFDEF FPC}{$MODE DELPHI}{$Optimization ON,All}{$ENDIF}
{$IFDEF Windows}{$APPTYPE CONSOLE}{$ENDIF}
uses
  sysutils;// TDatetime
const
  CntMagicNUmbers = 2492;
var
  MagicNumbs : array[0..CntMagicNUmbers] of Uint64;
  MagicCnt : Int32;
function checkpanX_9(MinDigit : Int32):UInt64;
var
  n,q : Uint64;
  idx: Uint32;
  testDigits,
  AllDigits : set of 0..9;
begin
  AllDigits := [];
  For idx := 9 downto MinDigit do
    include(AllDigits,idx);
  For idx := 1 to MagicCnt do
  begin
    n := MagicNumbs[idx];
    testDigits := [];
    repeat
      q := n DIV 10;
      include(TestDigits,n-10*q);
      n:= q;
    until q = 0;
    if TestDigits = AllDigits then
      EXIT(MagicNumbs[idx]);
  end;
end;

function ExtendMagic(dgtcnt:Int32):Boolean;
var
  newMg : Uint64;
  i,j,k : Int32;
begin
  i := 1;
  j := CntMagicNUmbers-MagicCnt+1;
  Move(MagicNumbs[i],MagicNumbs[j],SizeOf(MagicNumbs[0])*MagicCnt);
  if dgtcnt = 2 then //Jump over zero
    inc(j);
  repeat
    newMg := MagicNumbs[j]*10;
    k := newMg MOD dgtcnt;
    IF k > 0 then
      k := dgtCnt-k;
    newMg += k;
    while k in [0..9] do
    Begin
      MagicNumbs[i] := newMg;
      k += dgtCnt;
      newMg +=dgtcnt;
      inc(i);
    end;
    inc(j);
  until j > CntMagicNUmbers;
  MagicCnt := i-1;
  result := true;
end;

var
 PAN1_9,PAN0_9: Int64;
 i,sum : Int32;
Begin
  MagicNumbs[1] := 0;
  MagicCnt := 0;
  sum := 0;
  writeln('Magic number counts by number of digits and max value: ');
  For i := 1 to 18 do
  begin
    ExtendMagic(i);
    IF i = 9 then
      PAN1_9 := checkpanX_9(1);
    IF i = 10 then
      PAN0_9 :=  checkpanX_9(0);
    inc(sum,MagicCnt);
    writeln(i:4,MagicCnt:10,MagicNumbs[MagicCnt]:19);
  end;
  Writeln(' Sum of MagicCnt: ',sum);
  Writeln(' Pandigital number with 1..9: ', PAN1_9);
  Writeln(' Pandigital number with 0..9: ', PAN0_9);
end.
@TIO.RUN:
Magic number counts by number of digits and max value: 
   1        10                  9
   2        45                 98
   3       150                987
   4       375               9876
   5       750              98765
   6      1200             987654
   7      1713            9876545
   8      2227           98765456
   9      2492          987654564
  10      2492         9876545640
  11      2225        98765456405
  12      2041       987606963096
  13      1575      9876069630960
  14      1132     98760696309604
  15       770    987606963096045
  16       571   9876062430364208
  17       335  98485872309636009
  18       180 984450645096105672
 Sum of MagicCnt: 20283
 Pandigital number with 1..9: 381654729
 Pandigital number with 0..9: 3816547290

Perl

use strict; 
use warnings;
use bigint;

my $dcnt = 1;
my @ok = my @magic = 0..9; shift @ok;
while () {
    $dcnt++;
    my @candidates = ();
    for my $d (0..9) { push @candidates, map { 10*$_ + $d } @ok }
    (@ok = grep { 0 == $_ % $dcnt } @candidates) ? push(@magic, @ok) : last;
}

printf "There are %d magic numbers in total.\nThe largest is %s.\n\n", scalar(@magic), $magic[-1];

my %M; $M{length $_}++ for @magic;
for my $k (sort { $a <=> $b } keys %M) {
    printf " %6d with %3d digit%s\n",  $M{$k}, $k, $k>1?'s':'';
}

for my $i (1,0) {
    my $digits = join '', $i..9;
    printf "\nMagic number(s) pan-digital in $i through 9 with no repeats: %s\n",
        grep { length $_ == 10-$i and $digits eq join '', sort split '', $_ } @magic;
}
Output:
There are 20457 magic numbers in total.
The largest is 3608528850368400786036725.

     10 with   1 digit
     45 with   2 digits
    150 with   3 digits
    375 with   4 digits
    750 with   5 digits
   1200 with   6 digits
   1713 with   7 digits
   2227 with   8 digits
   2492 with   9 digits
   2492 with  10 digits
   2225 with  11 digits
   2041 with  12 digits
   1575 with  13 digits
   1132 with  14 digits
    770 with  15 digits
    571 with  16 digits
    335 with  17 digits
    180 with  18 digits
     90 with  19 digits
     44 with  20 digits
     18 with  21 digits
     12 with  22 digits
      6 with  23 digits
      3 with  24 digits
      1 with  25 digits

Magic number(s) pan-digital in 1 through 9 with no repeats: 381654729

Magic number(s) pan-digital in 0 through 9 with no repeats: 3816547290

Phix

Using strings

with javascript_semantics
function polydivisible()
    sequence res = {}, prev = {""}, next = {}
    integer digits = 1
    while length(prev) do
        for np in prev do
            for d='0'+(digits=1) to '9' do
                string n = np&d
                integer rem = 0
                for nd in n do
                    rem = remainder(rem*10+nd-'0',digits)
                end for
                if rem=0 then
                    next = append(next,n)
                end if
            end for
        end for
        if length(next) then
            res = append(res,next)
        end if
        prev = next
        next = {}
        digits += 1
    end while
    res[1] = {"0"} & res[1]
    return res
end function

sequence r = polydivisible(),
        rc = apply(r,length)
string fmt = """
There are %,d magic numbers in total.

The largest is %s.

There are:
"""
printf(1,fmt,{sum(rc),r[$][$]})
for i,c in rc do
    printf(1,"%,5d with %2d digit%s, the largest being %s\n",
             {c,i,iff(i=1?"":"s"),r[i][$]})
end for
function pandigital(string s,p) return sort(s)=p end function
function evenonly(string s) return sum(apply(s,odd))=0 end function
function filter_even(sequence ri) return filter(ri,evenonly) end function
function palindromic(string s) return s=reverse(s) end function
function filter_pal(sequence ri) return filter(ri,palindromic) end function
string p1 = join(filter(r[9],pandigital,"123456789"),"\n"),
       p0 = join(filter(r[10],pandigital,"0123456789"),"\n"),
       evenpd = trim_tail(apply(r,filter_even),{{}})[$][$],
       pallypd = trim_tail(apply(r,filter_pal),{{}})[$][$]
fmt = """%s
All magic numbers that are pan-digital in 1 through 9 with no repeats:
 %s

All magic numbers that are pan-digital in 0 through 9 with no repeats:
 %s

The longest polydivisible number that only uses even digits is:
 %s

The longest palindromic polydivisible number is:
 %s
"""
printf(1,fmt,{"\n",p1,p0,evenpd,pallypd})
Output:
There are 20,457 magic numbers in total.

The largest is 3608528850368400786036725.

There are:
   10 with  1 digit, the largest being 9
   45 with  2 digits, the largest being 98
  150 with  3 digits, the largest being 987
  375 with  4 digits, the largest being 9876
  750 with  5 digits, the largest being 98765
1,200 with  6 digits, the largest being 987654
1,713 with  7 digits, the largest being 9876545
2,227 with  8 digits, the largest being 98765456
2,492 with  9 digits, the largest being 987654564
2,492 with 10 digits, the largest being 9876545640
2,225 with 11 digits, the largest being 98765456405
2,041 with 12 digits, the largest being 987606963096
1,575 with 13 digits, the largest being 9876069630960
1,132 with 14 digits, the largest being 98760696309604
  770 with 15 digits, the largest being 987606963096045
  571 with 16 digits, the largest being 9876062430364208
  335 with 17 digits, the largest being 98485872309636009
  180 with 18 digits, the largest being 984450645096105672
   90 with 19 digits, the largest being 9812523240364656789
   44 with 20 digits, the largest being 96685896604836004260
   18 with 21 digits, the largest being 966858966048360042609
   12 with 22 digits, the largest being 9668589660483600426096
    6 with 23 digits, the largest being 72645656402410567240820
    3 with 24 digits, the largest being 402852168072900828009216
    1 with 25 digits, the largest being 3608528850368400786036725


All magic numbers that are pan-digital in 1 through 9 with no repeats:
 381654729

All magic numbers that are pan-digital in 0 through 9 with no repeats:
 3816547290

The longest polydivisible number that only uses even digits is:
 48000688208466084040

The longest palindromic polydivisible number is:
 30000600003

Python

from itertools import groupby

def magic_numbers(base):
    hist = []
    n = l = i = 0
    while True:
        l += 1
        hist.extend((n + digit, l) for digit in range(-n % l, base, l))
        i += 1
        if i == len(hist):
            return hist
        n, l = hist[i]
        n *= base

mn = magic_numbers(10)
print("found", len(mn), "magic numbers")
print("the largest one is", mn[-1][0])

print("count by number of digits:")
print(*(f"{l}:{sum(1 for _ in g)}" for l, g in groupby(l for _, l in mn)))

print(end="minimally pandigital in 1..9: ")
print(*(m for m, l in mn if l == 9 == len(set(str(m)) - {"0"})))
print(end="minimally pandigital in 0..9: ")
print(*(m for m, l in mn if l == 10 == len(set(str(m)))))
Output:
found 20457 magic numbers
the largest one is 3608528850368400786036725
count by number of digits:
1:10 2:45 3:150 4:375 5:750 6:1200 7:1713 8:2227 9:2492 10:2492 11:2225 12:2041 13:1575 14:1132 15:770 16:571 17:335 18:180 19:90 20:44 21:18 22:12 23:6 24:3 25:1
minimally pandigital in 1..9: 381654729
minimally pandigital in 0..9: 3816547290

Raku

my \Δ = $ = 1;
my @magic = flat 0, [1..9], {last if .not; ++Δ; [(.flat X~ 0..9).grep: * %% Δ]}…*;

put "There are {@magic.eager.elems} magic numbers in total.";
put "\nThe largest is {@magic.tail}.";
put "\nThere are:";
put "{(+.value).fmt: "%4d"} with {.key.fmt: "%2d"} digit{1 == +.key ?? '' !! 's'}"
    for sort @magic.classify: {.chars};
{
    my $pan-digital = ($_..9).join.comb.Bag;
    put "\nAll magic numbers that are pan-digital in $_ through 9 with no repeats: " ~
    @magic.grep( { .comb.Bag eqv $pan-digital } );
} for 1, 0;
Output:
There are 20457 magic numbers in total.

The largest is 3608528850368400786036725.

There are:
  10 with  1 digit
  45 with  2 digits
 150 with  3 digits
 375 with  4 digits
 750 with  5 digits
1200 with  6 digits
1713 with  7 digits
2227 with  8 digits
2492 with  9 digits
2492 with 10 digits
2225 with 11 digits
2041 with 12 digits
1575 with 13 digits
1132 with 14 digits
 770 with 15 digits
 571 with 16 digits
 335 with 17 digits
 180 with 18 digits
  90 with 19 digits
  44 with 20 digits
  18 with 21 digits
  12 with 22 digits
   6 with 23 digits
   3 with 24 digits
   1 with 25 digits

All magic numbers that are pan-digital in 1 through 9 with no repeats: 381654729

All magic numbers that are pan-digital in 0 through 9 with no repeats: 3816547290

Rust

fn get_digits(mut n: u128) -> [usize; 10] {
    let mut digits = [0; 10];
    while n > 0 {
        digits[(n % 10) as usize] += 1;
        n /= 10;
    }
    digits
}

fn magic_numbers() -> impl std::iter::Iterator<Item = u128> {
    let mut magic: Vec<u128> = vec![0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
    let mut index = 0;
    let mut digits = 2;
    std::iter::from_fn(move || {
        if index == magic.len() {
            let mut magic_new: Vec<u128> = Vec::new();
            for &m in &magic {
                if m == 0 {
                    continue;
                }
                let mut n = 10 * m;
                for _ in 0..10 {
                    if n % digits == 0 {
                        magic_new.push(n);
                    }
                    n += 1;
                }
            }
            index = 0;
            digits += 1;
            magic = magic_new;
        }
        if magic.is_empty() {
            return None;
        }
        let m = magic[index];
        index += 1;
        Some(m)
    })
}

fn main() {
    let mut count = 0;
    let mut dcount = 0;
    let mut magic: u128 = 0;
    let mut p: u128 = 10;
    let digits0 = [1; 10];
    let digits1 = [0, 1, 1, 1, 1, 1, 1, 1, 1, 1];
    let mut pandigital0: Vec<u128> = Vec::new();
    let mut pandigital1: Vec<u128> = Vec::new();
    let mut digit_count: Vec<usize> = Vec::new();
    for m in magic_numbers() {
        magic = m;
        if magic >= p {
            p *= 10;
            digit_count.push(dcount);
            dcount = 0;
        }
        let digits = get_digits(magic);
        if digits == digits0 {
            pandigital0.push(magic);
        } else if digits == digits1 {
            pandigital1.push(magic);
        }
        count += 1;
        dcount += 1;
    }
    digit_count.push(dcount);
    println!("There are {} magic numbers.\n", count);
    println!("The largest magic number is {}.\n", magic);
    println!("Magic number count by digits:");
    for (i, c) in digit_count.iter().enumerate() {
        println!("{}\t{}", i + 1, c);
    }
    println!("\nMagic numbers that are minimally pandigital in 1-9:");
    for m in pandigital1 {
        println!("{}", m);
    }
    println!("\nMagic numbers that are minimally pandigital in 0-9:");
    for m in pandigital0 {
        println!("{}", m);
    }
}
Output:
There are 20457 magic numbers.

The largest magic number is 3608528850368400786036725.

Magic number count by digits:
1	10
2	45
3	150
4	375
5	750
6	1200
7	1713
8	2227
9	2492
10	2492
11	2225
12	2041
13	1575
14	1132
15	770
16	571
17	335
18	180
19	90
20	44
21	18
22	12
23	6
24	3
25	1

Magic numbers that are minimally pandigital in 1-9:
381654729

Magic numbers that are minimally pandigital in 0-9:
3816547290

Wren

Library: Wren-big
Library: Wren-fmt

This is based on the Python code in the Wikipedia article.

import "./big" for BigInt
import "./fmt" for Fmt

var polydivisible = Fn.new {
    var numbers = []
    var previous = (1..9).toList
    var new = []
    var digits = 2
    while (previous.count > 0) {
        numbers.add(previous)
        for (n in previous) {
            for (j in 0..9) {
                var number = BigInt.ten * n + j
                if (number % digits == 0) new.add(number)
            }
        }
        previous = new
        new = []
        digits = digits + 1
    }
    return numbers
}

var numbers = polydivisible.call()
numbers[0].add(BigInt.zero) // include zero
var total = numbers.reduce(0) { |acc, number| acc + number.count }
Fmt.print("There are $,d magic numbers in total.", total)

var largest = numbers[-1][-1]
Fmt.print("\nThe largest is $,i.", largest)

System.print("\nThere are:")
for (i in 0...numbers.count) {
    Fmt.print("$,5d with $2d digit$s", numbers[i].count, i+1, (i == 0) ? "" : "s")
}

var pd19 = []
for (n in numbers[8]) {
    var s = n.toString
    var pandigital = true
    for (i in 1..9) {
        if (!s.contains(i.toString)) {
            pandigital = false
            break
        }
    }
    if (pandigital) pd19.add(n)
}
System.print("\nAll magic numbers that are pan-digital in 1 through 9 with no repeats: ")
Fmt.print("$,i", pd19)

var pd09 = []
for (n in numbers[9]) {
    var s = n.toString
    var pandigital = true
    for (i in 0..9) {
        if (!s.contains(i.toString)) {
            pandigital = false
            break
        }
    }
    if (pandigital) pd09.add(n)
}
System.print("\nAll magic numbers that are pan-digital in 0 through 9 with no repeats: ")
Fmt.print("$,i", pd09)
Output:
There are 20,457 magic numbers in total.

The largest is 3,608,528,850,368,400,786,036,725.

There are:
   10 with  1 digit 
   45 with  2 digits
  150 with  3 digits
  375 with  4 digits
  750 with  5 digits
1,200 with  6 digits
1,713 with  7 digits
2,227 with  8 digits
2,492 with  9 digits
2,492 with 10 digits
2,225 with 11 digits
2,041 with 12 digits
1,575 with 13 digits
1,132 with 14 digits
  770 with 15 digits
  571 with 16 digits
  335 with 17 digits
  180 with 18 digits
   90 with 19 digits
   44 with 20 digits
   18 with 21 digits
   12 with 22 digits
    6 with 23 digits
    3 with 24 digits
    1 with 25 digits

All magic numbers that are pan-digital in 1 through 9 with no repeats: 
381,654,729

All magic numbers that are pan-digital in 0 through 9 with no repeats: 
3,816,547,290