# Pan base non-primes

Pan base non-primes
You are encouraged to solve this task according to the task description, using any language you may know.

Primes are prime no matter which base they are expressed in. Some numeric strings are prime in a large number of bases. (Not the same prime, but a prime.)

For example

The numeric string "255", while obviously not a prime in base 10, is a prime in bases:

```     6   8  12  14  18  24  26  32  36  38  72  84  86  92  96 102 104 108 128 134
138 144 158 164 188 216 224 236 242 246 252 254 264 272 294 318 332 344 348 368
374 392 396 408 428 432 446 456 468 476 482 512 522 528 542 546 552 566 572 576
578 594 596 602 606 614 618 626 654 702 714 722 728 756 762 774 776 788 806 816
818 822 828 836 848 864 866 872 882 888 902 908 912 918 924 932 936 942 944 956
966 986 998
```

among others.

There are numeric strings however, that are not a prime in any base. Confining ourselves to 'decimal' numeric strings; the single digit numeric primes are prime in every base where they are a valid number.

E.G.

The numeric string "2" is a prime in every base except base 2, where it is invalid.

The numeric string "3" is a prime in every base except base 2 and 3, where it is invalid.

"4" is not a prime in every base except bases 2, 3, and 4 where it is an invalid number (and hence not a prime there either.)

In general, even pan-base non-primes are much more prevalent than odd, though both are fairly common.

With the exception of "10", numeric strings that end in 0 are composite in every base where they are valid.

Numeric strings where the greatest common divisor of all of the digits is more than 1 are composite in every base.

If a "decimal" numeric string N is composite in every base up to base N, it is composite in every base.

The digit 1 is an odd-ball case as it is neither prime nor composite. It typically is not included, but due to the ambiguous wording, would not be wrong if it is.

• Find and display, here on this page, the first 40 pan-base non-prime "base 10" numeric strings.
• Find and display, here on this page, the first 20 odd pan-base non-prime "base 10" numeric strings.
• Find and display the count of pan-base non-prime "base 10" numeric strings up to at least the numeric string "1000".
• What percentage of them are odd / even?

## ALGOL 68

Translation of: Wren
```BEGIN # pan-base non-primes - translated from the Wren sample               #
PR read "primes.incl.a68" PR                  # include prime utilities #
INT    limit = 2500;

# iterative Greatest Common Divisor routine, returns the gcd of m and n #
PROC gcd = ( INT m, n )INT:
BEGIN
INT a := ABS m, b := ABS n;
WHILE b /= 0 DO
INT new a = b;
b        := a MOD b;
a        := new a
OD;
a
END # gcd # ;

# table of digit-digit Greatest Common Divisors                        #
[ 0 : 9, 0 : 9 ]INT dd gcd;
FOR i FROM 0 TO 9 DO FOR j FROM 0 TO 9 DO dd gcd[ i, j ] := gcd( i, j ) OD OD;

# returns the gcd of the digits of n                                   #
PROC gcd digits = ( INT n )INT:
BEGIN
STRING s  = whole( n, 0 );
INT    g := 0;
FOR c FROM LWB s TO UPB s DO
g := dd gcd[ g, ABS s[ c ] - ABS "0" ]
OD;
g
END # gcd digits # ;

# returns the number represented by s in base b                        #
#         note s will only contain the digits 0 .. 9                   #
PROC str to dec = ( STRING s, INT base )LONG INT:
BEGIN
LONG INT res := 0;
FOR c pos FROM LWB s TO UPB s DO
res *:= base +:= ( ABS s[ c pos ] - ABS "0" )
OD;
res
END # str to dec # ;

[ 1 : limit ]INT pbnp;
INT pbnp count := 0;

FOR n FROM 3 TO limit DO
IF n MOD 10 = 0 AND n > 10 THEN
pbnp[ pbnp count +:= 1 ] := n
ELIF n > 9 AND gcd digits( n ) > 1 THEN
pbnp[ pbnp count +:= 1 ] := n
ELSE
BOOL   comp := TRUE;
STRING s     = whole( n, 0 );
FOR base FROM 2 TO n WHILE comp := NOT is probably prime( str to dec( s, base ) ) DO SKIP OD;
IF comp THEN pbnp[ pbnp count +:= 1 ] := n FI
FI
OD;

print( ( "First 50 pan-base composites:", newline ) );
FOR i TO IF pbnp count < 50 THEN pbnp count ELSE 50 FI DO
print( ( " ", whole( pbnp[ i ], -3 ) ) );
IF i MOD 10 = 0 THEN print( ( newline ) ) FI
OD;
print( ( newline, "First 20 odd pan-base composites:", newline ) );
INT odd count := 0;
FOR i TO pbnp count DO
INT n = pbnp[ i ];
IF ODD n THEN
odd count +:= 1;
IF odd count <= 20 THEN
print( ( " ", whole( n, -3 ) ) );
IF odd count MOD 10 = 0 THEN print( ( newline ) ) FI
FI
FI
OD;

print( ( newline
, "Count of pan-base composites up to and including "
, whole( limit, 0 )
, ": "
, whole( pbnp count, 0 )
)
);
print( ( newline
, "Number odd  = "
, whole( odd count, 0 )
, " or ", fixed( 100 * ( odd count / pbnp count ), -9, 6 )
, "%"
)
);
print( ( newline
, "Number even = "
, whole( pbnp count - odd count, 0 )
, " or ", fixed( 100 * ( ( pbnp count - odd count ) / pbnp count ), -9, 6 )
, "%"
)
)
END```
Output:
```First 50 pan-base composites:
4   6   8   9  20  22  24  26  28  30
33  36  39  40  42  44  46  48  50  55
60  62  63  64  66  68  69  70  77  80
82  84  86  88  90  93  96  99 100 110
112 114 116 118 120 121 130 132 134 136

First 20 odd pan-base composites:
9  33  39  55  63  69  77  93  99 121
143 165 169 187 231 253 273 275 297 299

Count of pan-base composites up to and including 2500: 953
Number odd  = 161 or 16.894019%
Number even = 792 or 83.105981%
```

## C

```#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>

bool is_prime(uint64_t n) {
if (n < 2)
return false;
if (n % 2 == 0)
return n == 2;
if (n % 3 == 0)
return n == 3;
if (n % 5 == 0)
return n == 5;
static const uint64_t wheel[] = {4, 2, 4, 2, 4, 6, 2, 6};
for (uint64_t p = 7;;) {
for (int i = 0; i < 8; ++i) {
if (p * p > n)
return true;
if (n % p == 0)
return false;
p += wheel[i];
}
}
}

// Compute the digits of n in base 10, least significant digit first.
int digits(uint64_t n, uint8_t* d, int size) {
int count = 0;
for (; n > 0 && size > 0; n /= 10, --size, ++count)
*d++ = n % 10;
return count;
}

// Convert digits in the given base to a number (least significant digit first).
uint64_t from_digits(uint8_t* a, int count, uint64_t base) {
uint64_t n = 0;
while (count-- > 0)
n = n * base + a[count];
return n;
}

#define MAX_DIGITS 20

bool is_pan_base_non_prime(uint64_t n) {
if (n < 10)
return !is_prime(n);
if (n > 10 && n % 10 == 0)
return true;
uint8_t d[MAX_DIGITS];
int count = digits(n, d, MAX_DIGITS);
uint8_t max_digit = 0;
for (int i = 0; i < count; ++i) {
if (max_digit < d[i])
max_digit = d[i];
}
for (uint64_t base = max_digit + 1; base <= n; ++base) {
if (is_prime(from_digits(d, count, base)))
return false;
}
return true;
}

int main() {
printf("First 50 prime pan-base composites:\n");
int count = 0;
for (uint64_t n = 2; count < 50; ++n) {
if (is_pan_base_non_prime(n)) {
++count;
printf("%3llu%c", n, count % 10 == 0 ? '\n' : ' ');
}
}

printf("\nFirst 20 odd prime pan-base composites:\n");
count = 0;
for (uint64_t n = 3; count < 20; n += 2) {
if (is_pan_base_non_prime(n)) {
++count;
printf("%3llu%c", n, count % 10 == 0 ? '\n' : ' ');
}
}

const uint64_t limit = 10000;
int odd = 0;
count = 0;
for (uint64_t n = 2; n <= limit; ++n) {
if (is_pan_base_non_prime(n)) {
++count;
if (n % 2 == 1)
++odd;
}
}

printf("\nCount of pan-base composites up to and including %llu: %d\n",
limit, count);
double percent = 100.0 * odd / count;
printf("Percent odd  up to and including %llu: %f\n", limit, percent);
printf("Percent even up to and including %llu: %f\n", limit,
100.0 - percent);

return 0;
}
```
Output:
```First 50 prime pan-base composites:
4   6   8   9  20  22  24  26  28  30
33  36  39  40  42  44  46  48  50  55
60  62  63  64  66  68  69  70  77  80
82  84  86  88  90  93  96  99 100 110
112 114 116 118 120 121 130 132 134 136

First 20 odd prime pan-base composites:
9  33  39  55  63  69  77  93  99 121
143 165 169 187 231 253 273 275 297 299

Count of pan-base composites up to and including 10000: 3849
Percent odd  up to and including 10000: 18.030657
Percent even up to and including 10000: 81.969343
```

## C++

```#include <algorithm>
#include <cassert>
#include <cstdint>
#include <iomanip>
#include <iostream>
#include <numeric>
#include <vector>

bool is_prime(uint64_t n) {
if (n < 2)
return false;
if (n % 2 == 0)
return n == 2;
if (n % 3 == 0)
return n == 3;
if (n % 5 == 0)
return n == 5;
static constexpr uint64_t wheel[] = {4, 2, 4, 2, 4, 6, 2, 6};
for (uint64_t p = 7;;) {
for (uint64_t w : wheel) {
if (p * p > n)
return true;
if (n % p == 0)
return false;
p += w;
}
}
}

std::vector<uint64_t> digits(uint64_t n) {
std::vector<uint64_t> d;
for (uint64_t m = n; m > 0; m /= 10)
d.push_back(m % 10);
reverse(d.begin(), d.end());
return d;
}

template <typename iterator> auto gcd(iterator begin, iterator end) {
assert(begin != end);
auto result = *begin++;
for (; begin != end; ++begin)
result = std::gcd(result, *begin);
return result;
}

template <typename number, typename iterator>
number polyval(iterator begin, iterator end, number value) {
number n = 0;
for (auto i = begin; i != end; ++i)
n = n * value + *i;
return n;
}

bool is_pan_base_non_prime(uint64_t n) {
if (n < 10)
return !is_prime(n);
if (n > 10 && n % 10 == 0)
return true;
auto d = digits(n);
if (gcd(d.begin(), d.end()) > 1)
return true;
auto max_digit = *std::max_element(d.begin(), d.end());
for (uint64_t base = max_digit + 1; base <= n; ++base) {
if (is_prime(polyval(d.begin(), d.end(), base)))
return false;
}
return true;
}

int main() {
std::vector<uint64_t> pbnp;
const uint64_t limit = 10000;
for (uint64_t n = 2; n <= limit; ++n) {
if (is_pan_base_non_prime(n))
pbnp.push_back(n);
}

std::cout << "First 50 pan-base composites:\n";
for (size_t i = 0; i < 50; ++i) {
std::cout << std::setw(3) << pbnp[i]
<< ((i + 1) % 10 == 0 ? '\n' : ' ');
}

std::cout << "\nFirst 20 odd pan-base composites:\n";
for (size_t i = 0, count = 0; count < 20; ++i) {
if (pbnp[i] % 2 == 1) {
++count;
std::cout << std::setw(3) << pbnp[i]
<< (count % 10 == 0 ? '\n' : ' ');
}
}

size_t total = pbnp.size();
size_t odd = std::count_if(pbnp.begin(), pbnp.end(),
[](uint64_t n) { return n % 2 == 1; });
std::cout << "\nCount of pan-base composites up to and including " << limit
<< ": " << total << '\n';
auto percent = (100.0 * odd) / total;
std::cout << std::fixed;
std::cout << "Percent odd  up to and including " << limit << ": " << percent
<< '\n';
std::cout << "Percent even up to and including " << limit << ": "
<< 100.0 - percent << '\n';
}
```
Output:
```First 50 pan-base composites:
4   6   8   9  20  22  24  26  28  30
33  36  39  40  42  44  46  48  50  55
60  62  63  64  66  68  69  70  77  80
82  84  86  88  90  93  96  99 100 110
112 114 116 118 120 121 130 132 134 136

First 20 odd pan-base composites:
9  33  39  55  63  69  77  93  99 121
143 165 169 187 231 253 273 275 297 299

Count of pan-base composites up to and including 10000: 3849
Percent odd  up to and including 10000: 18.030657
Percent even up to and including 10000: 81.969343
```

## EasyLang

```fastfunc isprim num .
if num mod 2 = 0
if num = 2
return 1
.
return 0
.
if num mod 3 = 0
if num = 3
return 1
.
return 0
.
i = 5
while i <= sqrt num
if num mod i = 0
return 0
.
i += 2
if num mod i = 0
return 0
.
i += 4
.
return 1
.
proc digits n . d[] .
while n > 0
d[] &= n mod 10
n = n div 10
.
.
proc fromdigits b . d[] n .
n = 0
for i = len d[] downto 1
n = n * b + d[i]
.
.
func panbasenpr n .
if n < 10
return 1 - isprim n
.
if n > 10 and n mod 10 = 0
return 1
.
digits n d[]
for i to len d[]
if maxdig < d[i]
maxdig = d[i]
.
.
for base = maxdig + 1 to n
fromdigits base d[] n
if isprim n = 1
return 0
.
.
return 1
.
print "First 50 prime pan-base composites:"
n = 2
repeat
if panbasenpr n = 1
cnt += 1
write n & " "
.
until cnt = 50
n += 1
.
cnt = 0
print "\n\nFirst 20 odd prime pan-base composites:"
n = 3
repeat
if panbasenpr n = 1
cnt += 1
write n & " "
.
until cnt = 20
n += 2
.
limit = 10000
cnt = 0
for n = 2 to limit
if panbasenpr n = 1
cnt += 1
if n mod 2 = 1
odd += 1
.
.
.
print "\nCount of pan-base composites up to and including " & limit & ": " & cnt
p = 100 * odd / cnt
print "Percent odd up to and including " & limit & ": " & p
print "Percent even up to and including " & limit & ": " & 100 - p```

## FreeBASIC

```#include "isprime.bas"

Const lim As Integer = 2500
Dim As Integer pbnp(lim)
Dim As Integer n, base_, d, c, tc, oc, ec
Dim As String digits
Dim As Boolean composite

For n = 3 To lim
digits = Str(n)
composite = True
For base_ = 2 To n
d = 0
For c = 1 To Len(digits)
d = d * base_ + Val(Mid(digits, c, 1))
Next c
If IsPrime(d) Then
composite = False
Exit For
End If
Next base_
If composite Then
tc += 1
pbnp(tc) = n
If n Mod 2 <> 0 Then oc += 1
End If
Next n

ec = tc - oc

Print "First 50 pan-base composites:"
For n = 1 To 50
Print Using "### "; pbnp(n);
If n Mod 10 = 0 Then Print
Next n

Print !"\nFirst 20 odd pan-base composites:"
c = 0
For n = 1 To 115
If pbnp(n) Mod 2 Then
Print Using "### "; pbnp(n);
'Print Using "### "; odds(n);
c += 1
If c Mod 10 = 0 Then Print
End If
Next n

Print !"\nCount of pan-base_ composites up to and including "; lim; ": "; tc
Print Using "Number odd  = ### or ##.######%"; oc; oc/tc*100
Print Using "Number even = ### or ##.######%"; ec; ec/tc*100

Sleep
```
Output:
`Same as Wren entry.`

## J

Implementation:

```pbnp=: {{ if. 10 > y do. -.1 p: y return. end.
digits=. 10 #.inv y
*/0=1 p: ((>./digits)+i.y) #."0 1 digits
}}"0
```

```   40{.1+I.pbnp 1+i.1e3 NB. first 40 pan based non primes
1 4 6 8 9 20 22 24 26 28 30 33 36 39 40 42 44 46 48 50 55 60 62 63 64 66 68 69 70 77 80 82 84 86 88 90 93 96 99 100
20{.(#~ 2&|)1+I.pbnp 1+i.1e3 NB. first 20 odd pan based non primes
1 9 33 39 55 63 69 77 93 99 121 143 165 169 187 231 253 273 275 297
#1+I.pbnp 1+i.1e3  NB. number of pan based non primes up to 1000
378
#(#~ 2&|)1+I.pbnp 1+i.1e3 NB. number of odd pan based non primes up to 1000
64
100*(+/%#)2|1+I.pbnp 1+i.1e3 NB. percent odd pan based non primes up to 1000
16.9761
```

## Java

```public class PanBaseNonPrimes {
public static void main(String[] args) {
System.out.printf("First 50 prime pan-base composites:\n");
int count = 0;
for (long n = 2; count < 50; ++n) {
if (isPanBaseNonPrime(n)) {
++count;
System.out.printf("%3d%c", n, count % 10 == 0 ? '\n' : ' ');
}
}

System.out.printf("\nFirst 20 odd prime pan-base composites:\n");
count = 0;
for (long n = 3; count < 20; n += 2) {
if (isPanBaseNonPrime(n)) {
++count;
System.out.printf("%3d%c", n, count % 10 == 0 ? '\n' : ' ');
}
}

final long limit = 10000;
count = 0;
int odd = 0;
for (long n = 2; n <= limit; ++n) {
if (isPanBaseNonPrime(n)) {
++count;
if (n % 2 == 1)
++odd;
}
}

System.out.printf("\nCount of pan-base composites up to and including %d: %d\n",
limit, count);
double percent = 100.0 * odd / count;
System.out.printf("Percent odd  up to and including %d: %f\n",
limit, percent);
System.out.printf("Percent even up to and including %d: %f\n",
limit, 100.0 - percent);
}

private static boolean isPanBaseNonPrime(long n) {
if (n < 10)
return !isPrime(n);
if (n > 10 && n % 10 == 0)
return true;
byte[] d = new byte[20];
int count = digits(n, d);
byte max_digit = 0;
for (int i = 0; i < count; ++i) {
if (max_digit < d[i])
max_digit = d[i];
}
for (long base = max_digit + 1; base <= n; ++base) {
if (isPrime(fromDigits(d, count, base)))
return false;
}
return true;
}

private static final long[] WHEEL = {4, 2, 4, 2, 4, 6, 2, 6};

private static boolean isPrime(long n) {
if (n < 2)
return false;
if (n % 2 == 0)
return n == 2;
if (n % 3 == 0)
return n == 3;
if (n % 5 == 0)
return n == 5;
for (long p = 7;;) {
for (int i = 0; i < 8; ++i) {
if (p * p > n)
return true;
if (n % p == 0)
return false;
p += WHEEL[i];
}
}
}

// Compute the digits of n in base 10, least significant digit first.
private static int digits(long n, byte[] d) {
int count = 0;
for (; n > 0 && count < d.length; n /= 10, ++count)
d[count] = (byte)(n % 10);
return count;
}

// Convert digits in the given base to a number (least significant digit first).
private static long fromDigits(byte[] a, int count, long base) {
long n = 0;
while (count-- > 0)
n = n * base + a[count];
return n;
}
}
```
Output:
```First 50 prime pan-base composites:
4   6   8   9  20  22  24  26  28  30
33  36  39  40  42  44  46  48  50  55
60  62  63  64  66  68  69  70  77  80
82  84  86  88  90  93  96  99 100 110
112 114 116 118 120 121 130 132 134 136

First 20 odd prime pan-base composites:
9  33  39  55  63  69  77  93  99 121
143 165 169 187 231 253 273 275 297 299

Count of pan-base composites up to and including 10000: 3849
Percent odd  up to and including 10000: 18.030657
Percent even up to and including 10000: 81.969343
```

## Julia

```using Primes

ispanbasecomposite(n) = (d = digits(n); all(b -> !isprime(evalpoly(b, d)), maximum(d)+1:max(10, n)))

panbase2500 = filter(ispanbasecomposite, 2:2500)
oddpanbase2500 = filter(isodd, panbase2500)
ratio = length(oddpanbase2500) // length(panbase2500)

println("First 50 pan base non-primes:")
foreach(p -> print(lpad(p[2], 4), p[1] % 10 == 0 ? "\n" : ""), pairs(panbase2500[1:50]))

println("\nFirst 20 odd pan base non-primes:")
foreach(p -> print(lpad(p[2], 4), p[1] % 10 == 0 ? "\n" : ""), pairs(oddpanbase2500[1:20]))

println("\nCount of pan-base composites up to and including 2500: ", length(panbase2500))

println("Odd up to and including 2500: ", ratio, ", or ", Float16(ratio * 100), "%.")
println("Even up to and including 2500: ", 1 - ratio, ", or ", Float16((1.0 - ratio) * 100), "%.")
```
Output:
```First 50 pan base non-primes:
4   6   8   9  20  22  24  26  28  30
33  36  39  40  42  44  46  48  50  55
60  62  63  64  66  68  69  70  77  80
82  84  86  88  90  93  96  99 100 110
112 114 116 118 120 121 130 132 134 136

First 20 odd pan base non-primes:
9  33  39  55  63  69  77  93  99 121
143 165 169 187 231 253 273 275 297 299

Count of pan-base composites up to and including 2500: 953
Odd up to and including 2500: 161//953, or 16.89%.
Even up to and including 2500: 792//953, or 83.1%.
```

## Mathematica/Wolfram Language

Translation of: Julia
```(* Define the function to check if a number is a pan base composite *)
IsPanBaseComposite[n_] := Module[
{d = IntegerDigits[n], bases, compositeInAllBases},
bases = Range[Max[d] + 1, Max[10, n]];
compositeInAllBases = Not /@ PrimeQ[FromDigits[d, #] & /@ bases];
AllTrue[compositeInAllBases, Identity]
]

(* Generate the list of all pan base composites up to 2500 *)
panBase2500 = Select[Range[2, 2500], IsPanBaseComposite]

(* Filter out the odd numbers from the pan base composites *)
oddPanBase2500 = Select[panBase2500, OddQ]

(* Calculate the ratio of odd pan base composites to all pan base composites *)
ratio = Length[oddPanBase2500] / Length[panBase2500]

(* Print the first 50 pan base non-primes *)
Print["First 50 pan base non-primes:"]
Print[StringJoin[Riffle[ToString /@ Take[panBase2500, 50], ", "]]]

(* Print the first 20 odd pan base non-primes *)
Print["\nFirst 20 odd pan base non-primes:"]
Print[StringJoin[Riffle[ToString /@ Take[oddPanBase2500, 20], ", "]]]

(* Print the count of pan-base composites up to and including 2500 *)
Print["\nCount of pan-base composites up to and including 2500: ", Length[panBase2500]]

(* Print the ratios *)
Print["Odd up to and including 2500: ", Rationalize[ratio], ", or ", N[ratio * 100, 4], "%."]
Print["Even up to and including 2500: ", Rationalize[1 - ratio], ", or ", N[(1 - ratio) * 100, 4], "%."]
```
Output:
```First 50 pan base non-primes:
4, 6, 8, 9, 20, 22, 24, 26, 28, 30, 33, 36, 39, 40, 42, 44, 46, 48, 50, 55, 60, 62, 63, 64, 66, 68, 69, 70, 77, 80, 82, 84, 86, 88, 90, 93, 96, 99, 100, 110, 112, 114, 116, 118, 120, 121, 130, 132, 134, 136

First 20 odd pan base non-primes:
9, 33, 39, 55, 63, 69, 77, 93, 99, 121, 143, 165, 169, 187, 231, 253, 273, 275, 297, 299

Count of pan-base composites up to and including 2500: 953
Odd up to and including 2500: 161/953, or 16.894018887722980063`4.%.
Even up to and including 2500: 792/953, or 83.105981112277019937`4.%.
```

## Nim

Translation of: C
```import std/strformat

func isPrime(n: int64): bool =
const Wheel = [4, 2, 4, 2, 4, 6, 2, 6]
if n < 2: return false
if (n and 1) == 0: return n == 2
if n mod 3 == 0: return n == 3
if n mod 5 == 0: return n == 5
var p = 7
while true:
for w in Wheel:
if p * p > n: return true
if n mod p == 0: return false
inc p, w

func digits(n: int64): seq[byte] =
## Compute the digits of n in base 10, least significant digit first.
var n = n
while n != 0:
n = n div 10

func fromDigits(a: seq[byte]; base: Positive): int64 =
## Convert digits in the given base to a number (least significant digit first).
for i in countdown(a.high, 0):
result = result * base + a[i].int

func isPanBaseNonPrime(n: int64): bool =
if n < 10: return not n.isPrime()
if n > 10 and n mod 10 == 0: return true
let d = n.digits
let maxDigit = max(d).int
for base in (maxDigit + 1)..n:
if d.fromDigits(base).isPrime():
return false
result = true

echo "First 50 prime pan-base composites:"
var count = 0;
var n = 2
while count < 50:
if n.isPanBaseNonPrime():
inc count
stdout.write &"{n:3}", if count mod 10 == 0: '\n' else: ' '
inc n

echo "\nFirst 20 odd prime pan-base composites:"
count = 0
n = 3
while count < 20:
if n.isPanBaseNonPrime():
inc count
stdout.write &"{n:3}", if count mod 10 == 0: '\n' else: ' '
inc n, 2

const Limit = 10_000
var odd = 0
count = 0
for n in 2..Limit:
if n.isPanBaseNonPrime():
inc count
if (n and 1) == 1:
inc odd
echo &"\nCount of pan-base composites up to and including {Limit}: {count}"
let percent = 100 * odd / count
echo &"Percent odd  up to and including {Limit}: {percent:.6f}"
echo &"Percent even up to and including {Limit}: {100 - percent:.6f}"
```
Output:
```First 50 prime pan-base composites:
4   6   8   9  20  22  24  26  28  30
33  36  39  40  42  44  46  48  50  55
60  62  63  64  66  68  69  70  77  80
82  84  86  88  90  93  96  99 100 110
112 114 116 118 120 121 130 132 134 136

First 20 odd prime pan-base composites:
9  33  39  55  63  69  77  93  99 121
143 165 169 187 231 253 273 275 297 299

Count of pan-base composites up to and including 10000: 3849
Percent odd  up to and including 10000: 18.030657
Percent even up to and including 10000: 81.969343
```

## PARI/GP

```/* Define the function to check if a number is not prime in all bases greater than its maximum digit */
is_pan_base_composite(n) = {
my(d = digits(n), base, isComp);
for (base = vecmax(d)+1, max(n, 10),
isComp = !isprime(fromdigits(d, base));
if (!isComp, return(0)); /* If number is prime in any base, return false */
);
return(1); /* Number is composite in all bases */
}

/* Generate the list of all pan base composites up to 2500 */
pan_base_2500 = select(is_pan_base_composite, [2..2500]);

/* Define a function to check if a number is odd */
is_odd(n) = n % 2 == 1;

/* Filter out the odd numbers from the pan base composites */
odd_pan_base_2500 = select(is_odd, pan_base_2500);

/* Calculate the ratio of odd pan base composites to all pan base composites */
ratio = #odd_pan_base_2500 / #pan_base_2500;

/* Print the first 50 pan base non-primes */
print("First 50 pan base non-primes:");
print(concat("", vector(min(#pan_base_2500, 50), i, Str(pan_base_2500[i]))));

/* Print the first 20 odd pan base non-primes */
print("\nFirst 20 odd pan base non-primes:");
print(concat("", vector(min(#odd_pan_base_2500, 20), i, Str(odd_pan_base_2500[i]))));

/* Print the count of pan-base composites up to and including 2500 */
print("\nCount of pan-base composites up to and including 2500: ", #pan_base_2500);

/* Print the ratios */
default(realprecision, 4)
print("Odd up to and including 2500: ", ratio, ", or ", ratio * 100.0, "%.");
print("Even up to and including 2500: ", 1 - ratio, ", or ", (1 - ratio) * 100.0, "%.");```
Output:
```First 50 pan base non-primes:
["4", "6", "8", "9", "20", "22", "24", "26", "28", "30", "33", "36", "39", "40", "42", "44", "46", "48", "50", "55", "60", "62", "63", "64", "66", "68", "69", "70", "77", "80", "82", "84", "86", "88", "90", "93", "96", "99", "100", "110", "112", "114", "116", "118", "120", "121", "130", "132", "134", "136"]

First 20 odd pan base non-primes:
["9", "33", "39", "55", "63", "69", "77", "93", "99", "121", "143", "165", "169", "187", "231", "253", "273", "275", "297", "299"]

Count of pan-base composites up to and including 2500: 953
Odd up to and including 2500: 161/953, or 16.89%.
Even up to and including 2500: 792/953, or 83.11%.
```

## Pascal

### Free Pascal

```program PanBaseNonPrime;
// Check Pan-Base Non-Prime
{\$IFDEF FPC}{\$MODE DELPHI}{\$OPTIMIZATION ON,ALL}{\$ENDIF}
{\$IFDEF WINDOWS}{\$APPTYPE CONSOLE}{\$ENDIF}
// MAXLIMIT beyond 10000 gets really slow 5 digits, depends on isPrime
//10004 checked til base 10003 -> 10003⁴+3 = 1.0012e16, takes >1 s longer
//real   0m1,307s
// 9999 checked til base  9998 -> 8,99555E12 much smaller
//real   0m0,260s
type
tDgts = 0..31;// Int32 is faster than 0..9 -> word
tUsedDgts = set of tDgts;
tDecDigits = packed record
decdgts   :array[0..20] of byte;
decmaxIdx :byte;
decmaxDgt :byte;
decUsedDgt :tUsedDgts;
end;
const
MAXLIMIT = 2500;
WithGCDNotOne : array[0..24] of tUsedDgts =
//all the same digits
([0],[2],[3],[4],[5],[6],[7],[8],[9],
//all even
[2,4],[2,6],[2,8],
[2,4,6],[2,4,8],[2,6,8],
[2,4,6,8],
[4,6],[4,8],
[4,6,8],[2,4,6,8],
[6,8],
//all divible 3
[3,6],[3,9],
[3,6,9],
[6,9]);
var
gblCnt,
gblOddCnt :NativeINt;

procedure OutDecDigits(var Dgts:tDecDigits);
var
idx : nativeInt;
begin
with Dgts do
begin
idx := decMaxIDx;
repeat
dec(idx);
write(decdgts[idx]);
until idx <= 0;
write(decmaxdgt:3);
writeln;
end;
end;

procedure CountOne(n:NativeInt);inline;
Begin
inc(gblCnt);
If odd(n) then
inc(gblOddCnt);
end;

procedure OutCountOne(n:NativeInt);
begin
CountOne(n);
write(n:5);
if gblCnt mod 10 = 0 then
writeln;
end;

function CheckGCD(var Dgts:tDecDigits):boolean;
var
idx: NativeInt;
UsedDgts:tUsedDgts;
begin
UsedDgts := Dgts.decUsedDgt;
For idx := Low(WithGCDNotOne) to High(WithGCDNotOne) do
if UsedDgts = WithGCDNotOne[idx] then
Exit(true);
Exit(false);
end;

procedure ConvToDecDgt(n : NativeUint;out Dgts:tDecDigits);//inline;
var
dgt,maxdgt,idx,q :NativeInt;
UsedDgts : tUsedDgts;
begin
UsedDgts := [];
maxdgt := 0;
idx := 0;
repeat
q := n div 10;
dgt := n-q*10;
Dgts.decdgts[idx]:= dgt;
include(UsedDgts,dgt);
IF maxdgt<dgt then
maxdgt := dgt;
inc(idx);
n := q;
until n = 0;

with Dgts do
Begin
decMaxIDx := idx;
decMaxdgt := maxDgt;
decUsedDgt := UsedDgts;
end;
end;

function ConvDgtToBase(var Dgts:tDecDigits;base:NativeInt):NativeUInt;
var
idx :NativeInt;
begin
result := 0;
if base<= Dgts.decMaxdgt then
EXIT;

with Dgts do
Begin
idx := decMaxIDx;
repeat
dec(idx);
result := result*base+decdgts[idx];
until idx <= 0;
end;
end;

function isPrime(n: NativeInt):boolean;
//simple trial division
var
j : nativeInt;
begin
if n in [2,3,5,7,11,13,17,19,23,29,31] then
EXIT(true);
if n<32 then
EXIT(false);
if not(odd(n)) then
EXIT(false);
if n mod 3 = 0 then
EXIT(false);
if n mod 5 = 0 then
EXIT(false);
j := 7;
while j*j<=n do
begin
if n mod j = 0 then
EXIT(false);
inc(j,4);
if n mod j = 0 then
EXIT(false);
inc(j,2);
end;
EXIT(true);
end;

function CheckPanBaseNonPrime(n: NativeUint):boolean;
var
myDecDgts:tDecDigits;
b,num : NativeInt;
Begin
result := true;
ConvToDecDgt(n,myDecDgts);
if (n>10) then
Begin
if (myDecDgts.decdgts[0] = 0) then
Exit;
if CheckGCD(myDecDgts) then
Exit;
end;

b := myDecDgts.decmaxdgt+1;
if b >= n then
Begin
if isPrime(n) then
Exit(false);
end
else
begin
while b < n do
begin
num := ConvDgtToBase(myDecDgts,b);
if isPrime(num) then
EXIT(false);
inc(b);
end;
end;
end;
var
i : NativeInt;

BEGIN
writeln('First 50 pan-base non-prime numbers ');
gblCnt := 0;
gblOddCnt := 0;
For i := 3 to MAXLIMIT do
Begin
if CheckPanBaseNonPrime(i) then
OutCountOne(i);
if gblCnt = 50 then
break;
end;
writeln;

writeln('First 20 pan-base non-prime odd numbers ');
gblCnt := 0;
gblOddCnt := 0;
For i := 3 to MAXLIMIT do
Begin
if ODD(i) then
Begin
if CheckPanBaseNonPrime(i) then
OutCountOne(i);
if gblOddCnt = 20 then
break;
end;
end;
writeln;

gblCnt := 0;
gblOddCnt := 0;
For i := 3 to MAXLIMIT do
if CheckPanBaseNonPrime(i) then
CountOne(i);
writeln('Count of pan-base composites up to and including ',MAXLIMIT,' : ',gblCnt);
writeln('odd  up to and including ',MAXLIMIT,' = ',gblOddCnt:4,' equals ',gblOddCnt/gblCnt*100:10:6,'%');
writeln('even up to and including ',MAXLIMIT,' = ',gblCnt-gblOddCnt:4,' equals ',(gblCnt-gblOddCnt)/gblCnt*100:10:6,'%');

END.
```
Output:
```First 50 pan-base non-prime numbers
4    6    8    9   20   22   24   26   28   30
33   36   39   40   42   44   46   48   50   55
60   62   63   64   66   68   69   70   77   80
82   84   86   88   90   93   96   99  100  110
112  114  116  118  120  121  130  132  134  136

First 20 pan-base non-prime odd numbers
9   33   39   55   63   69   77   93   99  121
143  165  169  187  231  253  273  275  297  299

Count of pan-base composites up to and including 2500 : 953
odd  up to and including 2500 =  161 equals  16.894019%
even up to and including 2500 =  792 equals  83.105981%
```

## Perl

Library: ntheory
```use v5.36;
use ntheory <fromdigits is_prime>;
use List::AllUtils <max firstidx>;

sub table (\$c, @V) { my \$t = \$c * (my \$w = 2 + length max @V); ( sprintf( ('%'.\$w.'d')x@V, @V) ) =~ s/.{1,\$t}\K/\n/gr }

my \$max = 2500;
my @np = <4 6 8 9>;
for my \$n (11..\$max) {
push @np, \$n unless max map { max(split '',\$n) < \$_ and is_prime fromdigits(\$n,\$_) } 2..\$n;
}

say "First 50 pan-base composites:\n"                        . table 10, @np[0..49];
say "First 20 odd pan-base composites:\n"                    . table 10, (grep { 0 !=  \$_ % 2 } @np)[0..19];
say "Count of pan-base composites up to and including \$max: ". (my \$f = 1 + firstidx { \$max <= \$_ } @np);
say "Percent odd  up to and including \$max: "                . sprintf '%.3f', 100 * (grep { 0 != \$_ % 2 } @np[0..\$f-1]) / \$f;
say "Percent even up to and including \$max: "                . sprintf '%.3f', 100 * (grep { 0 == \$_ % 2 } @np[0..\$f-1]) / \$f;
```
Output:
```First 50 pan-base composites:
4    6    8    9   20   22   24   26   28   30
33   36   39   40   42   44   46   48   50   55
60   62   63   64   66   68   69   70   77   80
82   84   86   88   90   93   96   99  100  110
112  114  116  118  120  121  130  132  134  136

First 20 odd pan-base composites:
9   33   39   55   63   69   77   93   99  121
143  165  169  187  231  253  273  275  297  299

Count of pan-base composites up to and including 2500: 953
Percent odd  up to and including 2500: 16.894
Percent even up to and including 2500: 83.106```

## Phix

Translation of: Wren
```with javascript_semantics
constant lim = 2500
sequence pbnp = {}
for n=3 to lim do
sequence digits = sq_sub(sprintf("%d",n),'0')
if (remainder(n,10)=0 and n>10)
or (n>9 and gcd(digits)>1) then
pbnp &= n
else
bool composite = true
for base=2 to n do
atom d = 0
for c in digits do
d = d*base + c
end for
if is_prime(d) then
composite = false
exit
end if
end for
if composite then pbnp &= n end if
end if
end for

sequence odds = filter(pbnp,odd)
integer tc = length(pbnp),
oc = length(odds),
ec = tc-oc
string f50 = join_by(pbnp[1..50],1,10," ",fmt:="%3d"),
o20 = join_by(odds[1..20],1,10," ",fmt:="%3d")
printf(1,"First 50 pan-base composites:\n%s\n",f50)
printf(1,"First 20 odd pan-base composites:\n%s\n",o20)
printf(1,"Count of pan-base composites up to and including %d: %d\n",{lim,tc})
printf(1,"Number odd  = %3d or %9.6f%%\n", {oc,oc/tc*100})
printf(1,"Number even = %3d or %9.6f%%\n", {ec,ec/tc*100})
```

Output same as Wren

## Raku

```use Base::Any;
use List::Divvy;

my @np = 4,6,8,9, |lazy (11..*).hyper.grep( -> \$n { (\$n.substr(*-1) eq '0') || (1 < [gcd] \$n.comb».Int) || none (2..\$n).map: { try "\$n".&from-base(\$_).is-prime } } );

put "First 50 pan-base composites:\n" ~ @np[^50].batch(10)».fmt("%3s").join: "\n";
put "\nFirst 20 odd pan-base composites:\n" ~ @np.grep(* % 2)[^20].batch(10)».fmt("%3s").join: "\n";

my \$threshold = 2500;
put "\nCount of pan-base composites up to and including \$threshold: " ~ +@np.&upto(\$threshold);

put "Percent odd  up to and including \$threshold: " ~ +@np.&upto(\$threshold).grep(* % 2) / +@np.&upto(\$threshold) × 100;
put "Percent even up to and including \$threshold: " ~ +@np.&upto(\$threshold).grep(* %% 2) / +@np.&upto(\$threshold) × 100;
```
Output:
```First 50 pan-base composites:
4   6   8   9  20  22  24  26  28  30
33  36  39  40  42  44  46  48  50  55
60  62  63  64  66  68  69  70  77  80
82  84  86  88  90  93  96  99 100 110
112 114 116 118 120 121 130 132 134 136

First 20 odd pan-base composites:
9  33  39  55  63  69  77  93  99 121
143 165 169 187 231 253 273 275 297 299

Count of pan-base composites up to and including 2500: 953
Percent odd  up to and including 2500: 16.894019
Percent even up to and including 2500: 83.105981```

## RPL

Works with: RPL version HP-49C
```« { } SWAP
WHILE DUP REPEAT 10 IDIV2 ROT + SWAP END
DROP
» '→DIGL' STO

« { } 3 ROT FOR n
1 CF
CASE
n 10 > LASTARG MOD NOT AND THEN 1 SF END
n
IF DUP 9 > THEN
→DIGL
IF DUP « GCD » STREAM 1 > THEN DROP 1 SF END
END
1 FC? THEN
1 SF
2 n FOR b
DUP
IF DUP TYPE 5 == THEN « SWAP b * + » STREAM END
IF ISPRIME? THEN 1 CF n 'b' STO END
NEXT DROP
END
END
IF 1 FS? THEN n + END
NEXT

« DUP 2 MOD OVER IFT
→ pbnp odds
« pbnp 1 50 SUB
odds 1 20 SUB
pbnp SIZE "pbnp ≤ 1000" →TAG
odds SIZE pbnp SIZE / 100 * "% odd" →TAG
» » 'PBNPVU' STO
```
```1000 TASK PBNPVU
```
Output:
```4: { 4 6 8 9 20 22 24 26 28 30 33 36 39 40 42 44 46 48 50 55 60 62 63 64 66 68 69 70 77 80 82 84 86 88 90 93 96 99 100 110 112 114 116 118 120 121 130 132 134 136 }
3: { 9 33 39 55 63 69 77 93 99 121 143 165 169 187 231 253 273 275 297 299 }
2: pbnp ≤ 1000: 377.
1: % odd: 16.7108753316
```

## Ruby

```require 'prime'

def int_from_digits(ar, base=10)
# expects array from digits method, which takes a base as argument and gives least significant digit first.
raise ArgumentError, "#{ar.max} not valid in base #{base}. " if ar.max > base-1
ar.each_with_index.sum {|d, i| d*base**i }
end

limit = 2500
a121719 = (2..limit).lazy.select do |n|
next false if (n < 10 && n.prime?)
digits = n.digits
from = digits.max + 1
(from..n).none?{|base| int_from_digits(digits, base).prime? }
end

n = 50
puts "First #{n} pan-base composites:"
a121719.take(n).each_slice(10){|s| puts "%4s"*s.size % s}

n = 20
puts "\nFirst #{n} odd pan-base composites:"
a121719.select(&:odd?).take(n).each_slice(10){|s| puts "%4s"*s.size % s }

tally = a121719.map(&:odd?).tally
total = tally.values.sum
puts "\nCount of pan-base composites up to and including #{limit}: #{total}"
puts "Number of odds  is #{tally[true ]}, proportion  #{tally[true ].fdiv(total) }%"
puts "Number of evens is #{tally[false]}, proportion  #{tally[false].fdiv(total) }%"
```
Output:
```First 50 pan-base composites:
4   6   8   9  20  22  24  26  28  30
33  36  39  40  42  44  46  48  50  55
60  62  63  64  66  68  69  70  77  80
82  84  86  88  90  93  96  99 100 110
112 114 116 118 120 121 130 132 134 136

First 20 odd pan-base composites:
9  33  39  55  63  69  77  93  99 121
143 165 169 187 231 253 273 275 297 299

Count of pan-base composites up to and including 2500: 953
Number of odds  is 161, proportion  0.1689401888772298%
Number of evens is 792, proportion  0.8310598111227702%
```

## Wren

Library: Wren-math
Library: Wren-fmt
```import "./math" for Int
import "./fmt" for Fmt

var strToDec = Fn.new { |s, b|
var res =  0
for (c in s) {
var d = Num.fromString(c)
res = res * b + d
}
return res
}

var limit = 2500
var pbnp = []
for (n in 3..limit) {
if (n % 10 == 0 && n > 10) {
} else if (n > 9 && Int.gcd(Int.digits(n)) > 1) {
} else {
var comp = true
for (b in 2...n) {
var d = strToDec.call(n.toString, b)
if (Int.isPrime(d)) {
comp = false
break
}
}
}
}

System.print("First 50 pan-base composites:")
Fmt.tprint("\$3d", pbnp[0..49], 10)

System.print("\nFirst 20 odd pan-base composites:")
var odd = pbnp.where { |n| n % 2 == 1 }.toList
Fmt.tprint("\$3d", odd[0..19], 10)

var tc
System.print("\nCount of pan-base composites up to and including %(limit): %(tc = pbnp.count)")
var c
Fmt.print("Number odd  = \$3d or \$9.6f\%", c = odd.count, c/tc * 100)
Fmt.print("Number even = \$3d or \$9.6f\%", c = tc - c, c/tc * 100)
```
Output:
```First 50 pan-base composites:
4   6   8   9  20  22  24  26  28  30
33  36  39  40  42  44  46  48  50  55
60  62  63  64  66  68  69  70  77  80
82  84  86  88  90  93  96  99 100 110
112 114 116 118 120 121 130 132 134 136

First 20 odd pan-base composites:
9  33  39  55  63  69  77  93  99 121
143 165 169 187 231 253 273 275 297 299

Count of pan-base composites up to and including 2500: 953
Number odd  = 161 or 16.894019%
Number even = 792 or 83.105981%
```